Commit 8612c7e5 authored by Dave Chinner's avatar Dave Chinner

Merge branch 'xfs-da-geom' into for-next

parents b70f14e1 35f46c5f
...@@ -88,6 +88,7 @@ xfs_attr_args_init( ...@@ -88,6 +88,7 @@ xfs_attr_args_init(
return EINVAL; return EINVAL;
memset(args, 0, sizeof(*args)); memset(args, 0, sizeof(*args));
args->geo = dp->i_mount->m_attr_geo;
args->whichfork = XFS_ATTR_FORK; args->whichfork = XFS_ATTR_FORK;
args->dp = dp; args->dp = dp;
args->flags = flags; args->flags = flags;
...@@ -173,12 +174,10 @@ xfs_attr_calc_size( ...@@ -173,12 +174,10 @@ xfs_attr_calc_size(
* Determine space new attribute will use, and if it would be * Determine space new attribute will use, and if it would be
* "local" or "remote" (note: local != inline). * "local" or "remote" (note: local != inline).
*/ */
size = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, size = xfs_attr_leaf_newentsize(args, local);
mp->m_sb.sb_blocksize, local);
nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
if (*local) { if (*local) {
if (size > (mp->m_sb.sb_blocksize >> 1)) { if (size > (args->geo->blksize / 2)) {
/* Double split possible */ /* Double split possible */
nblks *= 2; nblks *= 2;
} }
...@@ -864,7 +863,7 @@ xfs_attr_leaf_get(xfs_da_args_t *args) ...@@ -864,7 +863,7 @@ xfs_attr_leaf_get(xfs_da_args_t *args)
} }
/*======================================================================== /*========================================================================
* External routines when attribute list size > XFS_LBSIZE(mp). * External routines when attribute list size > geo->blksize
*========================================================================*/ *========================================================================*/
/* /*
...@@ -897,8 +896,6 @@ xfs_attr_node_addname(xfs_da_args_t *args) ...@@ -897,8 +896,6 @@ xfs_attr_node_addname(xfs_da_args_t *args)
state = xfs_da_state_alloc(); state = xfs_da_state_alloc();
state->args = args; state->args = args;
state->mp = mp; state->mp = mp;
state->blocksize = state->mp->m_sb.sb_blocksize;
state->node_ents = state->mp->m_attr_node_ents;
/* /*
* Search to see if name already exists, and get back a pointer * Search to see if name already exists, and get back a pointer
...@@ -1076,8 +1073,6 @@ xfs_attr_node_addname(xfs_da_args_t *args) ...@@ -1076,8 +1073,6 @@ xfs_attr_node_addname(xfs_da_args_t *args)
state = xfs_da_state_alloc(); state = xfs_da_state_alloc();
state->args = args; state->args = args;
state->mp = mp; state->mp = mp;
state->blocksize = state->mp->m_sb.sb_blocksize;
state->node_ents = state->mp->m_attr_node_ents;
state->inleaf = 0; state->inleaf = 0;
error = xfs_da3_node_lookup_int(state, &retval); error = xfs_da3_node_lookup_int(state, &retval);
if (error) if (error)
...@@ -1168,8 +1163,6 @@ xfs_attr_node_removename(xfs_da_args_t *args) ...@@ -1168,8 +1163,6 @@ xfs_attr_node_removename(xfs_da_args_t *args)
state = xfs_da_state_alloc(); state = xfs_da_state_alloc();
state->args = args; state->args = args;
state->mp = dp->i_mount; state->mp = dp->i_mount;
state->blocksize = state->mp->m_sb.sb_blocksize;
state->node_ents = state->mp->m_attr_node_ents;
/* /*
* Search to see if name exists, and get back a pointer to it. * Search to see if name exists, and get back a pointer to it.
...@@ -1431,8 +1424,6 @@ xfs_attr_node_get(xfs_da_args_t *args) ...@@ -1431,8 +1424,6 @@ xfs_attr_node_get(xfs_da_args_t *args)
state = xfs_da_state_alloc(); state = xfs_da_state_alloc();
state->args = args; state->args = args;
state->mp = args->dp->i_mount; state->mp = args->dp->i_mount;
state->blocksize = state->mp->m_sb.sb_blocksize;
state->node_ents = state->mp->m_attr_node_ents;
/* /*
* Search to see if name exists, and get back a pointer to it. * Search to see if name exists, and get back a pointer to it.
......
This diff is collapsed.
...@@ -96,8 +96,7 @@ int xfs_attr3_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp); ...@@ -96,8 +96,7 @@ int xfs_attr3_root_inactive(struct xfs_trans **trans, struct xfs_inode *dp);
xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_buf *bp, int *count); xfs_dahash_t xfs_attr_leaf_lasthash(struct xfs_buf *bp, int *count);
int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp, int xfs_attr_leaf_order(struct xfs_buf *leaf1_bp,
struct xfs_buf *leaf2_bp); struct xfs_buf *leaf2_bp);
int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int *local);
int *local);
int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
xfs_dablk_t bno, xfs_daddr_t mappedbno, xfs_dablk_t bno, xfs_daddr_t mappedbno,
struct xfs_buf **bpp); struct xfs_buf **bpp);
......
...@@ -444,6 +444,7 @@ xfs_attr3_leaf_list_int( ...@@ -444,6 +444,7 @@ xfs_attr3_leaf_list_int(
xfs_da_args_t args; xfs_da_args_t args;
memset((char *)&args, 0, sizeof(args)); memset((char *)&args, 0, sizeof(args));
args.geo = context->dp->i_mount->m_attr_geo;
args.dp = context->dp; args.dp = context->dp;
args.whichfork = XFS_ATTR_FORK; args.whichfork = XFS_ATTR_FORK;
args.valuelen = valuelen; args.valuelen = valuelen;
......
...@@ -125,6 +125,7 @@ xfs_attr3_rmt_read_verify( ...@@ -125,6 +125,7 @@ xfs_attr3_rmt_read_verify(
char *ptr; char *ptr;
int len; int len;
xfs_daddr_t bno; xfs_daddr_t bno;
int blksize = mp->m_attr_geo->blksize;
/* no verification of non-crc buffers */ /* no verification of non-crc buffers */
if (!xfs_sb_version_hascrc(&mp->m_sb)) if (!xfs_sb_version_hascrc(&mp->m_sb))
...@@ -133,21 +134,20 @@ xfs_attr3_rmt_read_verify( ...@@ -133,21 +134,20 @@ xfs_attr3_rmt_read_verify(
ptr = bp->b_addr; ptr = bp->b_addr;
bno = bp->b_bn; bno = bp->b_bn;
len = BBTOB(bp->b_length); len = BBTOB(bp->b_length);
ASSERT(len >= XFS_LBSIZE(mp)); ASSERT(len >= blksize);
while (len > 0) { while (len > 0) {
if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp), if (!xfs_verify_cksum(ptr, blksize, XFS_ATTR3_RMT_CRC_OFF)) {
XFS_ATTR3_RMT_CRC_OFF)) {
xfs_buf_ioerror(bp, EFSBADCRC); xfs_buf_ioerror(bp, EFSBADCRC);
break; break;
} }
if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { if (!xfs_attr3_rmt_verify(mp, ptr, blksize, bno)) {
xfs_buf_ioerror(bp, EFSCORRUPTED); xfs_buf_ioerror(bp, EFSCORRUPTED);
break; break;
} }
len -= XFS_LBSIZE(mp); len -= blksize;
ptr += XFS_LBSIZE(mp); ptr += blksize;
bno += mp->m_bsize; bno += BTOBB(blksize);
} }
if (bp->b_error) if (bp->b_error)
...@@ -165,6 +165,7 @@ xfs_attr3_rmt_write_verify( ...@@ -165,6 +165,7 @@ xfs_attr3_rmt_write_verify(
char *ptr; char *ptr;
int len; int len;
xfs_daddr_t bno; xfs_daddr_t bno;
int blksize = mp->m_attr_geo->blksize;
/* no verification of non-crc buffers */ /* no verification of non-crc buffers */
if (!xfs_sb_version_hascrc(&mp->m_sb)) if (!xfs_sb_version_hascrc(&mp->m_sb))
...@@ -173,10 +174,10 @@ xfs_attr3_rmt_write_verify( ...@@ -173,10 +174,10 @@ xfs_attr3_rmt_write_verify(
ptr = bp->b_addr; ptr = bp->b_addr;
bno = bp->b_bn; bno = bp->b_bn;
len = BBTOB(bp->b_length); len = BBTOB(bp->b_length);
ASSERT(len >= XFS_LBSIZE(mp)); ASSERT(len >= blksize);
while (len > 0) { while (len > 0) {
if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) { if (!xfs_attr3_rmt_verify(mp, ptr, blksize, bno)) {
xfs_buf_ioerror(bp, EFSCORRUPTED); xfs_buf_ioerror(bp, EFSCORRUPTED);
xfs_verifier_error(bp); xfs_verifier_error(bp);
return; return;
...@@ -187,11 +188,11 @@ xfs_attr3_rmt_write_verify( ...@@ -187,11 +188,11 @@ xfs_attr3_rmt_write_verify(
rmt = (struct xfs_attr3_rmt_hdr *)ptr; rmt = (struct xfs_attr3_rmt_hdr *)ptr;
rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn); rmt->rm_lsn = cpu_to_be64(bip->bli_item.li_lsn);
} }
xfs_update_cksum(ptr, XFS_LBSIZE(mp), XFS_ATTR3_RMT_CRC_OFF); xfs_update_cksum(ptr, blksize, XFS_ATTR3_RMT_CRC_OFF);
len -= XFS_LBSIZE(mp); len -= blksize;
ptr += XFS_LBSIZE(mp); ptr += blksize;
bno += mp->m_bsize; bno += BTOBB(blksize);
} }
ASSERT(len == 0); ASSERT(len == 0);
} }
...@@ -240,12 +241,13 @@ xfs_attr_rmtval_copyout( ...@@ -240,12 +241,13 @@ xfs_attr_rmtval_copyout(
char *src = bp->b_addr; char *src = bp->b_addr;
xfs_daddr_t bno = bp->b_bn; xfs_daddr_t bno = bp->b_bn;
int len = BBTOB(bp->b_length); int len = BBTOB(bp->b_length);
int blksize = mp->m_attr_geo->blksize;
ASSERT(len >= XFS_LBSIZE(mp)); ASSERT(len >= blksize);
while (len > 0 && *valuelen > 0) { while (len > 0 && *valuelen > 0) {
int hdr_size = 0; int hdr_size = 0;
int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, blksize);
byte_cnt = min(*valuelen, byte_cnt); byte_cnt = min(*valuelen, byte_cnt);
...@@ -263,9 +265,9 @@ xfs_attr_rmtval_copyout( ...@@ -263,9 +265,9 @@ xfs_attr_rmtval_copyout(
memcpy(*dst, src + hdr_size, byte_cnt); memcpy(*dst, src + hdr_size, byte_cnt);
/* roll buffer forwards */ /* roll buffer forwards */
len -= XFS_LBSIZE(mp); len -= blksize;
src += XFS_LBSIZE(mp); src += blksize;
bno += mp->m_bsize; bno += BTOBB(blksize);
/* roll attribute data forwards */ /* roll attribute data forwards */
*valuelen -= byte_cnt; *valuelen -= byte_cnt;
...@@ -287,12 +289,13 @@ xfs_attr_rmtval_copyin( ...@@ -287,12 +289,13 @@ xfs_attr_rmtval_copyin(
char *dst = bp->b_addr; char *dst = bp->b_addr;
xfs_daddr_t bno = bp->b_bn; xfs_daddr_t bno = bp->b_bn;
int len = BBTOB(bp->b_length); int len = BBTOB(bp->b_length);
int blksize = mp->m_attr_geo->blksize;
ASSERT(len >= XFS_LBSIZE(mp)); ASSERT(len >= blksize);
while (len > 0 && *valuelen > 0) { while (len > 0 && *valuelen > 0) {
int hdr_size; int hdr_size;
int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, XFS_LBSIZE(mp)); int byte_cnt = XFS_ATTR3_RMT_BUF_SPACE(mp, blksize);
byte_cnt = min(*valuelen, byte_cnt); byte_cnt = min(*valuelen, byte_cnt);
hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset, hdr_size = xfs_attr3_rmt_hdr_set(mp, dst, ino, *offset,
...@@ -304,17 +307,17 @@ xfs_attr_rmtval_copyin( ...@@ -304,17 +307,17 @@ xfs_attr_rmtval_copyin(
* If this is the last block, zero the remainder of it. * If this is the last block, zero the remainder of it.
* Check that we are actually the last block, too. * Check that we are actually the last block, too.
*/ */
if (byte_cnt + hdr_size < XFS_LBSIZE(mp)) { if (byte_cnt + hdr_size < blksize) {
ASSERT(*valuelen - byte_cnt == 0); ASSERT(*valuelen - byte_cnt == 0);
ASSERT(len == XFS_LBSIZE(mp)); ASSERT(len == blksize);
memset(dst + hdr_size + byte_cnt, 0, memset(dst + hdr_size + byte_cnt, 0,
XFS_LBSIZE(mp) - hdr_size - byte_cnt); blksize - hdr_size - byte_cnt);
} }
/* roll buffer forwards */ /* roll buffer forwards */
len -= XFS_LBSIZE(mp); len -= blksize;
dst += XFS_LBSIZE(mp); dst += blksize;
bno += mp->m_bsize; bno += BTOBB(blksize);
/* roll attribute data forwards */ /* roll attribute data forwards */
*valuelen -= byte_cnt; *valuelen -= byte_cnt;
......
...@@ -1098,10 +1098,11 @@ xfs_bmap_add_attrfork_local( ...@@ -1098,10 +1098,11 @@ xfs_bmap_add_attrfork_local(
if (S_ISDIR(ip->i_d.di_mode)) { if (S_ISDIR(ip->i_d.di_mode)) {
memset(&dargs, 0, sizeof(dargs)); memset(&dargs, 0, sizeof(dargs));
dargs.geo = ip->i_mount->m_dir_geo;
dargs.dp = ip; dargs.dp = ip;
dargs.firstblock = firstblock; dargs.firstblock = firstblock;
dargs.flist = flist; dargs.flist = flist;
dargs.total = ip->i_mount->m_dirblkfsbs; dargs.total = dargs.geo->fsbcount;
dargs.whichfork = XFS_DATA_FORK; dargs.whichfork = XFS_DATA_FORK;
dargs.trans = tp; dargs.trans = tp;
return xfs_dir2_sf_to_block(&dargs); return xfs_dir2_sf_to_block(&dargs);
......
...@@ -167,8 +167,8 @@ xfs_da3_node_verify( ...@@ -167,8 +167,8 @@ xfs_da3_node_verify(
* we don't know if the node is for and attribute or directory tree, * we don't know if the node is for and attribute or directory tree,
* so only fail if the count is outside both bounds * so only fail if the count is outside both bounds
*/ */
if (ichdr.count > mp->m_dir_node_ents && if (ichdr.count > mp->m_dir_geo->node_ents &&
ichdr.count > mp->m_attr_node_ents) ichdr.count > mp->m_attr_geo->node_ents)
return false; return false;
/* XXX: hash order check? */ /* XXX: hash order check? */
...@@ -598,7 +598,7 @@ xfs_da3_root_split( ...@@ -598,7 +598,7 @@ xfs_da3_root_split(
* Set up the new root node. * Set up the new root node.
*/ */
error = xfs_da3_node_create(args, error = xfs_da3_node_create(args,
(args->whichfork == XFS_DATA_FORK) ? mp->m_dirleafblk : 0, (args->whichfork == XFS_DATA_FORK) ? args->geo->leafblk : 0,
level + 1, &bp, args->whichfork); level + 1, &bp, args->whichfork);
if (error) if (error)
return error; return error;
...@@ -616,10 +616,10 @@ xfs_da3_root_split( ...@@ -616,10 +616,10 @@ xfs_da3_root_split(
#ifdef DEBUG #ifdef DEBUG
if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) { oldroot->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) {
ASSERT(blk1->blkno >= mp->m_dirleafblk && ASSERT(blk1->blkno >= args->geo->leafblk &&
blk1->blkno < mp->m_dirfreeblk); blk1->blkno < args->geo->freeblk);
ASSERT(blk2->blkno >= mp->m_dirleafblk && ASSERT(blk2->blkno >= args->geo->leafblk &&
blk2->blkno < mp->m_dirfreeblk); blk2->blkno < args->geo->freeblk);
} }
#endif #endif
...@@ -663,7 +663,7 @@ xfs_da3_node_split( ...@@ -663,7 +663,7 @@ xfs_da3_node_split(
/* /*
* Do we have to split the node? * Do we have to split the node?
*/ */
if (nodehdr.count + newcount > state->node_ents) { if (nodehdr.count + newcount > state->args->geo->node_ents) {
/* /*
* Allocate a new node, add to the doubly linked chain of * Allocate a new node, add to the doubly linked chain of
* nodes, then move some of our excess entries into it. * nodes, then move some of our excess entries into it.
...@@ -894,8 +894,8 @@ xfs_da3_node_add( ...@@ -894,8 +894,8 @@ xfs_da3_node_add(
ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count); ASSERT(oldblk->index >= 0 && oldblk->index <= nodehdr.count);
ASSERT(newblk->blkno != 0); ASSERT(newblk->blkno != 0);
if (state->args->whichfork == XFS_DATA_FORK) if (state->args->whichfork == XFS_DATA_FORK)
ASSERT(newblk->blkno >= state->mp->m_dirleafblk && ASSERT(newblk->blkno >= state->args->geo->leafblk &&
newblk->blkno < state->mp->m_dirfreeblk); newblk->blkno < state->args->geo->freeblk);
/* /*
* We may need to make some room before we insert the new node. * We may need to make some room before we insert the new node.
...@@ -1089,14 +1089,15 @@ xfs_da3_root_join( ...@@ -1089,14 +1089,15 @@ xfs_da3_root_join(
* that could occur. For dir3 blocks we also need to update the block * that could occur. For dir3 blocks we also need to update the block
* number in the buffer header. * number in the buffer header.
*/ */
memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize); memcpy(root_blk->bp->b_addr, bp->b_addr, args->geo->blksize);
root_blk->bp->b_ops = bp->b_ops; root_blk->bp->b_ops = bp->b_ops;
xfs_trans_buf_copy_type(root_blk->bp, bp); xfs_trans_buf_copy_type(root_blk->bp, bp);
if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) { if (oldroothdr.magic == XFS_DA3_NODE_MAGIC) {
struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr; struct xfs_da3_blkinfo *da3 = root_blk->bp->b_addr;
da3->blkno = cpu_to_be64(root_blk->bp->b_bn); da3->blkno = cpu_to_be64(root_blk->bp->b_bn);
} }
xfs_trans_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); xfs_trans_log_buf(args->trans, root_blk->bp, 0,
args->geo->blksize - 1);
error = xfs_da_shrink_inode(args, child, bp); error = xfs_da_shrink_inode(args, child, bp);
return(error); return(error);
} }
...@@ -1139,7 +1140,7 @@ xfs_da3_node_toosmall( ...@@ -1139,7 +1140,7 @@ xfs_da3_node_toosmall(
info = blk->bp->b_addr; info = blk->bp->b_addr;
node = (xfs_da_intnode_t *)info; node = (xfs_da_intnode_t *)info;
dp->d_ops->node_hdr_from_disk(&nodehdr, node); dp->d_ops->node_hdr_from_disk(&nodehdr, node);
if (nodehdr.count > (state->node_ents >> 1)) { if (nodehdr.count > (state->args->geo->node_ents >> 1)) {
*action = 0; /* blk over 50%, don't try to join */ *action = 0; /* blk over 50%, don't try to join */
return(0); /* blk over 50%, don't try to join */ return(0); /* blk over 50%, don't try to join */
} }
...@@ -1176,8 +1177,8 @@ xfs_da3_node_toosmall( ...@@ -1176,8 +1177,8 @@ xfs_da3_node_toosmall(
* We prefer coalescing with the lower numbered sibling so as * We prefer coalescing with the lower numbered sibling so as
* to shrink a directory over time. * to shrink a directory over time.
*/ */
count = state->node_ents; count = state->args->geo->node_ents;
count -= state->node_ents >> 2; count -= state->args->geo->node_ents >> 2;
count -= nodehdr.count; count -= nodehdr.count;
/* start with smaller blk num */ /* start with smaller blk num */
...@@ -1472,7 +1473,7 @@ xfs_da3_node_lookup_int( ...@@ -1472,7 +1473,7 @@ xfs_da3_node_lookup_int(
* Descend thru the B-tree searching each level for the right * Descend thru the B-tree searching each level for the right
* node to use, until the right hashval is found. * node to use, until the right hashval is found.
*/ */
blkno = (args->whichfork == XFS_DATA_FORK)? state->mp->m_dirleafblk : 0; blkno = (args->whichfork == XFS_DATA_FORK)? args->geo->leafblk : 0;
for (blk = &state->path.blk[0], state->path.active = 1; for (blk = &state->path.blk[0], state->path.active = 1;
state->path.active <= XFS_DA_NODE_MAXDEPTH; state->path.active <= XFS_DA_NODE_MAXDEPTH;
blk++, state->path.active++) { blk++, state->path.active++) {
...@@ -2090,20 +2091,12 @@ xfs_da_grow_inode( ...@@ -2090,20 +2091,12 @@ xfs_da_grow_inode(
xfs_dablk_t *new_blkno) xfs_dablk_t *new_blkno)
{ {
xfs_fileoff_t bno; xfs_fileoff_t bno;
int count;
int error; int error;
trace_xfs_da_grow_inode(args); trace_xfs_da_grow_inode(args);
if (args->whichfork == XFS_DATA_FORK) { bno = args->geo->leafblk;
bno = args->dp->i_mount->m_dirleafblk; error = xfs_da_grow_inode_int(args, &bno, args->geo->fsbcount);
count = args->dp->i_mount->m_dirblkfsbs;
} else {
bno = 0;
count = 1;
}
error = xfs_da_grow_inode_int(args, &bno, count);
if (!error) if (!error)
*new_blkno = (xfs_dablk_t)bno; *new_blkno = (xfs_dablk_t)bno;
return error; return error;
...@@ -2158,7 +2151,7 @@ xfs_da3_swap_lastblock( ...@@ -2158,7 +2151,7 @@ xfs_da3_swap_lastblock(
w = args->whichfork; w = args->whichfork;
ASSERT(w == XFS_DATA_FORK); ASSERT(w == XFS_DATA_FORK);
mp = dp->i_mount; mp = dp->i_mount;
lastoff = mp->m_dirfreeblk; lastoff = args->geo->freeblk;
error = xfs_bmap_last_before(tp, dp, &lastoff, w); error = xfs_bmap_last_before(tp, dp, &lastoff, w);
if (error) if (error)
return error; return error;
...@@ -2170,15 +2163,15 @@ xfs_da3_swap_lastblock( ...@@ -2170,15 +2163,15 @@ xfs_da3_swap_lastblock(
/* /*
* Read the last block in the btree space. * Read the last block in the btree space.
*/ */
last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs; last_blkno = (xfs_dablk_t)lastoff - args->geo->fsbcount;
error = xfs_da3_node_read(tp, dp, last_blkno, -1, &last_buf, w); error = xfs_da3_node_read(tp, dp, last_blkno, -1, &last_buf, w);
if (error) if (error)
return error; return error;
/* /*
* Copy the last block into the dead buffer and log it. * Copy the last block into the dead buffer and log it.
*/ */
memcpy(dead_buf->b_addr, last_buf->b_addr, mp->m_dirblksize); memcpy(dead_buf->b_addr, last_buf->b_addr, args->geo->blksize);
xfs_trans_log_buf(tp, dead_buf, 0, mp->m_dirblksize - 1); xfs_trans_log_buf(tp, dead_buf, 0, args->geo->blksize - 1);
dead_info = dead_buf->b_addr; dead_info = dead_buf->b_addr;
/* /*
* Get values from the moved block. * Get values from the moved block.
...@@ -2247,7 +2240,7 @@ xfs_da3_swap_lastblock( ...@@ -2247,7 +2240,7 @@ xfs_da3_swap_lastblock(
sizeof(sib_info->back))); sizeof(sib_info->back)));
sib_buf = NULL; sib_buf = NULL;
} }
par_blkno = mp->m_dirleafblk; par_blkno = args->geo->leafblk;
level = -1; level = -1;
/* /*
* Walk down the tree looking for the parent of the moved block. * Walk down the tree looking for the parent of the moved block.
...@@ -2357,10 +2350,7 @@ xfs_da_shrink_inode( ...@@ -2357,10 +2350,7 @@ xfs_da_shrink_inode(
w = args->whichfork; w = args->whichfork;
tp = args->trans; tp = args->trans;
mp = dp->i_mount; mp = dp->i_mount;
if (w == XFS_DATA_FORK) count = args->geo->fsbcount;
count = mp->m_dirblkfsbs;
else
count = 1;
for (;;) { for (;;) {
/* /*
* Remove extents. If we get ENOSPC for a dir we have to move * Remove extents. If we get ENOSPC for a dir we have to move
...@@ -2479,7 +2469,10 @@ xfs_dabuf_map( ...@@ -2479,7 +2469,10 @@ xfs_dabuf_map(
ASSERT(map && *map); ASSERT(map && *map);
ASSERT(*nmaps == 1); ASSERT(*nmaps == 1);
nfsb = (whichfork == XFS_DATA_FORK) ? mp->m_dirblkfsbs : 1; if (whichfork == XFS_DATA_FORK)
nfsb = mp->m_dir_geo->fsbcount;
else
nfsb = mp->m_attr_geo->fsbcount;
/* /*
* Caller doesn't have a mapping. -2 means don't complain * Caller doesn't have a mapping. -2 means don't complain
......
...@@ -25,6 +25,23 @@ struct xfs_trans; ...@@ -25,6 +25,23 @@ struct xfs_trans;
struct zone; struct zone;
struct xfs_dir_ops; struct xfs_dir_ops;
/*
* Directory/attribute geometry information. There will be one of these for each
* data fork type, and it will be passed around via the xfs_da_args. Global
* structures will be attached to the xfs_mount.
*/
struct xfs_da_geometry {
int blksize; /* da block size in bytes */
int fsbcount; /* da block size in filesystem blocks */
uint8_t fsblog; /* log2 of _filesystem_ block size */
uint8_t blklog; /* log2 of da block size */
uint node_ents; /* # of entries in a danode */
int magicpct; /* 37% of block size in bytes */
xfs_dablk_t datablk; /* blockno of dir data v2 */
xfs_dablk_t leafblk; /* blockno of leaf data v2 */
xfs_dablk_t freeblk; /* blockno of free data v2 */
};
/*======================================================================== /*========================================================================
* Btree searching and modification structure definitions. * Btree searching and modification structure definitions.
*========================================================================*/ *========================================================================*/
...@@ -42,6 +59,7 @@ enum xfs_dacmp { ...@@ -42,6 +59,7 @@ enum xfs_dacmp {
* Structure to ease passing around component names. * Structure to ease passing around component names.
*/ */
typedef struct xfs_da_args { typedef struct xfs_da_args {
struct xfs_da_geometry *geo; /* da block geometry */
const __uint8_t *name; /* string (maybe not NULL terminated) */ const __uint8_t *name; /* string (maybe not NULL terminated) */
int namelen; /* length of string (maybe no NULL) */ int namelen; /* length of string (maybe no NULL) */
__uint8_t filetype; /* filetype of inode for directories */ __uint8_t filetype; /* filetype of inode for directories */
...@@ -110,8 +128,6 @@ typedef struct xfs_da_state_path { ...@@ -110,8 +128,6 @@ typedef struct xfs_da_state_path {
typedef struct xfs_da_state { typedef struct xfs_da_state {
xfs_da_args_t *args; /* filename arguments */ xfs_da_args_t *args; /* filename arguments */
struct xfs_mount *mp; /* filesystem mount point */ struct xfs_mount *mp; /* filesystem mount point */
unsigned int blocksize; /* logical block size */
unsigned int node_ents; /* how many entries in danode */
xfs_da_state_path_t path; /* search/split paths */ xfs_da_state_path_t path; /* search/split paths */
xfs_da_state_path_t altpath; /* alternate path for join */ xfs_da_state_path_t altpath; /* alternate path for join */
unsigned char inleaf; /* insert into 1->lf, 0->splf */ unsigned char inleaf; /* insert into 1->lf, 0->splf */
......
...@@ -26,8 +26,10 @@ ...@@ -26,8 +26,10 @@
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_da_format.h" #include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_inode.h" #include "xfs_inode.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_dir2_priv.h"
/* /*
* Shortform directory ops * Shortform directory ops
...@@ -425,9 +427,9 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) ...@@ -425,9 +427,9 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
* Directory Leaf block operations * Directory Leaf block operations
*/ */
static int static int
xfs_dir2_max_leaf_ents(struct xfs_mount *mp) xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
{ {
return (mp->m_dirblksize - sizeof(struct xfs_dir2_leaf_hdr)) / return (geo->blksize - sizeof(struct xfs_dir2_leaf_hdr)) /
(uint)sizeof(struct xfs_dir2_leaf_entry); (uint)sizeof(struct xfs_dir2_leaf_entry);
} }
...@@ -438,9 +440,9 @@ xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp) ...@@ -438,9 +440,9 @@ xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
} }
static int static int
xfs_dir3_max_leaf_ents(struct xfs_mount *mp) xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
{ {
return (mp->m_dirblksize - sizeof(struct xfs_dir3_leaf_hdr)) / return (geo->blksize - sizeof(struct xfs_dir3_leaf_hdr)) /
(uint)sizeof(struct xfs_dir2_leaf_entry); (uint)sizeof(struct xfs_dir2_leaf_entry);
} }
...@@ -591,9 +593,9 @@ xfs_da3_node_hdr_to_disk( ...@@ -591,9 +593,9 @@ xfs_da3_node_hdr_to_disk(
* Directory free space block operations * Directory free space block operations
*/ */
static int static int
xfs_dir2_free_max_bests(struct xfs_mount *mp) xfs_dir2_free_max_bests(struct xfs_da_geometry *geo)
{ {
return (mp->m_dirblksize - sizeof(struct xfs_dir2_free_hdr)) / return (geo->blksize - sizeof(struct xfs_dir2_free_hdr)) /
sizeof(xfs_dir2_data_off_t); sizeof(xfs_dir2_data_off_t);
} }
...@@ -607,24 +609,25 @@ xfs_dir2_free_bests_p(struct xfs_dir2_free *free) ...@@ -607,24 +609,25 @@ xfs_dir2_free_bests_p(struct xfs_dir2_free *free)
* Convert data space db to the corresponding free db. * Convert data space db to the corresponding free db.
*/ */
static xfs_dir2_db_t static xfs_dir2_db_t
xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) xfs_dir2_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
{ {
return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir2_free_max_bests(mp); return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
(db / xfs_dir2_free_max_bests(geo));
} }
/* /*
* Convert data space db to the corresponding index in a free db. * Convert data space db to the corresponding index in a free db.
*/ */
static int static int
xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) xfs_dir2_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
{ {
return db % xfs_dir2_free_max_bests(mp); return db % xfs_dir2_free_max_bests(geo);
} }
static int static int
xfs_dir3_free_max_bests(struct xfs_mount *mp) xfs_dir3_free_max_bests(struct xfs_da_geometry *geo)
{ {
return (mp->m_dirblksize - sizeof(struct xfs_dir3_free_hdr)) / return (geo->blksize - sizeof(struct xfs_dir3_free_hdr)) /
sizeof(xfs_dir2_data_off_t); sizeof(xfs_dir2_data_off_t);
} }
...@@ -638,18 +641,19 @@ xfs_dir3_free_bests_p(struct xfs_dir2_free *free) ...@@ -638,18 +641,19 @@ xfs_dir3_free_bests_p(struct xfs_dir2_free *free)
* Convert data space db to the corresponding free db. * Convert data space db to the corresponding free db.
*/ */
static xfs_dir2_db_t static xfs_dir2_db_t
xfs_dir3_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db) xfs_dir3_db_to_fdb(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
{ {
return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir3_free_max_bests(mp); return xfs_dir2_byte_to_db(geo, XFS_DIR2_FREE_OFFSET) +
(db / xfs_dir3_free_max_bests(geo));
} }
/* /*
* Convert data space db to the corresponding index in a free db. * Convert data space db to the corresponding index in a free db.
*/ */
static int static int
xfs_dir3_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db) xfs_dir3_db_to_fdindex(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
{ {
return db % xfs_dir3_free_max_bests(mp); return db % xfs_dir3_free_max_bests(geo);
} }
static void static void
......
...@@ -19,10 +19,6 @@ ...@@ -19,10 +19,6 @@
#ifndef __XFS_DA_FORMAT_H__ #ifndef __XFS_DA_FORMAT_H__
#define __XFS_DA_FORMAT_H__ #define __XFS_DA_FORMAT_H__
/*========================================================================
* Directory Structure when greater than XFS_LBSIZE(mp) bytes.
*========================================================================*/
/* /*
* This structure is common to both leaf nodes and non-leaf nodes in the Btree. * This structure is common to both leaf nodes and non-leaf nodes in the Btree.
* *
...@@ -122,8 +118,6 @@ struct xfs_da3_icnode_hdr { ...@@ -122,8 +118,6 @@ struct xfs_da3_icnode_hdr {
__uint16_t level; __uint16_t level;
}; };
#define XFS_LBSIZE(mp) (mp)->m_sb.sb_blocksize
/* /*
* Directory version 2. * Directory version 2.
* *
...@@ -330,8 +324,6 @@ xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr) ...@@ -330,8 +324,6 @@ xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
#define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG)) #define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
#define XFS_DIR2_DATA_SPACE 0 #define XFS_DIR2_DATA_SPACE 0
#define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE) #define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
#define XFS_DIR2_DATA_FIRSTDB(mp) \
xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
/* /*
* Describe a free area in the data block. * Describe a free area in the data block.
...@@ -456,8 +448,6 @@ xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup) ...@@ -456,8 +448,6 @@ xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
*/ */
#define XFS_DIR2_LEAF_SPACE 1 #define XFS_DIR2_LEAF_SPACE 1
#define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE) #define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
#define XFS_DIR2_LEAF_FIRSTDB(mp) \
xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
/* /*
* Leaf block header. * Leaf block header.
...@@ -513,17 +503,6 @@ struct xfs_dir3_leaf { ...@@ -513,17 +503,6 @@ struct xfs_dir3_leaf {
#define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc) #define XFS_DIR3_LEAF_CRC_OFF offsetof(struct xfs_dir3_leaf_hdr, info.crc)
/*
* Get address of the bestcount field in the single-leaf block.
*/
static inline struct xfs_dir2_leaf_tail *
xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
{
return (struct xfs_dir2_leaf_tail *)
((char *)lp + mp->m_dirblksize -
sizeof(struct xfs_dir2_leaf_tail));
}
/* /*
* Get address of the bests array in the single-leaf block. * Get address of the bests array in the single-leaf block.
*/ */
...@@ -533,123 +512,6 @@ xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp) ...@@ -533,123 +512,6 @@ xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
return (__be16 *)ltp - be32_to_cpu(ltp->bestcount); return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
} }
/*
* DB blocks here are logical directory block numbers, not filesystem blocks.
*/
/*
* Convert dataptr to byte in file space
*/
static inline xfs_dir2_off_t
xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
{
return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
}
/*
* Convert byte in file space to dataptr. It had better be aligned.
*/
static inline xfs_dir2_dataptr_t
xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
{
return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
}
/*
* Convert byte in space to (DB) block
*/
static inline xfs_dir2_db_t
xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
{
return (xfs_dir2_db_t)
(by >> (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog));
}
/*
* Convert dataptr to a block number
*/
static inline xfs_dir2_db_t
xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
{
return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(dp));
}
/*
* Convert byte in space to offset in a block
*/
static inline xfs_dir2_data_aoff_t
xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
{
return (xfs_dir2_data_aoff_t)(by &
((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) - 1));
}
/*
* Convert dataptr to a byte offset in a block
*/
static inline xfs_dir2_data_aoff_t
xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
{
return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(dp));
}
/*
* Convert block and offset to byte in space
*/
static inline xfs_dir2_off_t
xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
xfs_dir2_data_aoff_t o)
{
return ((xfs_dir2_off_t)db <<
(mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) + o;
}
/*
* Convert block (DB) to block (dablk)
*/
static inline xfs_dablk_t
xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
{
return (xfs_dablk_t)(db << mp->m_sb.sb_dirblklog);
}
/*
* Convert byte in space to (DA) block
*/
static inline xfs_dablk_t
xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
{
return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by));
}
/*
* Convert block and offset to dataptr
*/
static inline xfs_dir2_dataptr_t
xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
xfs_dir2_data_aoff_t o)
{
return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(mp, db, o));
}
/*
* Convert block (dablk) to block (DB)
*/
static inline xfs_dir2_db_t
xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
{
return (xfs_dir2_db_t)(da >> mp->m_sb.sb_dirblklog);
}
/*
* Convert block (dablk) to byte offset in space
*/
static inline xfs_dir2_off_t
xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
{
return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0);
}
/* /*
* Free space block defintions for the node format. * Free space block defintions for the node format.
*/ */
...@@ -659,8 +521,6 @@ xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da) ...@@ -659,8 +521,6 @@ xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
*/ */
#define XFS_DIR2_FREE_SPACE 2 #define XFS_DIR2_FREE_SPACE 2
#define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE) #define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
#define XFS_DIR2_FREE_FIRSTDB(mp) \
xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
typedef struct xfs_dir2_free_hdr { typedef struct xfs_dir2_free_hdr {
__be32 magic; /* XFS_DIR2_FREE_MAGIC */ __be32 magic; /* XFS_DIR2_FREE_MAGIC */
...@@ -735,16 +595,6 @@ typedef struct xfs_dir2_block_tail { ...@@ -735,16 +595,6 @@ typedef struct xfs_dir2_block_tail {
__be32 stale; /* count of stale lf entries */ __be32 stale; /* count of stale lf entries */
} xfs_dir2_block_tail_t; } xfs_dir2_block_tail_t;
/*
* Pointer to the leaf header embedded in a data block (1-block format)
*/
static inline struct xfs_dir2_block_tail *
xfs_dir2_block_tail_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr)
{
return ((struct xfs_dir2_block_tail *)
((char *)hdr + mp->m_dirblksize)) - 1;
}
/* /*
* Pointer to the leaf entries embedded in a data block (1-block format) * Pointer to the leaf entries embedded in a data block (1-block format)
*/ */
...@@ -764,10 +614,6 @@ xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp) ...@@ -764,10 +614,6 @@ xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
* of an attribute name may not be unique, we may have duplicate keys. The * of an attribute name may not be unique, we may have duplicate keys. The
* internal links in the Btree are logical block offsets into the file. * internal links in the Btree are logical block offsets into the file.
* *
*========================================================================
* Attribute structure when equal to XFS_LBSIZE(mp) bytes.
*========================================================================
*
* Struct leaf_entry's are packed from the top. Name/values grow from the * Struct leaf_entry's are packed from the top. Name/values grow from the
* bottom but are not packed. The freemap contains run-length-encoded entries * bottom but are not packed. The freemap contains run-length-encoded entries
* for the free bytes after the leaf_entry's, but only the N largest such, * for the free bytes after the leaf_entry's, but only the N largest such,
......
...@@ -85,11 +85,12 @@ static struct xfs_nameops xfs_ascii_ci_nameops = { ...@@ -85,11 +85,12 @@ static struct xfs_nameops xfs_ascii_ci_nameops = {
.compname = xfs_ascii_ci_compname, .compname = xfs_ascii_ci_compname,
}; };
void int
xfs_dir_mount( xfs_da_mount(
xfs_mount_t *mp) struct xfs_mount *mp)
{ {
int nodehdr_size; struct xfs_da_geometry *dageo;
int nodehdr_size;
ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT); ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
...@@ -99,24 +100,59 @@ xfs_dir_mount( ...@@ -99,24 +100,59 @@ xfs_dir_mount(
mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL); mp->m_dir_inode_ops = xfs_dir_get_ops(mp, NULL);
mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL); mp->m_nondir_inode_ops = xfs_nondir_get_ops(mp, NULL);
mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
mp->m_dirblkfsbs = 1 << mp->m_sb.sb_dirblklog;
mp->m_dirdatablk = xfs_dir2_db_to_da(mp, XFS_DIR2_DATA_FIRSTDB(mp));
mp->m_dirleafblk = xfs_dir2_db_to_da(mp, XFS_DIR2_LEAF_FIRSTDB(mp));
mp->m_dirfreeblk = xfs_dir2_db_to_da(mp, XFS_DIR2_FREE_FIRSTDB(mp));
nodehdr_size = mp->m_dir_inode_ops->node_hdr_size; nodehdr_size = mp->m_dir_inode_ops->node_hdr_size;
mp->m_attr_node_ents = (mp->m_sb.sb_blocksize - nodehdr_size) / mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
KM_SLEEP | KM_MAYFAIL);
mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
KM_SLEEP | KM_MAYFAIL);
if (!mp->m_dir_geo || !mp->m_attr_geo) {
kmem_free(mp->m_dir_geo);
kmem_free(mp->m_attr_geo);
return ENOMEM;
}
/* set up directory geometry */
dageo = mp->m_dir_geo;
dageo->blklog = mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog;
dageo->fsblog = mp->m_sb.sb_blocklog;
dageo->blksize = 1 << dageo->blklog;
dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
/*
* Now we've set up the block conversion variables, we can calculate the
* segment block constants using the geometry structure.
*/
dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET);
dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET);
dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET);
dageo->node_ents = (dageo->blksize - nodehdr_size) /
(uint)sizeof(xfs_da_node_entry_t); (uint)sizeof(xfs_da_node_entry_t);
mp->m_dir_node_ents = (mp->m_dirblksize - nodehdr_size) / dageo->magicpct = (dageo->blksize * 37) / 100;
/* set up attribute geometry - single fsb only */
dageo = mp->m_attr_geo;
dageo->blklog = mp->m_sb.sb_blocklog;
dageo->fsblog = mp->m_sb.sb_blocklog;
dageo->blksize = 1 << dageo->blklog;
dageo->fsbcount = 1;
dageo->node_ents = (dageo->blksize - nodehdr_size) /
(uint)sizeof(xfs_da_node_entry_t); (uint)sizeof(xfs_da_node_entry_t);
dageo->magicpct = (dageo->blksize * 37) / 100;
mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100;
if (xfs_sb_version_hasasciici(&mp->m_sb)) if (xfs_sb_version_hasasciici(&mp->m_sb))
mp->m_dirnameops = &xfs_ascii_ci_nameops; mp->m_dirnameops = &xfs_ascii_ci_nameops;
else else
mp->m_dirnameops = &xfs_default_nameops; mp->m_dirnameops = &xfs_default_nameops;
return 0;
}
void
xfs_da_unmount(
struct xfs_mount *mp)
{
kmem_free(mp->m_dir_geo);
kmem_free(mp->m_attr_geo);
} }
/* /*
...@@ -192,6 +228,7 @@ xfs_dir_init( ...@@ -192,6 +228,7 @@ xfs_dir_init(
if (!args) if (!args)
return ENOMEM; return ENOMEM;
args->geo = dp->i_mount->m_dir_geo;
args->dp = dp; args->dp = dp;
args->trans = tp; args->trans = tp;
error = xfs_dir2_sf_create(args, pdp->i_ino); error = xfs_dir2_sf_create(args, pdp->i_ino);
...@@ -226,6 +263,7 @@ xfs_dir_createname( ...@@ -226,6 +263,7 @@ xfs_dir_createname(
if (!args) if (!args)
return ENOMEM; return ENOMEM;
args->geo = dp->i_mount->m_dir_geo;
args->name = name->name; args->name = name->name;
args->namelen = name->len; args->namelen = name->len;
args->filetype = name->type; args->filetype = name->type;
...@@ -244,7 +282,7 @@ xfs_dir_createname( ...@@ -244,7 +282,7 @@ xfs_dir_createname(
goto out_free; goto out_free;
} }
rval = xfs_dir2_isblock(dp, &v); rval = xfs_dir2_isblock(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) { if (v) {
...@@ -252,7 +290,7 @@ xfs_dir_createname( ...@@ -252,7 +290,7 @@ xfs_dir_createname(
goto out_free; goto out_free;
} }
rval = xfs_dir2_isleaf(dp, &v); rval = xfs_dir2_isleaf(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) if (v)
...@@ -320,6 +358,7 @@ xfs_dir_lookup( ...@@ -320,6 +358,7 @@ xfs_dir_lookup(
* annotations into the reclaim path for the ilock. * annotations into the reclaim path for the ilock.
*/ */
args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS);
args->geo = dp->i_mount->m_dir_geo;
args->name = name->name; args->name = name->name;
args->namelen = name->len; args->namelen = name->len;
args->filetype = name->type; args->filetype = name->type;
...@@ -336,7 +375,7 @@ xfs_dir_lookup( ...@@ -336,7 +375,7 @@ xfs_dir_lookup(
goto out_check_rval; goto out_check_rval;
} }
rval = xfs_dir2_isblock(dp, &v); rval = xfs_dir2_isblock(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) { if (v) {
...@@ -344,7 +383,7 @@ xfs_dir_lookup( ...@@ -344,7 +383,7 @@ xfs_dir_lookup(
goto out_check_rval; goto out_check_rval;
} }
rval = xfs_dir2_isleaf(dp, &v); rval = xfs_dir2_isleaf(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) if (v)
...@@ -391,6 +430,7 @@ xfs_dir_removename( ...@@ -391,6 +430,7 @@ xfs_dir_removename(
if (!args) if (!args)
return ENOMEM; return ENOMEM;
args->geo = dp->i_mount->m_dir_geo;
args->name = name->name; args->name = name->name;
args->namelen = name->len; args->namelen = name->len;
args->filetype = name->type; args->filetype = name->type;
...@@ -408,7 +448,7 @@ xfs_dir_removename( ...@@ -408,7 +448,7 @@ xfs_dir_removename(
goto out_free; goto out_free;
} }
rval = xfs_dir2_isblock(dp, &v); rval = xfs_dir2_isblock(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) { if (v) {
...@@ -416,7 +456,7 @@ xfs_dir_removename( ...@@ -416,7 +456,7 @@ xfs_dir_removename(
goto out_free; goto out_free;
} }
rval = xfs_dir2_isleaf(dp, &v); rval = xfs_dir2_isleaf(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) if (v)
...@@ -455,6 +495,7 @@ xfs_dir_replace( ...@@ -455,6 +495,7 @@ xfs_dir_replace(
if (!args) if (!args)
return ENOMEM; return ENOMEM;
args->geo = dp->i_mount->m_dir_geo;
args->name = name->name; args->name = name->name;
args->namelen = name->len; args->namelen = name->len;
args->filetype = name->type; args->filetype = name->type;
...@@ -472,7 +513,7 @@ xfs_dir_replace( ...@@ -472,7 +513,7 @@ xfs_dir_replace(
goto out_free; goto out_free;
} }
rval = xfs_dir2_isblock(dp, &v); rval = xfs_dir2_isblock(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) { if (v) {
...@@ -480,7 +521,7 @@ xfs_dir_replace( ...@@ -480,7 +521,7 @@ xfs_dir_replace(
goto out_free; goto out_free;
} }
rval = xfs_dir2_isleaf(dp, &v); rval = xfs_dir2_isleaf(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) if (v)
...@@ -516,6 +557,7 @@ xfs_dir_canenter( ...@@ -516,6 +557,7 @@ xfs_dir_canenter(
if (!args) if (!args)
return ENOMEM; return ENOMEM;
args->geo = dp->i_mount->m_dir_geo;
args->name = name->name; args->name = name->name;
args->namelen = name->len; args->namelen = name->len;
args->filetype = name->type; args->filetype = name->type;
...@@ -531,7 +573,7 @@ xfs_dir_canenter( ...@@ -531,7 +573,7 @@ xfs_dir_canenter(
goto out_free; goto out_free;
} }
rval = xfs_dir2_isblock(dp, &v); rval = xfs_dir2_isblock(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) { if (v) {
...@@ -539,7 +581,7 @@ xfs_dir_canenter( ...@@ -539,7 +581,7 @@ xfs_dir_canenter(
goto out_free; goto out_free;
} }
rval = xfs_dir2_isleaf(dp, &v); rval = xfs_dir2_isleaf(args, &v);
if (rval) if (rval)
goto out_free; goto out_free;
if (v) if (v)
...@@ -579,13 +621,13 @@ xfs_dir2_grow_inode( ...@@ -579,13 +621,13 @@ xfs_dir2_grow_inode(
* Set lowest possible block in the space requested. * Set lowest possible block in the space requested.
*/ */
bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE); bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE);
count = mp->m_dirblkfsbs; count = args->geo->fsbcount;
error = xfs_da_grow_inode_int(args, &bno, count); error = xfs_da_grow_inode_int(args, &bno, count);
if (error) if (error)
return error; return error;
*dbp = xfs_dir2_da_to_db(mp, (xfs_dablk_t)bno); *dbp = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)bno);
/* /*
* Update file's size if this is the data space and it grew. * Update file's size if this is the data space and it grew.
...@@ -607,18 +649,16 @@ xfs_dir2_grow_inode( ...@@ -607,18 +649,16 @@ xfs_dir2_grow_inode(
*/ */
int int
xfs_dir2_isblock( xfs_dir2_isblock(
xfs_inode_t *dp, struct xfs_da_args *args,
int *vp) /* out: 1 is block, 0 is not block */ int *vp) /* out: 1 is block, 0 is not block */
{ {
xfs_fileoff_t last; /* last file offset */ xfs_fileoff_t last; /* last file offset */
xfs_mount_t *mp; int rval;
int rval;
mp = dp->i_mount; if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
if ((rval = xfs_bmap_last_offset(dp, &last, XFS_DATA_FORK)))
return rval; return rval;
rval = XFS_FSB_TO_B(mp, last) == mp->m_dirblksize; rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize;
ASSERT(rval == 0 || dp->i_d.di_size == mp->m_dirblksize); ASSERT(rval == 0 || args->dp->i_d.di_size == args->geo->blksize);
*vp = rval; *vp = rval;
return 0; return 0;
} }
...@@ -628,17 +668,15 @@ xfs_dir2_isblock( ...@@ -628,17 +668,15 @@ xfs_dir2_isblock(
*/ */
int int
xfs_dir2_isleaf( xfs_dir2_isleaf(
xfs_inode_t *dp, struct xfs_da_args *args,
int *vp) /* out: 1 is leaf, 0 is not leaf */ int *vp) /* out: 1 is block, 0 is not block */
{ {
xfs_fileoff_t last; /* last file offset */ xfs_fileoff_t last; /* last file offset */
xfs_mount_t *mp; int rval;
int rval;
mp = dp->i_mount; if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK)))
if ((rval = xfs_bmap_last_offset(dp, &last, XFS_DATA_FORK)))
return rval; return rval;
*vp = last == mp->m_dirleafblk + (1 << mp->m_sb.sb_dirblklog); *vp = last == args->geo->leafblk + args->geo->fsbcount;
return 0; return 0;
} }
...@@ -666,11 +704,11 @@ xfs_dir2_shrink_inode( ...@@ -666,11 +704,11 @@ xfs_dir2_shrink_inode(
dp = args->dp; dp = args->dp;
mp = dp->i_mount; mp = dp->i_mount;
tp = args->trans; tp = args->trans;
da = xfs_dir2_db_to_da(mp, db); da = xfs_dir2_db_to_da(args->geo, db);
/* /*
* Unmap the fsblock(s). * Unmap the fsblock(s).
*/ */
if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs, if ((error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount,
XFS_BMAPI_METADATA, 0, args->firstblock, args->flist, XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
&done))) { &done))) {
/* /*
...@@ -697,12 +735,12 @@ xfs_dir2_shrink_inode( ...@@ -697,12 +735,12 @@ xfs_dir2_shrink_inode(
/* /*
* If it's not a data block, we're done. * If it's not a data block, we're done.
*/ */
if (db >= XFS_DIR2_LEAF_FIRSTDB(mp)) if (db >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET))
return 0; return 0;
/* /*
* If the block isn't the last one in the directory, we're done. * If the block isn't the last one in the directory, we're done.
*/ */
if (dp->i_d.di_size > xfs_dir2_db_off_to_byte(mp, db + 1, 0)) if (dp->i_d.di_size > xfs_dir2_db_off_to_byte(args->geo, db + 1, 0))
return 0; return 0;
bno = da; bno = da;
if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) { if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) {
...@@ -711,7 +749,7 @@ xfs_dir2_shrink_inode( ...@@ -711,7 +749,7 @@ xfs_dir2_shrink_inode(
*/ */
return error; return error;
} }
if (db == mp->m_dirdatablk) if (db == args->geo->datablk)
ASSERT(bno == 0); ASSERT(bno == 0);
else else
ASSERT(bno > 0); ASSERT(bno > 0);
......
...@@ -80,7 +80,7 @@ struct xfs_dir_ops { ...@@ -80,7 +80,7 @@ struct xfs_dir_ops {
struct xfs_dir3_icleaf_hdr *from); struct xfs_dir3_icleaf_hdr *from);
void (*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to, void (*leaf_hdr_from_disk)(struct xfs_dir3_icleaf_hdr *to,
struct xfs_dir2_leaf *from); struct xfs_dir2_leaf *from);
int (*leaf_max_ents)(struct xfs_mount *mp); int (*leaf_max_ents)(struct xfs_da_geometry *geo);
struct xfs_dir2_leaf_entry * struct xfs_dir2_leaf_entry *
(*leaf_ents_p)(struct xfs_dir2_leaf *lp); (*leaf_ents_p)(struct xfs_dir2_leaf *lp);
...@@ -97,10 +97,12 @@ struct xfs_dir_ops { ...@@ -97,10 +97,12 @@ struct xfs_dir_ops {
struct xfs_dir3_icfree_hdr *from); struct xfs_dir3_icfree_hdr *from);
void (*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to, void (*free_hdr_from_disk)(struct xfs_dir3_icfree_hdr *to,
struct xfs_dir2_free *from); struct xfs_dir2_free *from);
int (*free_max_bests)(struct xfs_mount *mp); int (*free_max_bests)(struct xfs_da_geometry *geo);
__be16 * (*free_bests_p)(struct xfs_dir2_free *free); __be16 * (*free_bests_p)(struct xfs_dir2_free *free);
xfs_dir2_db_t (*db_to_fdb)(struct xfs_mount *mp, xfs_dir2_db_t db); xfs_dir2_db_t (*db_to_fdb)(struct xfs_da_geometry *geo,
int (*db_to_fdindex)(struct xfs_mount *mp, xfs_dir2_db_t db); xfs_dir2_db_t db);
int (*db_to_fdindex)(struct xfs_da_geometry *geo,
xfs_dir2_db_t db);
}; };
extern const struct xfs_dir_ops * extern const struct xfs_dir_ops *
...@@ -112,7 +114,9 @@ extern const struct xfs_dir_ops * ...@@ -112,7 +114,9 @@ extern const struct xfs_dir_ops *
* Generic directory interface routines * Generic directory interface routines
*/ */
extern void xfs_dir_startup(void); extern void xfs_dir_startup(void);
extern void xfs_dir_mount(struct xfs_mount *mp); extern int xfs_da_mount(struct xfs_mount *mp);
extern void xfs_da_unmount(struct xfs_mount *mp);
extern int xfs_dir_isempty(struct xfs_inode *dp); extern int xfs_dir_isempty(struct xfs_inode *dp);
extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp, extern int xfs_dir_init(struct xfs_trans *tp, struct xfs_inode *dp,
struct xfs_inode *pdp); struct xfs_inode *pdp);
...@@ -142,23 +146,23 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args); ...@@ -142,23 +146,23 @@ extern int xfs_dir2_sf_to_block(struct xfs_da_args *args);
/* /*
* Interface routines used by userspace utilities * Interface routines used by userspace utilities
*/ */
extern int xfs_dir2_isblock(struct xfs_inode *dp, int *r); extern int xfs_dir2_isblock(struct xfs_da_args *args, int *r);
extern int xfs_dir2_isleaf(struct xfs_inode *dp, int *r); extern int xfs_dir2_isleaf(struct xfs_da_args *args, int *r);
extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db, extern int xfs_dir2_shrink_inode(struct xfs_da_args *args, xfs_dir2_db_t db,
struct xfs_buf *bp); struct xfs_buf *bp);
extern void xfs_dir2_data_freescan(struct xfs_inode *dp, extern void xfs_dir2_data_freescan(struct xfs_inode *dp,
struct xfs_dir2_data_hdr *hdr, int *loghead); struct xfs_dir2_data_hdr *hdr, int *loghead);
extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_inode *dp, extern void xfs_dir2_data_log_entry(struct xfs_da_args *args,
struct xfs_buf *bp, struct xfs_dir2_data_entry *dep); struct xfs_buf *bp, struct xfs_dir2_data_entry *dep);
extern void xfs_dir2_data_log_header(struct xfs_trans *tp, struct xfs_inode *dp, extern void xfs_dir2_data_log_header(struct xfs_da_args *args,
struct xfs_buf *bp); struct xfs_buf *bp);
extern void xfs_dir2_data_log_unused(struct xfs_trans *tp, struct xfs_buf *bp, extern void xfs_dir2_data_log_unused(struct xfs_da_args *args,
struct xfs_dir2_data_unused *dup); struct xfs_buf *bp, struct xfs_dir2_data_unused *dup);
extern void xfs_dir2_data_make_free(struct xfs_trans *tp, struct xfs_inode *dp, extern void xfs_dir2_data_make_free(struct xfs_da_args *args,
struct xfs_buf *bp, xfs_dir2_data_aoff_t offset, struct xfs_buf *bp, xfs_dir2_data_aoff_t offset,
xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_inode *dp, extern void xfs_dir2_data_use_free(struct xfs_da_args *args,
struct xfs_buf *bp, struct xfs_dir2_data_unused *dup, struct xfs_buf *bp, struct xfs_dir2_data_unused *dup,
xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len, xfs_dir2_data_aoff_t offset, xfs_dir2_data_aoff_t len,
int *needlogp, int *needscanp); int *needlogp, int *needscanp);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -20,6 +20,140 @@ ...@@ -20,6 +20,140 @@
struct dir_context; struct dir_context;
/*
* Directory offset/block conversion functions.
*
* DB blocks here are logical directory block numbers, not filesystem blocks.
*/
/*
* Convert dataptr to byte in file space
*/
static inline xfs_dir2_off_t
xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
{
return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
}
/*
* Convert byte in file space to dataptr. It had better be aligned.
*/
static inline xfs_dir2_dataptr_t
xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
{
return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
}
/*
* Convert byte in space to (DB) block
*/
static inline xfs_dir2_db_t
xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
{
return (xfs_dir2_db_t)(by >> geo->blklog);
}
/*
* Convert dataptr to a block number
*/
static inline xfs_dir2_db_t
xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
{
return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
}
/*
* Convert byte in space to offset in a block
*/
static inline xfs_dir2_data_aoff_t
xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
{
return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
}
/*
* Convert dataptr to a byte offset in a block
*/
static inline xfs_dir2_data_aoff_t
xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
{
return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
}
/*
* Convert block and offset to byte in space
*/
static inline xfs_dir2_off_t
xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
xfs_dir2_data_aoff_t o)
{
return ((xfs_dir2_off_t)db << geo->blklog) + o;
}
/*
* Convert block (DB) to block (dablk)
*/
static inline xfs_dablk_t
xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
{
return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
}
/*
* Convert byte in space to (DA) block
*/
static inline xfs_dablk_t
xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
{
return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
}
/*
* Convert block and offset to dataptr
*/
static inline xfs_dir2_dataptr_t
xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
xfs_dir2_data_aoff_t o)
{
return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
}
/*
* Convert block (dablk) to block (DB)
*/
static inline xfs_dir2_db_t
xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
{
return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
}
/*
* Convert block (dablk) to byte offset in space
*/
static inline xfs_dir2_off_t
xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
{
return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
}
/*
* Directory tail pointer accessor functions. Based on block geometry.
*/
static inline struct xfs_dir2_block_tail *
xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
{
return ((struct xfs_dir2_block_tail *)
((char *)hdr + geo->blksize)) - 1;
}
static inline struct xfs_dir2_leaf_tail *
xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
{
return (struct xfs_dir2_leaf_tail *)
((char *)lp + geo->blksize -
sizeof(struct xfs_dir2_leaf_tail));
}
/* xfs_dir2.c */ /* xfs_dir2.c */
extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino); extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space, extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
...@@ -77,9 +211,9 @@ extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr, ...@@ -77,9 +211,9 @@ extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
int *lowstalep, int *highstalep, int *lowlogp, int *highlogp); int *lowstalep, int *highstalep, int *lowlogp, int *highlogp);
extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno, extern int xfs_dir3_leaf_get_buf(struct xfs_da_args *args, xfs_dir2_db_t bno,
struct xfs_buf **bpp, __uint16_t magic); struct xfs_buf **bpp, __uint16_t magic);
extern void xfs_dir3_leaf_log_ents(struct xfs_trans *tp, struct xfs_inode *dp, extern void xfs_dir3_leaf_log_ents(struct xfs_da_args *args,
struct xfs_buf *bp, int first, int last); struct xfs_buf *bp, int first, int last);
extern void xfs_dir3_leaf_log_header(struct xfs_trans *tp, struct xfs_inode *dp, extern void xfs_dir3_leaf_log_header(struct xfs_da_args *args,
struct xfs_buf *bp); struct xfs_buf *bp);
extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args); extern int xfs_dir2_leaf_lookup(struct xfs_da_args *args);
extern int xfs_dir2_leaf_removename(struct xfs_da_args *args); extern int xfs_dir2_leaf_removename(struct xfs_da_args *args);
......
This diff is collapsed.
...@@ -82,8 +82,10 @@ xfs_dir2_block_sfsize( ...@@ -82,8 +82,10 @@ xfs_dir2_block_sfsize(
xfs_ino_t parent = 0; /* parent inode number */ xfs_ino_t parent = 0; /* parent inode number */
int size=0; /* total computed size */ int size=0; /* total computed size */
int has_ftype; int has_ftype;
struct xfs_da_geometry *geo;
mp = dp->i_mount; mp = dp->i_mount;
geo = mp->m_dir_geo;
/* /*
* if there is a filetype field, add the extra byte to the namelen * if there is a filetype field, add the extra byte to the namelen
...@@ -92,7 +94,7 @@ xfs_dir2_block_sfsize( ...@@ -92,7 +94,7 @@ xfs_dir2_block_sfsize(
has_ftype = xfs_sb_version_hasftype(&mp->m_sb) ? 1 : 0; has_ftype = xfs_sb_version_hasftype(&mp->m_sb) ? 1 : 0;
count = i8count = namelen = 0; count = i8count = namelen = 0;
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(geo, hdr);
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
/* /*
...@@ -104,8 +106,8 @@ xfs_dir2_block_sfsize( ...@@ -104,8 +106,8 @@ xfs_dir2_block_sfsize(
/* /*
* Calculate the pointer to the entry at hand. * Calculate the pointer to the entry at hand.
*/ */
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)((char *)hdr +
((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); xfs_dir2_dataptr_to_off(geo, addr));
/* /*
* Detect . and .., so we can special-case them. * Detect . and .., so we can special-case them.
* . is not included in sf directories. * . is not included in sf directories.
...@@ -195,7 +197,7 @@ xfs_dir2_block_to_sf( ...@@ -195,7 +197,7 @@ xfs_dir2_block_to_sf(
/* /*
* Set up to loop over the block's entries. * Set up to loop over the block's entries.
*/ */
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
ptr = (char *)dp->d_ops->data_entry_p(hdr); ptr = (char *)dp->d_ops->data_entry_p(hdr);
endptr = (char *)xfs_dir2_block_leaf_p(btp); endptr = (char *)xfs_dir2_block_leaf_p(btp);
sfep = xfs_dir2_sf_firstentry(sfp); sfep = xfs_dir2_sf_firstentry(sfp);
...@@ -247,7 +249,7 @@ xfs_dir2_block_to_sf( ...@@ -247,7 +249,7 @@ xfs_dir2_block_to_sf(
/* now we are done with the block, we can shrink the inode */ /* now we are done with the block, we can shrink the inode */
logflags = XFS_ILOG_CORE; logflags = XFS_ILOG_CORE;
error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp); error = xfs_dir2_shrink_inode(args, args->geo->datablk, bp);
if (error) { if (error) {
ASSERT(error != ENOSPC); ASSERT(error != ENOSPC);
goto out; goto out;
...@@ -586,7 +588,7 @@ xfs_dir2_sf_addname_pick( ...@@ -586,7 +588,7 @@ xfs_dir2_sf_addname_pick(
* we'll go back, convert to block, then try the insert and convert * we'll go back, convert to block, then try the insert and convert
* to leaf. * to leaf.
*/ */
if (used + (holefit ? 0 : size) > mp->m_dirblksize) if (used + (holefit ? 0 : size) > args->geo->blksize)
return 0; return 0;
/* /*
* If changing the inode number size, do it the hard way. * If changing the inode number size, do it the hard way.
...@@ -601,7 +603,7 @@ xfs_dir2_sf_addname_pick( ...@@ -601,7 +603,7 @@ xfs_dir2_sf_addname_pick(
/* /*
* If it won't fit at the end then do it the hard way (use the hole). * If it won't fit at the end then do it the hard way (use the hole).
*/ */
if (used + size > mp->m_dirblksize) if (used + size > args->geo->blksize)
return 2; return 2;
/* /*
* Do it the easy way. * Do it the easy way.
...@@ -652,7 +654,7 @@ xfs_dir2_sf_check( ...@@ -652,7 +654,7 @@ xfs_dir2_sf_check(
ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size);
ASSERT(offset + ASSERT(offset +
(sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) +
(uint)sizeof(xfs_dir2_block_tail_t) <= mp->m_dirblksize); (uint)sizeof(xfs_dir2_block_tail_t) <= args->geo->blksize);
} }
#endif /* DEBUG */ #endif /* DEBUG */
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "xfs_sb.h" #include "xfs_sb.h"
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_inode.h" #include "xfs_inode.h"
#include "xfs_trans.h" #include "xfs_trans.h"
#include "xfs_inode_item.h" #include "xfs_inode_item.h"
...@@ -105,7 +107,7 @@ xfs_fs_geometry( ...@@ -105,7 +107,7 @@ xfs_fs_geometry(
geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ?
mp->m_sb.sb_logsectsize : BBSIZE; mp->m_sb.sb_logsectsize : BBSIZE;
geo->rtsectsize = mp->m_sb.sb_blocksize; geo->rtsectsize = mp->m_sb.sb_blocksize;
geo->dirblocksize = mp->m_dirblksize; geo->dirblocksize = mp->m_dir_geo->blksize;
} }
if (new_version >= 4) { if (new_version >= 4) {
geo->flags |= geo->flags |=
......
...@@ -42,7 +42,7 @@ xfs_log_calc_max_attrsetm_res( ...@@ -42,7 +42,7 @@ xfs_log_calc_max_attrsetm_res(
int size; int size;
int nblks; int nblks;
size = xfs_attr_leaf_entsize_local_max(mp->m_sb.sb_blocksize) - size = xfs_attr_leaf_entsize_local_max(mp->m_attr_geo->blksize) -
MAXNAMELEN - 1; MAXNAMELEN - 1;
nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK); nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
nblks += XFS_B_TO_FSB(mp, size); nblks += XFS_B_TO_FSB(mp, size);
......
...@@ -780,12 +780,11 @@ xfs_mountfs( ...@@ -780,12 +780,11 @@ xfs_mountfs(
mp->m_dmevmask = 0; /* not persistent; set after each mount */ mp->m_dmevmask = 0; /* not persistent; set after each mount */
xfs_dir_mount(mp); error = xfs_da_mount(mp);
if (error) {
/* xfs_warn(mp, "Failed dir/attr init: %d", error);
* Initialize the attribute manager's entries. goto out_remove_uuid;
*/ }
mp->m_attr_magicpct = (mp->m_sb.sb_blocksize * 37) / 100;
/* /*
* Initialize the precomputed transaction reservations values. * Initialize the precomputed transaction reservations values.
...@@ -800,7 +799,7 @@ xfs_mountfs( ...@@ -800,7 +799,7 @@ xfs_mountfs(
error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi); error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);
if (error) { if (error) {
xfs_warn(mp, "Failed per-ag init: %d", error); xfs_warn(mp, "Failed per-ag init: %d", error);
goto out_remove_uuid; goto out_free_dir;
} }
if (!sbp->sb_logblocks) { if (!sbp->sb_logblocks) {
...@@ -975,6 +974,8 @@ xfs_mountfs( ...@@ -975,6 +974,8 @@ xfs_mountfs(
xfs_wait_buftarg(mp->m_ddev_targp); xfs_wait_buftarg(mp->m_ddev_targp);
out_free_perag: out_free_perag:
xfs_free_perag(mp); xfs_free_perag(mp);
out_free_dir:
xfs_da_unmount(mp);
out_remove_uuid: out_remove_uuid:
xfs_uuid_unmount(mp); xfs_uuid_unmount(mp);
out: out:
...@@ -1052,6 +1053,7 @@ xfs_unmountfs( ...@@ -1052,6 +1053,7 @@ xfs_unmountfs(
"Freespace may not be correct on next mount."); "Freespace may not be correct on next mount.");
xfs_log_unmount(mp); xfs_log_unmount(mp);
xfs_da_unmount(mp);
xfs_uuid_unmount(mp); xfs_uuid_unmount(mp);
#if defined(DEBUG) #if defined(DEBUG)
......
...@@ -27,6 +27,7 @@ struct xfs_nameops; ...@@ -27,6 +27,7 @@ struct xfs_nameops;
struct xfs_ail; struct xfs_ail;
struct xfs_quotainfo; struct xfs_quotainfo;
struct xfs_dir_ops; struct xfs_dir_ops;
struct xfs_da_geometry;
#ifdef HAVE_PERCPU_SB #ifdef HAVE_PERCPU_SB
...@@ -96,6 +97,8 @@ typedef struct xfs_mount { ...@@ -96,6 +97,8 @@ typedef struct xfs_mount {
uint m_readio_blocks; /* min read size blocks */ uint m_readio_blocks; /* min read size blocks */
uint m_writeio_log; /* min write size log bytes */ uint m_writeio_log; /* min write size log bytes */
uint m_writeio_blocks; /* min write size blocks */ uint m_writeio_blocks; /* min write size blocks */
struct xfs_da_geometry *m_dir_geo; /* directory block geometry */
struct xfs_da_geometry *m_attr_geo; /* attribute block geometry */
struct xlog *m_log; /* log specific stuff */ struct xlog *m_log; /* log specific stuff */
int m_logbufs; /* number of log buffers */ int m_logbufs; /* number of log buffers */
int m_logbsize; /* size of each log buffer */ int m_logbsize; /* size of each log buffer */
...@@ -131,8 +134,6 @@ typedef struct xfs_mount { ...@@ -131,8 +134,6 @@ typedef struct xfs_mount {
int m_fixedfsid[2]; /* unchanged for life of FS */ int m_fixedfsid[2]; /* unchanged for life of FS */
uint m_dmevmask; /* DMI events for this FS */ uint m_dmevmask; /* DMI events for this FS */
__uint64_t m_flags; /* global mount flags */ __uint64_t m_flags; /* global mount flags */
uint m_dir_node_ents; /* #entries in a dir danode */
uint m_attr_node_ents; /* #entries in attr danode */
int m_ialloc_inos; /* inodes in inode allocation */ int m_ialloc_inos; /* inodes in inode allocation */
int m_ialloc_blks; /* blocks in inode allocation */ int m_ialloc_blks; /* blocks in inode allocation */
int m_inoalign_mask;/* mask sb_inoalignmt if used */ int m_inoalign_mask;/* mask sb_inoalignmt if used */
...@@ -145,17 +146,10 @@ typedef struct xfs_mount { ...@@ -145,17 +146,10 @@ typedef struct xfs_mount {
int m_dalign; /* stripe unit */ int m_dalign; /* stripe unit */
int m_swidth; /* stripe width */ int m_swidth; /* stripe width */
int m_sinoalign; /* stripe unit inode alignment */ int m_sinoalign; /* stripe unit inode alignment */
int m_attr_magicpct;/* 37% of the blocksize */
int m_dir_magicpct; /* 37% of the dir blocksize */
__uint8_t m_sectbb_log; /* sectlog - BBSHIFT */ __uint8_t m_sectbb_log; /* sectlog - BBSHIFT */
const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */ const struct xfs_nameops *m_dirnameops; /* vector of dir name ops */
const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */ const struct xfs_dir_ops *m_dir_inode_ops; /* vector of dir inode ops */
const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode ops */ const struct xfs_dir_ops *m_nondir_inode_ops; /* !dir inode ops */
int m_dirblksize; /* directory block sz--bytes */
int m_dirblkfsbs; /* directory block sz--fsbs */
xfs_dablk_t m_dirdatablk; /* blockno of dir data v2 */
xfs_dablk_t m_dirleafblk; /* blockno of dir non-data v2 */
xfs_dablk_t m_dirfreeblk; /* blockno of dirfreeindex v2 */
uint m_chsize; /* size of next field */ uint m_chsize; /* size of next field */
atomic_t m_active_trans; /* number trans frozen */ atomic_t m_active_trans; /* number trans frozen */
#ifdef HAVE_PERCPU_SB #ifdef HAVE_PERCPU_SB
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_da_format.h" #include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_dir2.h" #include "xfs_dir2.h"
#include "xfs_inode.h" #include "xfs_inode.h"
#include "xfs_ialloc.h" #include "xfs_ialloc.h"
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "xfs_ag.h" #include "xfs_ag.h"
#include "xfs_mount.h" #include "xfs_mount.h"
#include "xfs_da_format.h" #include "xfs_da_format.h"
#include "xfs_da_btree.h"
#include "xfs_inode.h" #include "xfs_inode.h"
#include "xfs_bmap_btree.h" #include "xfs_bmap_btree.h"
#include "xfs_ialloc.h" #include "xfs_ialloc.h"
...@@ -609,7 +610,7 @@ xfs_calc_addafork_reservation( ...@@ -609,7 +610,7 @@ xfs_calc_addafork_reservation(
return XFS_DQUOT_LOGRES(mp) + return XFS_DQUOT_LOGRES(mp) +
xfs_calc_inode_res(mp, 1) + xfs_calc_inode_res(mp, 1) +
xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
xfs_calc_buf_res(1, mp->m_dirblksize) + xfs_calc_buf_res(1, mp->m_dir_geo->blksize) +
xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1, xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1,
XFS_FSB_TO_B(mp, 1)) + XFS_FSB_TO_B(mp, 1)) +
xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1),
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
(((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \ (((b + XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp) - 1) / \
XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \ XFS_MAX_CONTIG_EXTENTS_PER_BLOCK(mp)) * \
XFS_EXTENTADD_SPACE_RES(mp,w)) XFS_EXTENTADD_SPACE_RES(mp,w))
#define XFS_DAENTER_1B(mp,w) ((w) == XFS_DATA_FORK ? (mp)->m_dirblkfsbs : 1) #define XFS_DAENTER_1B(mp,w) \
((w) == XFS_DATA_FORK ? (mp)->m_dir_geo->fsbcount : 1)
#define XFS_DAENTER_DBS(mp,w) \ #define XFS_DAENTER_DBS(mp,w) \
(XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0)) (XFS_DA_NODE_MAXDEPTH + (((w) == XFS_DATA_FORK) ? 2 : 0))
#define XFS_DAENTER_BLOCKS(mp,w) \ #define XFS_DAENTER_BLOCKS(mp,w) \
...@@ -55,7 +56,7 @@ ...@@ -55,7 +56,7 @@
* Space reservation values for various transactions. * Space reservation values for various transactions.
*/ */
#define XFS_ADDAFORK_SPACE_RES(mp) \ #define XFS_ADDAFORK_SPACE_RES(mp) \
((mp)->m_dirblkfsbs + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK)) ((mp)->m_dir_geo->fsbcount + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK))
#define XFS_ATTRRM_SPACE_RES(mp) \ #define XFS_ATTRRM_SPACE_RES(mp) \
XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK) XFS_DAREMOVE_SPACE_RES(mp, XFS_ATTR_FORK)
/* This macro is not used - see inline code in xfs_attr_set */ /* This macro is not used - see inline code in xfs_attr_set */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment