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

This commit is contained in:
Dave Chinner 2014-06-10 07:32:41 +10:00
commit 8612c7e594
26 changed files with 821 additions and 780 deletions

View File

@ -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(
* 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)
} }
/*======================================================================== /*========================================================================
* External routines when attribute list size > XFS_LBSIZE(mp). * External routines when attribute list size > geo->blksize
*========================================================================*/ *========================================================================*/
/* /*
@ -897,8 +896,6 @@ restart:
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 @@ restart:
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)
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)
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.

View File

@ -80,11 +80,12 @@ STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state,
/* /*
* Utility routines. * Utility routines.
*/ */
STATIC void xfs_attr3_leaf_moveents(struct xfs_attr_leafblock *src_leaf, STATIC void xfs_attr3_leaf_moveents(struct xfs_da_args *args,
struct xfs_attr_leafblock *src_leaf,
struct xfs_attr3_icleaf_hdr *src_ichdr, int src_start, struct xfs_attr3_icleaf_hdr *src_ichdr, int src_start,
struct xfs_attr_leafblock *dst_leaf, struct xfs_attr_leafblock *dst_leaf,
struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start, struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start,
int move_count, struct xfs_mount *mp); int move_count);
STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
void void
@ -711,6 +712,7 @@ xfs_attr_shortform_to_leaf(xfs_da_args_t *args)
memset((char *)&nargs, 0, sizeof(nargs)); memset((char *)&nargs, 0, sizeof(nargs));
nargs.dp = dp; nargs.dp = dp;
nargs.geo = args->geo;
nargs.firstblock = args->firstblock; nargs.firstblock = args->firstblock;
nargs.flist = args->flist; nargs.flist = args->flist;
nargs.total = args->total; nargs.total = args->total;
@ -805,18 +807,18 @@ xfs_attr3_leaf_to_shortform(
trace_xfs_attr_leaf_to_sf(args); trace_xfs_attr_leaf_to_sf(args);
tmpbuffer = kmem_alloc(XFS_LBSIZE(dp->i_mount), KM_SLEEP); tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP);
if (!tmpbuffer) if (!tmpbuffer)
return ENOMEM; return ENOMEM;
memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(dp->i_mount)); memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
leaf = (xfs_attr_leafblock_t *)tmpbuffer; leaf = (xfs_attr_leafblock_t *)tmpbuffer;
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
entry = xfs_attr3_leaf_entryp(leaf); entry = xfs_attr3_leaf_entryp(leaf);
/* XXX (dgc): buffer is about to be marked stale - why zero it? */ /* XXX (dgc): buffer is about to be marked stale - why zero it? */
memset(bp->b_addr, 0, XFS_LBSIZE(dp->i_mount)); memset(bp->b_addr, 0, args->geo->blksize);
/* /*
* Clean out the prior contents of the attribute list. * Clean out the prior contents of the attribute list.
@ -838,6 +840,7 @@ xfs_attr3_leaf_to_shortform(
* Copy the attributes * Copy the attributes
*/ */
memset((char *)&nargs, 0, sizeof(nargs)); memset((char *)&nargs, 0, sizeof(nargs));
nargs.geo = args->geo;
nargs.dp = dp; nargs.dp = dp;
nargs.firstblock = args->firstblock; nargs.firstblock = args->firstblock;
nargs.flist = args->flist; nargs.flist = args->flist;
@ -904,12 +907,12 @@ xfs_attr3_leaf_to_node(
/* copy leaf to new buffer, update identifiers */ /* copy leaf to new buffer, update identifiers */
xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF); xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF);
bp2->b_ops = bp1->b_ops; bp2->b_ops = bp1->b_ops;
memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(mp)); memcpy(bp2->b_addr, bp1->b_addr, args->geo->blksize);
if (xfs_sb_version_hascrc(&mp->m_sb)) { if (xfs_sb_version_hascrc(&mp->m_sb)) {
struct xfs_da3_blkinfo *hdr3 = bp2->b_addr; struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
hdr3->blkno = cpu_to_be64(bp2->b_bn); hdr3->blkno = cpu_to_be64(bp2->b_bn);
} }
xfs_trans_log_buf(args->trans, bp2, 0, XFS_LBSIZE(mp) - 1); xfs_trans_log_buf(args->trans, bp2, 0, args->geo->blksize - 1);
/* /*
* Set up the new root node. * Set up the new root node.
@ -930,7 +933,7 @@ xfs_attr3_leaf_to_node(
btree[0].before = cpu_to_be32(blkno); btree[0].before = cpu_to_be32(blkno);
icnodehdr.count = 1; icnodehdr.count = 1;
dp->d_ops->node_hdr_to_disk(node, &icnodehdr); dp->d_ops->node_hdr_to_disk(node, &icnodehdr);
xfs_trans_log_buf(args->trans, bp1, 0, XFS_LBSIZE(mp) - 1); xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
error = 0; error = 0;
out: out:
return error; return error;
@ -966,10 +969,10 @@ xfs_attr3_leaf_create(
bp->b_ops = &xfs_attr3_leaf_buf_ops; bp->b_ops = &xfs_attr3_leaf_buf_ops;
xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF); xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF);
leaf = bp->b_addr; leaf = bp->b_addr;
memset(leaf, 0, XFS_LBSIZE(mp)); memset(leaf, 0, args->geo->blksize);
memset(&ichdr, 0, sizeof(ichdr)); memset(&ichdr, 0, sizeof(ichdr));
ichdr.firstused = XFS_LBSIZE(mp); ichdr.firstused = args->geo->blksize;
if (xfs_sb_version_hascrc(&mp->m_sb)) { if (xfs_sb_version_hascrc(&mp->m_sb)) {
struct xfs_da3_blkinfo *hdr3 = bp->b_addr; struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
@ -988,7 +991,7 @@ xfs_attr3_leaf_create(
ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base;
xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr);
xfs_trans_log_buf(args->trans, bp, 0, XFS_LBSIZE(mp) - 1); xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1);
*bpp = bp; *bpp = bp;
return 0; return 0;
@ -1074,8 +1077,7 @@ xfs_attr3_leaf_add(
leaf = bp->b_addr; leaf = bp->b_addr;
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
ASSERT(args->index >= 0 && args->index <= ichdr.count); ASSERT(args->index >= 0 && args->index <= ichdr.count);
entsize = xfs_attr_leaf_newentsize(args->namelen, args->valuelen, entsize = xfs_attr_leaf_newentsize(args, NULL);
args->trans->t_mountp->m_sb.sb_blocksize, NULL);
/* /*
* Search through freemap for first-fit on new name length. * Search through freemap for first-fit on new name length.
@ -1174,17 +1176,14 @@ xfs_attr3_leaf_add_work(
* Allocate space for the new string (at the end of the run). * Allocate space for the new string (at the end of the run).
*/ */
mp = args->trans->t_mountp; mp = args->trans->t_mountp;
ASSERT(ichdr->freemap[mapindex].base < XFS_LBSIZE(mp)); ASSERT(ichdr->freemap[mapindex].base < args->geo->blksize);
ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0); ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0);
ASSERT(ichdr->freemap[mapindex].size >= ASSERT(ichdr->freemap[mapindex].size >=
xfs_attr_leaf_newentsize(args->namelen, args->valuelen, xfs_attr_leaf_newentsize(args, NULL));
mp->m_sb.sb_blocksize, NULL)); ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize);
ASSERT(ichdr->freemap[mapindex].size < XFS_LBSIZE(mp));
ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0); ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0);
ichdr->freemap[mapindex].size -= ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp);
xfs_attr_leaf_newentsize(args->namelen, args->valuelen,
mp->m_sb.sb_blocksize, &tmp);
entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base + entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
ichdr->freemap[mapindex].size); ichdr->freemap[mapindex].size);
@ -1269,14 +1268,13 @@ xfs_attr3_leaf_compact(
struct xfs_attr_leafblock *leaf_dst; struct xfs_attr_leafblock *leaf_dst;
struct xfs_attr3_icleaf_hdr ichdr_src; struct xfs_attr3_icleaf_hdr ichdr_src;
struct xfs_trans *trans = args->trans; struct xfs_trans *trans = args->trans;
struct xfs_mount *mp = trans->t_mountp;
char *tmpbuffer; char *tmpbuffer;
trace_xfs_attr_leaf_compact(args); trace_xfs_attr_leaf_compact(args);
tmpbuffer = kmem_alloc(XFS_LBSIZE(mp), KM_SLEEP); tmpbuffer = kmem_alloc(args->geo->blksize, KM_SLEEP);
memcpy(tmpbuffer, bp->b_addr, XFS_LBSIZE(mp)); memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
memset(bp->b_addr, 0, XFS_LBSIZE(mp)); memset(bp->b_addr, 0, args->geo->blksize);
leaf_src = (xfs_attr_leafblock_t *)tmpbuffer; leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
leaf_dst = bp->b_addr; leaf_dst = bp->b_addr;
@ -1289,7 +1287,7 @@ xfs_attr3_leaf_compact(
/* Initialise the incore headers */ /* Initialise the incore headers */
ichdr_src = *ichdr_dst; /* struct copy */ ichdr_src = *ichdr_dst; /* struct copy */
ichdr_dst->firstused = XFS_LBSIZE(mp); ichdr_dst->firstused = args->geo->blksize;
ichdr_dst->usedbytes = 0; ichdr_dst->usedbytes = 0;
ichdr_dst->count = 0; ichdr_dst->count = 0;
ichdr_dst->holes = 0; ichdr_dst->holes = 0;
@ -1304,13 +1302,13 @@ xfs_attr3_leaf_compact(
* Copy all entry's in the same (sorted) order, * Copy all entry's in the same (sorted) order,
* but allocate name/value pairs packed and in sequence. * but allocate name/value pairs packed and in sequence.
*/ */
xfs_attr3_leaf_moveents(leaf_src, &ichdr_src, 0, leaf_dst, ichdr_dst, 0, xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0,
ichdr_src.count, mp); leaf_dst, ichdr_dst, 0, ichdr_src.count);
/* /*
* this logs the entire buffer, but the caller must write the header * this logs the entire buffer, but the caller must write the header
* back to the buffer when it is finished modifying it. * back to the buffer when it is finished modifying it.
*/ */
xfs_trans_log_buf(trans, bp, 0, XFS_LBSIZE(mp) - 1); xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
kmem_free(tmpbuffer); kmem_free(tmpbuffer);
} }
@ -1461,8 +1459,8 @@ xfs_attr3_leaf_rebalance(
/* /*
* Move high entries from leaf1 to low end of leaf2. * Move high entries from leaf1 to low end of leaf2.
*/ */
xfs_attr3_leaf_moveents(leaf1, &ichdr1, ichdr1.count - count, xfs_attr3_leaf_moveents(args, leaf1, &ichdr1,
leaf2, &ichdr2, 0, count, state->mp); ichdr1.count - count, leaf2, &ichdr2, 0, count);
} else if (count > ichdr1.count) { } else if (count > ichdr1.count) {
/* /*
@ -1490,14 +1488,14 @@ xfs_attr3_leaf_rebalance(
/* /*
* Move low entries from leaf2 to high end of leaf1. * Move low entries from leaf2 to high end of leaf1.
*/ */
xfs_attr3_leaf_moveents(leaf2, &ichdr2, 0, leaf1, &ichdr1, xfs_attr3_leaf_moveents(args, leaf2, &ichdr2, 0, leaf1, &ichdr1,
ichdr1.count, count, state->mp); ichdr1.count, count);
} }
xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1); xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1);
xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2); xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2);
xfs_trans_log_buf(args->trans, blk1->bp, 0, state->blocksize-1); xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1);
xfs_trans_log_buf(args->trans, blk2->bp, 0, state->blocksize-1); xfs_trans_log_buf(args->trans, blk2->bp, 0, args->geo->blksize - 1);
/* /*
* Copy out last hashval in each block for B-tree code. * Copy out last hashval in each block for B-tree code.
@ -1592,11 +1590,9 @@ xfs_attr3_leaf_figure_balance(
max = ichdr1->count + ichdr2->count; max = ichdr1->count + ichdr2->count;
half = (max + 1) * sizeof(*entry); half = (max + 1) * sizeof(*entry);
half += ichdr1->usedbytes + ichdr2->usedbytes + half += ichdr1->usedbytes + ichdr2->usedbytes +
xfs_attr_leaf_newentsize(state->args->namelen, xfs_attr_leaf_newentsize(state->args, NULL);
state->args->valuelen,
state->blocksize, NULL);
half /= 2; half /= 2;
lastdelta = state->blocksize; lastdelta = state->args->geo->blksize;
entry = xfs_attr3_leaf_entryp(leaf1); entry = xfs_attr3_leaf_entryp(leaf1);
for (count = index = 0; count < max; entry++, index++, count++) { for (count = index = 0; count < max; entry++, index++, count++) {
@ -1606,10 +1602,7 @@ xfs_attr3_leaf_figure_balance(
*/ */
if (count == blk1->index) { if (count == blk1->index) {
tmp = totallen + sizeof(*entry) + tmp = totallen + sizeof(*entry) +
xfs_attr_leaf_newentsize( xfs_attr_leaf_newentsize(state->args, NULL);
state->args->namelen,
state->args->valuelen,
state->blocksize, NULL);
if (XFS_ATTR_ABS(half - tmp) > lastdelta) if (XFS_ATTR_ABS(half - tmp) > lastdelta)
break; break;
lastdelta = XFS_ATTR_ABS(half - tmp); lastdelta = XFS_ATTR_ABS(half - tmp);
@ -1645,10 +1638,7 @@ xfs_attr3_leaf_figure_balance(
totallen -= count * sizeof(*entry); totallen -= count * sizeof(*entry);
if (foundit) { if (foundit) {
totallen -= sizeof(*entry) + totallen -= sizeof(*entry) +
xfs_attr_leaf_newentsize( xfs_attr_leaf_newentsize(state->args, NULL);
state->args->namelen,
state->args->valuelen,
state->blocksize, NULL);
} }
*countarg = count; *countarg = count;
@ -1700,7 +1690,7 @@ xfs_attr3_leaf_toosmall(
bytes = xfs_attr3_leaf_hdr_size(leaf) + bytes = xfs_attr3_leaf_hdr_size(leaf) +
ichdr.count * sizeof(xfs_attr_leaf_entry_t) + ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
ichdr.usedbytes; ichdr.usedbytes;
if (bytes > (state->blocksize >> 1)) { if (bytes > (state->args->geo->blksize >> 1)) {
*action = 0; /* blk over 50%, don't try to join */ *action = 0; /* blk over 50%, don't try to join */
return(0); return(0);
} }
@ -1754,7 +1744,8 @@ xfs_attr3_leaf_toosmall(
xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr); xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr);
bytes = state->blocksize - (state->blocksize >> 2) - bytes = state->args->geo->blksize -
(state->args->geo->blksize >> 2) -
ichdr.usedbytes - ichdr2.usedbytes - ichdr.usedbytes - ichdr2.usedbytes -
((ichdr.count + ichdr2.count) * ((ichdr.count + ichdr2.count) *
sizeof(xfs_attr_leaf_entry_t)) - sizeof(xfs_attr_leaf_entry_t)) -
@ -1805,7 +1796,6 @@ xfs_attr3_leaf_remove(
struct xfs_attr_leafblock *leaf; struct xfs_attr_leafblock *leaf;
struct xfs_attr3_icleaf_hdr ichdr; struct xfs_attr3_icleaf_hdr ichdr;
struct xfs_attr_leaf_entry *entry; struct xfs_attr_leaf_entry *entry;
struct xfs_mount *mp = args->trans->t_mountp;
int before; int before;
int after; int after;
int smallest; int smallest;
@ -1819,7 +1809,7 @@ xfs_attr3_leaf_remove(
leaf = bp->b_addr; leaf = bp->b_addr;
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
ASSERT(ichdr.count > 0 && ichdr.count < XFS_LBSIZE(mp) / 8); ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8);
ASSERT(args->index >= 0 && args->index < ichdr.count); ASSERT(args->index >= 0 && args->index < ichdr.count);
ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) + ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
xfs_attr3_leaf_hdr_size(leaf)); xfs_attr3_leaf_hdr_size(leaf));
@ -1827,7 +1817,7 @@ xfs_attr3_leaf_remove(
entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
/* /*
* Scan through free region table: * Scan through free region table:
@ -1842,8 +1832,8 @@ xfs_attr3_leaf_remove(
smallest = XFS_ATTR_LEAF_MAPSIZE - 1; smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
entsize = xfs_attr_leaf_entsize(leaf, args->index); entsize = xfs_attr_leaf_entsize(leaf, args->index);
for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
ASSERT(ichdr.freemap[i].base < XFS_LBSIZE(mp)); ASSERT(ichdr.freemap[i].base < args->geo->blksize);
ASSERT(ichdr.freemap[i].size < XFS_LBSIZE(mp)); ASSERT(ichdr.freemap[i].size < args->geo->blksize);
if (ichdr.freemap[i].base == tablesize) { if (ichdr.freemap[i].base == tablesize) {
ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t); ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t);
ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t); ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t);
@ -1920,11 +1910,11 @@ xfs_attr3_leaf_remove(
* removing the name. * removing the name.
*/ */
if (smallest) { if (smallest) {
tmp = XFS_LBSIZE(mp); tmp = args->geo->blksize;
entry = xfs_attr3_leaf_entryp(leaf); entry = xfs_attr3_leaf_entryp(leaf);
for (i = ichdr.count - 1; i >= 0; entry++, i--) { for (i = ichdr.count - 1; i >= 0; entry++, i--) {
ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused); ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
ASSERT(be16_to_cpu(entry->nameidx) < XFS_LBSIZE(mp)); ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
if (be16_to_cpu(entry->nameidx) < tmp) if (be16_to_cpu(entry->nameidx) < tmp)
tmp = be16_to_cpu(entry->nameidx); tmp = be16_to_cpu(entry->nameidx);
@ -1947,7 +1937,7 @@ xfs_attr3_leaf_remove(
tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) + tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
ichdr.count * sizeof(xfs_attr_leaf_entry_t); ichdr.count * sizeof(xfs_attr_leaf_entry_t);
return tmp < mp->m_attr_magicpct; /* leaf is < 37% full */ return tmp < args->geo->magicpct; /* leaf is < 37% full */
} }
/* /*
@ -1964,7 +1954,6 @@ xfs_attr3_leaf_unbalance(
struct xfs_attr3_icleaf_hdr drophdr; struct xfs_attr3_icleaf_hdr drophdr;
struct xfs_attr3_icleaf_hdr savehdr; struct xfs_attr3_icleaf_hdr savehdr;
struct xfs_attr_leaf_entry *entry; struct xfs_attr_leaf_entry *entry;
struct xfs_mount *mp = state->mp;
trace_xfs_attr_leaf_unbalance(state->args); trace_xfs_attr_leaf_unbalance(state->args);
@ -1991,13 +1980,15 @@ xfs_attr3_leaf_unbalance(
*/ */
if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
drop_blk->bp, &drophdr)) { drop_blk->bp, &drophdr)) {
xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, xfs_attr3_leaf_moveents(state->args,
drop_leaf, &drophdr, 0,
save_leaf, &savehdr, 0, save_leaf, &savehdr, 0,
drophdr.count, mp); drophdr.count);
} else { } else {
xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, xfs_attr3_leaf_moveents(state->args,
drop_leaf, &drophdr, 0,
save_leaf, &savehdr, save_leaf, &savehdr,
savehdr.count, drophdr.count, mp); savehdr.count, drophdr.count);
} }
} else { } else {
/* /*
@ -2007,7 +1998,7 @@ xfs_attr3_leaf_unbalance(
struct xfs_attr_leafblock *tmp_leaf; struct xfs_attr_leafblock *tmp_leaf;
struct xfs_attr3_icleaf_hdr tmphdr; struct xfs_attr3_icleaf_hdr tmphdr;
tmp_leaf = kmem_zalloc(state->blocksize, KM_SLEEP); tmp_leaf = kmem_zalloc(state->args->geo->blksize, KM_SLEEP);
/* /*
* Copy the header into the temp leaf so that all the stuff * Copy the header into the temp leaf so that all the stuff
@ -2020,35 +2011,39 @@ xfs_attr3_leaf_unbalance(
tmphdr.magic = savehdr.magic; tmphdr.magic = savehdr.magic;
tmphdr.forw = savehdr.forw; tmphdr.forw = savehdr.forw;
tmphdr.back = savehdr.back; tmphdr.back = savehdr.back;
tmphdr.firstused = state->blocksize; tmphdr.firstused = state->args->geo->blksize;
/* write the header to the temp buffer to initialise it */ /* write the header to the temp buffer to initialise it */
xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr);
if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
drop_blk->bp, &drophdr)) { drop_blk->bp, &drophdr)) {
xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, xfs_attr3_leaf_moveents(state->args,
drop_leaf, &drophdr, 0,
tmp_leaf, &tmphdr, 0, tmp_leaf, &tmphdr, 0,
drophdr.count, mp); drophdr.count);
xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, xfs_attr3_leaf_moveents(state->args,
save_leaf, &savehdr, 0,
tmp_leaf, &tmphdr, tmphdr.count, tmp_leaf, &tmphdr, tmphdr.count,
savehdr.count, mp); savehdr.count);
} else { } else {
xfs_attr3_leaf_moveents(save_leaf, &savehdr, 0, xfs_attr3_leaf_moveents(state->args,
save_leaf, &savehdr, 0,
tmp_leaf, &tmphdr, 0, tmp_leaf, &tmphdr, 0,
savehdr.count, mp); savehdr.count);
xfs_attr3_leaf_moveents(drop_leaf, &drophdr, 0, xfs_attr3_leaf_moveents(state->args,
drop_leaf, &drophdr, 0,
tmp_leaf, &tmphdr, tmphdr.count, tmp_leaf, &tmphdr, tmphdr.count,
drophdr.count, mp); drophdr.count);
} }
memcpy(save_leaf, tmp_leaf, state->blocksize); memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
savehdr = tmphdr; /* struct copy */ savehdr = tmphdr; /* struct copy */
kmem_free(tmp_leaf); kmem_free(tmp_leaf);
} }
xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr); xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr);
xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, xfs_trans_log_buf(state->args->trans, save_blk->bp, 0,
state->blocksize - 1); state->args->geo->blksize - 1);
/* /*
* Copy out last hashval in each block for B-tree code. * Copy out last hashval in each block for B-tree code.
@ -2094,7 +2089,7 @@ xfs_attr3_leaf_lookup_int(
leaf = bp->b_addr; leaf = bp->b_addr;
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
entries = xfs_attr3_leaf_entryp(leaf); entries = xfs_attr3_leaf_entryp(leaf);
ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8); ASSERT(ichdr.count < args->geo->blksize / 8);
/* /*
* Binary search. (note: small blocks will skip this loop) * Binary search. (note: small blocks will skip this loop)
@ -2198,7 +2193,7 @@ xfs_attr3_leaf_getvalue(
leaf = bp->b_addr; leaf = bp->b_addr;
xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf);
ASSERT(ichdr.count < XFS_LBSIZE(args->dp->i_mount) / 8); ASSERT(ichdr.count < args->geo->blksize / 8);
ASSERT(args->index < ichdr.count); ASSERT(args->index < ichdr.count);
entry = &xfs_attr3_leaf_entryp(leaf)[args->index]; entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
@ -2249,14 +2244,14 @@ xfs_attr3_leaf_getvalue(
/*ARGSUSED*/ /*ARGSUSED*/
STATIC void STATIC void
xfs_attr3_leaf_moveents( xfs_attr3_leaf_moveents(
struct xfs_da_args *args,
struct xfs_attr_leafblock *leaf_s, struct xfs_attr_leafblock *leaf_s,
struct xfs_attr3_icleaf_hdr *ichdr_s, struct xfs_attr3_icleaf_hdr *ichdr_s,
int start_s, int start_s,
struct xfs_attr_leafblock *leaf_d, struct xfs_attr_leafblock *leaf_d,
struct xfs_attr3_icleaf_hdr *ichdr_d, struct xfs_attr3_icleaf_hdr *ichdr_d,
int start_d, int start_d,
int count, int count)
struct xfs_mount *mp)
{ {
struct xfs_attr_leaf_entry *entry_s; struct xfs_attr_leaf_entry *entry_s;
struct xfs_attr_leaf_entry *entry_d; struct xfs_attr_leaf_entry *entry_d;
@ -2276,10 +2271,10 @@ xfs_attr3_leaf_moveents(
ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC || ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC ||
ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC); ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
ASSERT(ichdr_s->magic == ichdr_d->magic); ASSERT(ichdr_s->magic == ichdr_d->magic);
ASSERT(ichdr_s->count > 0 && ichdr_s->count < XFS_LBSIZE(mp) / 8); ASSERT(ichdr_s->count > 0 && ichdr_s->count < args->geo->blksize / 8);
ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s)) ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
+ xfs_attr3_leaf_hdr_size(leaf_s)); + xfs_attr3_leaf_hdr_size(leaf_s));
ASSERT(ichdr_d->count < XFS_LBSIZE(mp) / 8); ASSERT(ichdr_d->count < args->geo->blksize / 8);
ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d)) ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
+ xfs_attr3_leaf_hdr_size(leaf_d)); + xfs_attr3_leaf_hdr_size(leaf_d));
@ -2331,11 +2326,11 @@ xfs_attr3_leaf_moveents(
entry_d->nameidx = cpu_to_be16(ichdr_d->firstused); entry_d->nameidx = cpu_to_be16(ichdr_d->firstused);
entry_d->flags = entry_s->flags; entry_d->flags = entry_s->flags;
ASSERT(be16_to_cpu(entry_d->nameidx) + tmp ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
<= XFS_LBSIZE(mp)); <= args->geo->blksize);
memmove(xfs_attr3_leaf_name(leaf_d, desti), memmove(xfs_attr3_leaf_name(leaf_d, desti),
xfs_attr3_leaf_name(leaf_s, start_s + i), tmp); xfs_attr3_leaf_name(leaf_s, start_s + i), tmp);
ASSERT(be16_to_cpu(entry_s->nameidx) + tmp ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
<= XFS_LBSIZE(mp)); <= args->geo->blksize);
memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp); memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
ichdr_s->usedbytes -= tmp; ichdr_s->usedbytes -= tmp;
ichdr_d->usedbytes += tmp; ichdr_d->usedbytes += tmp;
@ -2356,7 +2351,7 @@ xfs_attr3_leaf_moveents(
tmp = count * sizeof(xfs_attr_leaf_entry_t); tmp = count * sizeof(xfs_attr_leaf_entry_t);
entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s]; entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
ASSERT(((char *)entry_s + tmp) <= ASSERT(((char *)entry_s + tmp) <=
((char *)leaf_s + XFS_LBSIZE(mp))); ((char *)leaf_s + args->geo->blksize));
memset(entry_s, 0, tmp); memset(entry_s, 0, tmp);
} else { } else {
/* /*
@ -2371,7 +2366,7 @@ xfs_attr3_leaf_moveents(
tmp = count * sizeof(xfs_attr_leaf_entry_t); tmp = count * sizeof(xfs_attr_leaf_entry_t);
entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count]; entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count];
ASSERT(((char *)entry_s + tmp) <= ASSERT(((char *)entry_s + tmp) <=
((char *)leaf_s + XFS_LBSIZE(mp))); ((char *)leaf_s + args->geo->blksize));
memset(entry_s, 0, tmp); memset(entry_s, 0, tmp);
} }
@ -2439,22 +2434,21 @@ xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
* a "local" or a "remote" attribute. * a "local" or a "remote" attribute.
*/ */
int int
xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize, int *local) xfs_attr_leaf_newentsize(
struct xfs_da_args *args,
int *local)
{ {
int size; int size;
size = xfs_attr_leaf_entsize_local(namelen, valuelen); size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen);
if (size < xfs_attr_leaf_entsize_local_max(blocksize)) { if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) {
if (local) { if (local)
*local = 1; *local = 1;
} return size;
} else {
size = xfs_attr_leaf_entsize_remote(namelen);
if (local) {
*local = 0;
}
} }
return size; if (local)
*local = 0;
return xfs_attr_leaf_entsize_remote(args->namelen);
} }

View File

@ -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);

View File

@ -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;

View File

@ -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(
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(
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(
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(
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(
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(
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(
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(
* 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;

View File

@ -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);

View File

@ -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(
* 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(
#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(
/* /*
* 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(
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(
* 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(
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(
* 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(
* 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(
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(
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(
/* /*
* 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(
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(
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(
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

View File

@ -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 {
* 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 {
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 */

View File

@ -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)
* 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)
} }
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(
* 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)
* 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)
* 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

View File

@ -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 {
__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)
#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)
*/ */
#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 {
#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)
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)
*/ */
#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 {
__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)
* 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,

View File

@ -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(
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),
(uint)sizeof(xfs_da_node_entry_t); KM_SLEEP | KM_MAYFAIL);
mp->m_dir_node_ents = (mp->m_dirblksize - nodehdr_size) / mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
(uint)sizeof(xfs_da_node_entry_t); 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);
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);
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(
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(
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(
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(
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(
* 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(
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(
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(
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(
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(
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(
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(
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(
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(
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(
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(
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(
* 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(
*/ */
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(
*/ */
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(
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(
/* /*
* 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(
*/ */
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);

View File

@ -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 {
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 *
* 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);
/* /*
* 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);

View File

@ -136,7 +136,7 @@ xfs_dir3_block_read(
struct xfs_mount *mp = dp->i_mount; struct xfs_mount *mp = dp->i_mount;
int err; int err;
err = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp, err = xfs_da_read_buf(tp, dp, mp->m_dir_geo->datablk, -1, bpp,
XFS_DATA_FORK, &xfs_dir3_block_buf_ops); XFS_DATA_FORK, &xfs_dir3_block_buf_ops);
if (!err && tp) if (!err && tp)
xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF); xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_BLOCK_BUF);
@ -281,8 +281,7 @@ out:
*/ */
static void static void
xfs_dir2_block_compact( xfs_dir2_block_compact(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_inode *dp,
struct xfs_buf *bp, struct xfs_buf *bp,
struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_hdr *hdr,
struct xfs_dir2_block_tail *btp, struct xfs_dir2_block_tail *btp,
@ -315,7 +314,7 @@ xfs_dir2_block_compact(
*lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1); *lfloglow = toidx + 1 - (be32_to_cpu(btp->stale) - 1);
*lfloghigh -= be32_to_cpu(btp->stale) - 1; *lfloghigh -= be32_to_cpu(btp->stale) - 1;
be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1));
xfs_dir2_data_make_free(tp, dp, bp, xfs_dir2_data_make_free(args, bp,
(xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
(xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)),
needlog, &needscan); needlog, &needscan);
@ -325,7 +324,7 @@ xfs_dir2_block_compact(
* This needs to happen before the next call to use_free. * This needs to happen before the next call to use_free.
*/ */
if (needscan) if (needscan)
xfs_dir2_data_freescan(dp, hdr, needlog); xfs_dir2_data_freescan(args->dp, hdr, needlog);
} }
/* /*
@ -377,7 +376,7 @@ xfs_dir2_block_addname(
* Set up pointers to parts of the block. * Set up pointers to parts of the block.
*/ */
hdr = bp->b_addr; hdr = bp->b_addr;
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
/* /*
@ -420,7 +419,7 @@ xfs_dir2_block_addname(
* If need to compact the leaf entries, do it now. * If need to compact the leaf entries, do it now.
*/ */
if (compact) { if (compact) {
xfs_dir2_block_compact(tp, dp, bp, hdr, btp, blp, &needlog, xfs_dir2_block_compact(args, bp, hdr, btp, blp, &needlog,
&lfloghigh, &lfloglow); &lfloghigh, &lfloglow);
/* recalculate blp post-compaction */ /* recalculate blp post-compaction */
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
@ -455,7 +454,7 @@ xfs_dir2_block_addname(
/* /*
* Mark the space needed for the new leaf entry, now in use. * Mark the space needed for the new leaf entry, now in use.
*/ */
xfs_dir2_data_use_free(tp, dp, bp, enddup, xfs_dir2_data_use_free(args, bp, enddup,
(xfs_dir2_data_aoff_t) (xfs_dir2_data_aoff_t)
((char *)enddup - (char *)hdr + be16_to_cpu(enddup->length) - ((char *)enddup - (char *)hdr + be16_to_cpu(enddup->length) -
sizeof(*blp)), sizeof(*blp)),
@ -542,7 +541,7 @@ xfs_dir2_block_addname(
/* /*
* Mark space for the data entry used. * Mark space for the data entry used.
*/ */
xfs_dir2_data_use_free(tp, dp, bp, dup, xfs_dir2_data_use_free(args, bp, dup,
(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
(xfs_dir2_data_aoff_t)len, &needlog, &needscan); (xfs_dir2_data_aoff_t)len, &needlog, &needscan);
/* /*
@ -560,9 +559,9 @@ xfs_dir2_block_addname(
if (needscan) if (needscan)
xfs_dir2_data_freescan(dp, hdr, &needlog); xfs_dir2_data_freescan(dp, hdr, &needlog);
if (needlog) if (needlog)
xfs_dir2_data_log_header(tp, dp, bp); xfs_dir2_data_log_header(args, bp);
xfs_dir2_block_log_tail(tp, bp); xfs_dir2_block_log_tail(tp, bp);
xfs_dir2_data_log_entry(tp, dp, bp, dep); xfs_dir2_data_log_entry(args, bp, dep);
xfs_dir3_data_check(dp, bp); xfs_dir3_data_check(dp, bp);
return 0; return 0;
} }
@ -581,7 +580,7 @@ xfs_dir2_block_log_leaf(
xfs_dir2_leaf_entry_t *blp; xfs_dir2_leaf_entry_t *blp;
xfs_dir2_block_tail_t *btp; xfs_dir2_block_tail_t *btp;
btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); btp = xfs_dir2_block_tail_p(tp->t_mountp->m_dir_geo, hdr);
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
xfs_trans_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr), xfs_trans_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr),
(uint)((char *)&blp[last + 1] - (char *)hdr - 1)); (uint)((char *)&blp[last + 1] - (char *)hdr - 1));
@ -598,7 +597,7 @@ xfs_dir2_block_log_tail(
xfs_dir2_data_hdr_t *hdr = bp->b_addr; xfs_dir2_data_hdr_t *hdr = bp->b_addr;
xfs_dir2_block_tail_t *btp; xfs_dir2_block_tail_t *btp;
btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); btp = xfs_dir2_block_tail_p(tp->t_mountp->m_dir_geo, hdr);
xfs_trans_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr), xfs_trans_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr),
(uint)((char *)(btp + 1) - (char *)hdr - 1)); (uint)((char *)(btp + 1) - (char *)hdr - 1));
} }
@ -633,13 +632,14 @@ xfs_dir2_block_lookup(
mp = dp->i_mount; mp = dp->i_mount;
hdr = bp->b_addr; hdr = bp->b_addr;
xfs_dir3_data_check(dp, bp); xfs_dir3_data_check(dp, bp);
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
/* /*
* Get the offset from the leaf entry, to point to the data. * Get the offset from the leaf entry, to point to the data.
*/ */
dep = (xfs_dir2_data_entry_t *)((char *)hdr + dep = (xfs_dir2_data_entry_t *)((char *)hdr +
xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); xfs_dir2_dataptr_to_off(args->geo,
be32_to_cpu(blp[ent].address)));
/* /*
* Fill in inode number, CI name if appropriate, release the block. * Fill in inode number, CI name if appropriate, release the block.
*/ */
@ -685,7 +685,7 @@ xfs_dir2_block_lookup_int(
hdr = bp->b_addr; hdr = bp->b_addr;
xfs_dir3_data_check(dp, bp); xfs_dir3_data_check(dp, bp);
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
/* /*
* Loop doing a binary search for our hash value. * Loop doing a binary search for our hash value.
@ -723,7 +723,7 @@ xfs_dir2_block_lookup_int(
* Get pointer to the entry from the leaf. * Get pointer to the entry from the leaf.
*/ */
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)
((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); ((char *)hdr + xfs_dir2_dataptr_to_off(args->geo, addr));
/* /*
* Compare name and if it's an exact match, return the index * Compare name and if it's an exact match, return the index
* and buffer. If it's the first case-insensitive match, store * and buffer. If it's the first case-insensitive match, store
@ -790,18 +790,19 @@ xfs_dir2_block_removename(
tp = args->trans; tp = args->trans;
mp = dp->i_mount; mp = dp->i_mount;
hdr = bp->b_addr; hdr = bp->b_addr;
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
/* /*
* Point to the data entry using the leaf entry. * Point to the data entry using the leaf entry.
*/ */
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)((char *)hdr +
((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); xfs_dir2_dataptr_to_off(args->geo,
be32_to_cpu(blp[ent].address)));
/* /*
* Mark the data entry's space free. * Mark the data entry's space free.
*/ */
needlog = needscan = 0; needlog = needscan = 0;
xfs_dir2_data_make_free(tp, dp, bp, xfs_dir2_data_make_free(args, bp,
(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
/* /*
@ -820,7 +821,7 @@ xfs_dir2_block_removename(
if (needscan) if (needscan)
xfs_dir2_data_freescan(dp, hdr, &needlog); xfs_dir2_data_freescan(dp, hdr, &needlog);
if (needlog) if (needlog)
xfs_dir2_data_log_header(tp, dp, bp); xfs_dir2_data_log_header(args, bp);
xfs_dir3_data_check(dp, bp); xfs_dir3_data_check(dp, bp);
/* /*
* See if the size as a shortform is good enough. * See if the size as a shortform is good enough.
@ -865,20 +866,21 @@ xfs_dir2_block_replace(
dp = args->dp; dp = args->dp;
mp = dp->i_mount; mp = dp->i_mount;
hdr = bp->b_addr; hdr = bp->b_addr;
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
/* /*
* Point to the data entry we need to change. * Point to the data entry we need to change.
*/ */
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)((char *)hdr +
((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); xfs_dir2_dataptr_to_off(args->geo,
be32_to_cpu(blp[ent].address)));
ASSERT(be64_to_cpu(dep->inumber) != args->inumber); ASSERT(be64_to_cpu(dep->inumber) != args->inumber);
/* /*
* Change the inode number to the new value. * Change the inode number to the new value.
*/ */
dep->inumber = cpu_to_be64(args->inumber); dep->inumber = cpu_to_be64(args->inumber);
dp->d_ops->data_put_ftype(dep, args->filetype); dp->d_ops->data_put_ftype(dep, args->filetype);
xfs_dir2_data_log_entry(args->trans, dp, bp, dep); xfs_dir2_data_log_entry(args, bp, dep);
xfs_dir3_data_check(dp, bp); xfs_dir3_data_check(dp, bp);
return 0; return 0;
} }
@ -938,7 +940,7 @@ xfs_dir2_leaf_to_block(
leaf = lbp->b_addr; leaf = lbp->b_addr;
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
ents = dp->d_ops->leaf_ents_p(leaf); ents = dp->d_ops->leaf_ents_p(leaf);
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC || ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
leafhdr.magic == XFS_DIR3_LEAF1_MAGIC); leafhdr.magic == XFS_DIR3_LEAF1_MAGIC);
@ -948,13 +950,13 @@ xfs_dir2_leaf_to_block(
* been left behind during no-space-reservation operations. * been left behind during no-space-reservation operations.
* These will show up in the leaf bests table. * These will show up in the leaf bests table.
*/ */
while (dp->i_d.di_size > mp->m_dirblksize) { while (dp->i_d.di_size > args->geo->blksize) {
int hdrsz; int hdrsz;
hdrsz = dp->d_ops->data_entry_offset; hdrsz = dp->d_ops->data_entry_offset;
bestsp = xfs_dir2_leaf_bests_p(ltp); bestsp = xfs_dir2_leaf_bests_p(ltp);
if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) ==
mp->m_dirblksize - hdrsz) { args->geo->blksize - hdrsz) {
if ((error = if ((error =
xfs_dir2_leaf_trim_data(args, lbp, xfs_dir2_leaf_trim_data(args, lbp,
(xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1))))
@ -966,7 +968,7 @@ xfs_dir2_leaf_to_block(
* Read the data block if we don't already have it, give up if it fails. * Read the data block if we don't already have it, give up if it fails.
*/ */
if (!dbp) { if (!dbp) {
error = xfs_dir3_data_read(tp, dp, mp->m_dirdatablk, -1, &dbp); error = xfs_dir3_data_read(tp, dp, args->geo->datablk, -1, &dbp);
if (error) if (error)
return error; return error;
} }
@ -982,7 +984,7 @@ xfs_dir2_leaf_to_block(
/* /*
* Look at the last data entry. * Look at the last data entry.
*/ */
tagp = (__be16 *)((char *)hdr + mp->m_dirblksize) - 1; tagp = (__be16 *)((char *)hdr + args->geo->blksize) - 1;
dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
/* /*
* If it's not free or is too short we can't do it. * If it's not free or is too short we can't do it.
@ -1001,12 +1003,12 @@ xfs_dir2_leaf_to_block(
/* /*
* Use up the space at the end of the block (blp/btp). * Use up the space at the end of the block (blp/btp).
*/ */
xfs_dir2_data_use_free(tp, dp, dbp, dup, mp->m_dirblksize - size, size, xfs_dir2_data_use_free(args, dbp, dup, args->geo->blksize - size, size,
&needlog, &needscan); &needlog, &needscan);
/* /*
* Initialize the block tail. * Initialize the block tail.
*/ */
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
btp->count = cpu_to_be32(leafhdr.count - leafhdr.stale); btp->count = cpu_to_be32(leafhdr.count - leafhdr.stale);
btp->stale = 0; btp->stale = 0;
xfs_dir2_block_log_tail(tp, dbp); xfs_dir2_block_log_tail(tp, dbp);
@ -1027,11 +1029,11 @@ xfs_dir2_leaf_to_block(
if (needscan) if (needscan)
xfs_dir2_data_freescan(dp, hdr, &needlog); xfs_dir2_data_freescan(dp, hdr, &needlog);
if (needlog) if (needlog)
xfs_dir2_data_log_header(tp, dp, dbp); xfs_dir2_data_log_header(args, dbp);
/* /*
* Pitch the old leaf block. * Pitch the old leaf block.
*/ */
error = xfs_da_shrink_inode(args, mp->m_dirleafblk, lbp); error = xfs_da_shrink_inode(args, args->geo->leafblk, lbp);
if (error) if (error)
return error; return error;
@ -1140,13 +1142,13 @@ xfs_dir2_sf_to_block(
*/ */
dup = dp->d_ops->data_unused_p(hdr); dup = dp->d_ops->data_unused_p(hdr);
needlog = needscan = 0; needlog = needscan = 0;
xfs_dir2_data_use_free(tp, dp, bp, dup, mp->m_dirblksize - i, i, &needlog, xfs_dir2_data_use_free(args, bp, dup, args->geo->blksize - i,
&needscan); i, &needlog, &needscan);
ASSERT(needscan == 0); ASSERT(needscan == 0);
/* /*
* Fill in the tail. * Fill in the tail.
*/ */
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
btp->count = cpu_to_be32(sfp->count + 2); /* ., .. */ btp->count = cpu_to_be32(sfp->count + 2); /* ., .. */
btp->stale = 0; btp->stale = 0;
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
@ -1154,7 +1156,7 @@ xfs_dir2_sf_to_block(
/* /*
* Remove the freespace, we'll manage it. * Remove the freespace, we'll manage it.
*/ */
xfs_dir2_data_use_free(tp, dp, bp, dup, xfs_dir2_data_use_free(args, bp, dup,
(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr),
be16_to_cpu(dup->length), &needlog, &needscan); be16_to_cpu(dup->length), &needlog, &needscan);
/* /*
@ -1167,7 +1169,7 @@ xfs_dir2_sf_to_block(
dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
tagp = dp->d_ops->data_entry_tag_p(dep); tagp = dp->d_ops->data_entry_tag_p(dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr); *tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, dp, bp, dep); xfs_dir2_data_log_entry(args, bp, dep);
blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot);
blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
(char *)dep - (char *)hdr)); (char *)dep - (char *)hdr));
@ -1181,7 +1183,7 @@ xfs_dir2_sf_to_block(
dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR); dp->d_ops->data_put_ftype(dep, XFS_DIR3_FT_DIR);
tagp = dp->d_ops->data_entry_tag_p(dep); tagp = dp->d_ops->data_entry_tag_p(dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr); *tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, dp, bp, dep); xfs_dir2_data_log_entry(args, bp, dep);
blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr( blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(
(char *)dep - (char *)hdr)); (char *)dep - (char *)hdr));
@ -1215,7 +1217,7 @@ xfs_dir2_sf_to_block(
dup->length = cpu_to_be16(newoffset - offset); dup->length = cpu_to_be16(newoffset - offset);
*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16(
((char *)dup - (char *)hdr)); ((char *)dup - (char *)hdr));
xfs_dir2_data_log_unused(tp, bp, dup); xfs_dir2_data_log_unused(args, bp, dup);
xfs_dir2_data_freeinsert(hdr, xfs_dir2_data_freeinsert(hdr,
dp->d_ops->data_bestfree_p(hdr), dp->d_ops->data_bestfree_p(hdr),
dup, &dummy); dup, &dummy);
@ -1232,7 +1234,7 @@ xfs_dir2_sf_to_block(
memcpy(dep->name, sfep->name, dep->namelen); memcpy(dep->name, sfep->name, dep->namelen);
tagp = dp->d_ops->data_entry_tag_p(dep); tagp = dp->d_ops->data_entry_tag_p(dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr); *tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, dp, bp, dep); xfs_dir2_data_log_entry(args, bp, dep);
name.name = sfep->name; name.name = sfep->name;
name.len = sfep->namelen; name.len = sfep->namelen;
blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops->

View File

@ -63,8 +63,10 @@ __xfs_dir3_data_check(
int stale; /* count of stale leaves */ int stale; /* count of stale leaves */
struct xfs_name name; struct xfs_name name;
const struct xfs_dir_ops *ops; const struct xfs_dir_ops *ops;
struct xfs_da_geometry *geo;
mp = bp->b_target->bt_mount; mp = bp->b_target->bt_mount;
geo = mp->m_dir_geo;
/* /*
* We can be passed a null dp here from a verifier, so we need to go the * We can be passed a null dp here from a verifier, so we need to go the
@ -78,7 +80,7 @@ __xfs_dir3_data_check(
switch (hdr->magic) { switch (hdr->magic) {
case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(geo, hdr);
lep = xfs_dir2_block_leaf_p(btp); lep = xfs_dir2_block_leaf_p(btp);
endp = (char *)lep; endp = (char *)lep;
@ -94,7 +96,7 @@ __xfs_dir3_data_check(
break; break;
case cpu_to_be32(XFS_DIR3_DATA_MAGIC): case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
case cpu_to_be32(XFS_DIR2_DATA_MAGIC): case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
endp = (char *)hdr + mp->m_dirblksize; endp = (char *)hdr + geo->blksize;
break; break;
default: default:
XFS_ERROR_REPORT("Bad Magic", XFS_ERRLEVEL_LOW, mp); XFS_ERROR_REPORT("Bad Magic", XFS_ERRLEVEL_LOW, mp);
@ -172,9 +174,9 @@ __xfs_dir3_data_check(
lastfree = 0; lastfree = 0;
if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, addr = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
(xfs_dir2_data_aoff_t) (xfs_dir2_data_aoff_t)
((char *)dep - (char *)hdr)); ((char *)dep - (char *)hdr));
name.name = dep->name; name.name = dep->name;
name.len = dep->namelen; name.len = dep->namelen;
hash = mp->m_dirnameops->hashname(&name); hash = mp->m_dirnameops->hashname(&name);
@ -509,6 +511,7 @@ xfs_dir2_data_freescan(
struct xfs_dir2_data_free *bf; struct xfs_dir2_data_free *bf;
char *endp; /* end of block's data */ char *endp; /* end of block's data */
char *p; /* current entry pointer */ char *p; /* current entry pointer */
struct xfs_da_geometry *geo = dp->i_mount->m_dir_geo;
ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
@ -527,10 +530,10 @@ xfs_dir2_data_freescan(
p = (char *)dp->d_ops->data_entry_p(hdr); p = (char *)dp->d_ops->data_entry_p(hdr);
if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
btp = xfs_dir2_block_tail_p(dp->i_mount, hdr); btp = xfs_dir2_block_tail_p(geo, hdr);
endp = (char *)xfs_dir2_block_leaf_p(btp); endp = (char *)xfs_dir2_block_leaf_p(btp);
} else } else
endp = (char *)hdr + dp->i_mount->m_dirblksize; endp = (char *)hdr + geo->blksize;
/* /*
* Loop over the block's entries. * Loop over the block's entries.
*/ */
@ -584,8 +587,8 @@ xfs_dir3_data_init(
/* /*
* Get the buffer set up for the block. * Get the buffer set up for the block.
*/ */
error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, blkno), -1, &bp, error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno),
XFS_DATA_FORK); -1, &bp, XFS_DATA_FORK);
if (error) if (error)
return error; return error;
bp->b_ops = &xfs_dir3_data_buf_ops; bp->b_ops = &xfs_dir3_data_buf_ops;
@ -620,15 +623,15 @@ xfs_dir3_data_init(
dup = dp->d_ops->data_unused_p(hdr); dup = dp->d_ops->data_unused_p(hdr);
dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
t = mp->m_dirblksize - (uint)dp->d_ops->data_entry_offset; t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset;
bf[0].length = cpu_to_be16(t); bf[0].length = cpu_to_be16(t);
dup->length = cpu_to_be16(t); dup->length = cpu_to_be16(t);
*xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
/* /*
* Log it and return it. * Log it and return it.
*/ */
xfs_dir2_data_log_header(tp, dp, bp); xfs_dir2_data_log_header(args, bp);
xfs_dir2_data_log_unused(tp, bp, dup); xfs_dir2_data_log_unused(args, bp, dup);
*bpp = bp; *bpp = bp;
return 0; return 0;
} }
@ -638,8 +641,7 @@ xfs_dir3_data_init(
*/ */
void void
xfs_dir2_data_log_entry( xfs_dir2_data_log_entry(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_inode *dp,
struct xfs_buf *bp, struct xfs_buf *bp,
xfs_dir2_data_entry_t *dep) /* data entry pointer */ xfs_dir2_data_entry_t *dep) /* data entry pointer */
{ {
@ -650,8 +652,8 @@ xfs_dir2_data_log_entry(
hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr), xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
(uint)((char *)(dp->d_ops->data_entry_tag_p(dep) + 1) - (uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) -
(char *)hdr - 1)); (char *)hdr - 1));
} }
@ -660,8 +662,7 @@ xfs_dir2_data_log_entry(
*/ */
void void
xfs_dir2_data_log_header( xfs_dir2_data_log_header(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_inode *dp,
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
#ifdef DEBUG #ifdef DEBUG
@ -673,7 +674,8 @@ xfs_dir2_data_log_header(
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
#endif #endif
xfs_trans_log_buf(tp, bp, 0, dp->d_ops->data_entry_offset - 1); xfs_trans_log_buf(args->trans, bp, 0,
args->dp->d_ops->data_entry_offset - 1);
} }
/* /*
@ -681,7 +683,7 @@ xfs_dir2_data_log_header(
*/ */
void void
xfs_dir2_data_log_unused( xfs_dir2_data_log_unused(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_buf *bp, struct xfs_buf *bp,
xfs_dir2_data_unused_t *dup) /* data unused pointer */ xfs_dir2_data_unused_t *dup) /* data unused pointer */
{ {
@ -695,13 +697,13 @@ xfs_dir2_data_log_unused(
/* /*
* Log the first part of the unused entry. * Log the first part of the unused entry.
*/ */
xfs_trans_log_buf(tp, bp, (uint)((char *)dup - (char *)hdr), xfs_trans_log_buf(args->trans, bp, (uint)((char *)dup - (char *)hdr),
(uint)((char *)&dup->length + sizeof(dup->length) - (uint)((char *)&dup->length + sizeof(dup->length) -
1 - (char *)hdr)); 1 - (char *)hdr));
/* /*
* Log the end (tag) of the unused entry. * Log the end (tag) of the unused entry.
*/ */
xfs_trans_log_buf(tp, bp, xfs_trans_log_buf(args->trans, bp,
(uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr), (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr),
(uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr + (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr +
sizeof(xfs_dir2_data_off_t) - 1)); sizeof(xfs_dir2_data_off_t) - 1));
@ -713,8 +715,7 @@ xfs_dir2_data_log_unused(
*/ */
void void
xfs_dir2_data_make_free( xfs_dir2_data_make_free(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_inode *dp,
struct xfs_buf *bp, struct xfs_buf *bp,
xfs_dir2_data_aoff_t offset, /* starting byte offset */ xfs_dir2_data_aoff_t offset, /* starting byte offset */
xfs_dir2_data_aoff_t len, /* length in bytes */ xfs_dir2_data_aoff_t len, /* length in bytes */
@ -724,14 +725,12 @@ xfs_dir2_data_make_free(
xfs_dir2_data_hdr_t *hdr; /* data block pointer */ xfs_dir2_data_hdr_t *hdr; /* data block pointer */
xfs_dir2_data_free_t *dfp; /* bestfree pointer */ xfs_dir2_data_free_t *dfp; /* bestfree pointer */
char *endptr; /* end of data area */ char *endptr; /* end of data area */
xfs_mount_t *mp; /* filesystem mount point */
int needscan; /* need to regen bestfree */ int needscan; /* need to regen bestfree */
xfs_dir2_data_unused_t *newdup; /* new unused entry */ xfs_dir2_data_unused_t *newdup; /* new unused entry */
xfs_dir2_data_unused_t *postdup; /* unused entry after us */ xfs_dir2_data_unused_t *postdup; /* unused entry after us */
xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ xfs_dir2_data_unused_t *prevdup; /* unused entry before us */
struct xfs_dir2_data_free *bf; struct xfs_dir2_data_free *bf;
mp = tp->t_mountp;
hdr = bp->b_addr; hdr = bp->b_addr;
/* /*
@ -739,20 +738,20 @@ xfs_dir2_data_make_free(
*/ */
if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)) hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC))
endptr = (char *)hdr + mp->m_dirblksize; endptr = (char *)hdr + args->geo->blksize;
else { else {
xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_block_tail_t *btp; /* block tail */
ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
endptr = (char *)xfs_dir2_block_leaf_p(btp); endptr = (char *)xfs_dir2_block_leaf_p(btp);
} }
/* /*
* If this isn't the start of the block, then back up to * If this isn't the start of the block, then back up to
* the previous entry and see if it's free. * the previous entry and see if it's free.
*/ */
if (offset > dp->d_ops->data_entry_offset) { if (offset > args->dp->d_ops->data_entry_offset) {
__be16 *tagp; /* tag just before us */ __be16 *tagp; /* tag just before us */
tagp = (__be16 *)((char *)hdr + offset) - 1; tagp = (__be16 *)((char *)hdr + offset) - 1;
@ -778,7 +777,7 @@ xfs_dir2_data_make_free(
* Previous and following entries are both free, * Previous and following entries are both free,
* merge everything into a single free entry. * merge everything into a single free entry.
*/ */
bf = dp->d_ops->data_bestfree_p(hdr); bf = args->dp->d_ops->data_bestfree_p(hdr);
if (prevdup && postdup) { if (prevdup && postdup) {
xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */
@ -800,7 +799,7 @@ xfs_dir2_data_make_free(
be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length)); be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
*xfs_dir2_data_unused_tag_p(prevdup) = *xfs_dir2_data_unused_tag_p(prevdup) =
cpu_to_be16((char *)prevdup - (char *)hdr); cpu_to_be16((char *)prevdup - (char *)hdr);
xfs_dir2_data_log_unused(tp, bp, prevdup); xfs_dir2_data_log_unused(args, bp, prevdup);
if (!needscan) { if (!needscan) {
/* /*
* Has to be the case that entries 0 and 1 are * Has to be the case that entries 0 and 1 are
@ -835,7 +834,7 @@ xfs_dir2_data_make_free(
be16_add_cpu(&prevdup->length, len); be16_add_cpu(&prevdup->length, len);
*xfs_dir2_data_unused_tag_p(prevdup) = *xfs_dir2_data_unused_tag_p(prevdup) =
cpu_to_be16((char *)prevdup - (char *)hdr); cpu_to_be16((char *)prevdup - (char *)hdr);
xfs_dir2_data_log_unused(tp, bp, prevdup); xfs_dir2_data_log_unused(args, bp, prevdup);
/* /*
* If the previous entry was in the table, the new entry * If the previous entry was in the table, the new entry
* is longer, so it will be in the table too. Remove * is longer, so it will be in the table too. Remove
@ -863,7 +862,7 @@ xfs_dir2_data_make_free(
newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
*xfs_dir2_data_unused_tag_p(newdup) = *xfs_dir2_data_unused_tag_p(newdup) =
cpu_to_be16((char *)newdup - (char *)hdr); cpu_to_be16((char *)newdup - (char *)hdr);
xfs_dir2_data_log_unused(tp, bp, newdup); xfs_dir2_data_log_unused(args, bp, newdup);
/* /*
* If the following entry was in the table, the new entry * If the following entry was in the table, the new entry
* is longer, so it will be in the table too. Remove * is longer, so it will be in the table too. Remove
@ -890,7 +889,7 @@ xfs_dir2_data_make_free(
newdup->length = cpu_to_be16(len); newdup->length = cpu_to_be16(len);
*xfs_dir2_data_unused_tag_p(newdup) = *xfs_dir2_data_unused_tag_p(newdup) =
cpu_to_be16((char *)newdup - (char *)hdr); cpu_to_be16((char *)newdup - (char *)hdr);
xfs_dir2_data_log_unused(tp, bp, newdup); xfs_dir2_data_log_unused(args, bp, newdup);
xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp); xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
} }
*needscanp = needscan; *needscanp = needscan;
@ -901,8 +900,7 @@ xfs_dir2_data_make_free(
*/ */
void void
xfs_dir2_data_use_free( xfs_dir2_data_use_free(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_inode *dp,
struct xfs_buf *bp, struct xfs_buf *bp,
xfs_dir2_data_unused_t *dup, /* unused entry */ xfs_dir2_data_unused_t *dup, /* unused entry */
xfs_dir2_data_aoff_t offset, /* starting offset to use */ xfs_dir2_data_aoff_t offset, /* starting offset to use */
@ -933,7 +931,7 @@ xfs_dir2_data_use_free(
* Look up the entry in the bestfree table. * Look up the entry in the bestfree table.
*/ */
oldlen = be16_to_cpu(dup->length); oldlen = be16_to_cpu(dup->length);
bf = dp->d_ops->data_bestfree_p(hdr); bf = args->dp->d_ops->data_bestfree_p(hdr);
dfp = xfs_dir2_data_freefind(hdr, bf, dup); dfp = xfs_dir2_data_freefind(hdr, bf, dup);
ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length)); ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
/* /*
@ -965,7 +963,7 @@ xfs_dir2_data_use_free(
newdup->length = cpu_to_be16(oldlen - len); newdup->length = cpu_to_be16(oldlen - len);
*xfs_dir2_data_unused_tag_p(newdup) = *xfs_dir2_data_unused_tag_p(newdup) =
cpu_to_be16((char *)newdup - (char *)hdr); cpu_to_be16((char *)newdup - (char *)hdr);
xfs_dir2_data_log_unused(tp, bp, newdup); xfs_dir2_data_log_unused(args, bp, newdup);
/* /*
* If it was in the table, remove it and add the new one. * If it was in the table, remove it and add the new one.
*/ */
@ -993,7 +991,7 @@ xfs_dir2_data_use_free(
newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
*xfs_dir2_data_unused_tag_p(newdup) = *xfs_dir2_data_unused_tag_p(newdup) =
cpu_to_be16((char *)newdup - (char *)hdr); cpu_to_be16((char *)newdup - (char *)hdr);
xfs_dir2_data_log_unused(tp, bp, newdup); xfs_dir2_data_log_unused(args, bp, newdup);
/* /*
* If it was in the table, remove it and add the new one. * If it was in the table, remove it and add the new one.
*/ */
@ -1021,13 +1019,13 @@ xfs_dir2_data_use_free(
newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
*xfs_dir2_data_unused_tag_p(newdup) = *xfs_dir2_data_unused_tag_p(newdup) =
cpu_to_be16((char *)newdup - (char *)hdr); cpu_to_be16((char *)newdup - (char *)hdr);
xfs_dir2_data_log_unused(tp, bp, newdup); xfs_dir2_data_log_unused(args, bp, newdup);
newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length));
*xfs_dir2_data_unused_tag_p(newdup2) = *xfs_dir2_data_unused_tag_p(newdup2) =
cpu_to_be16((char *)newdup2 - (char *)hdr); cpu_to_be16((char *)newdup2 - (char *)hdr);
xfs_dir2_data_log_unused(tp, bp, newdup2); xfs_dir2_data_log_unused(args, bp, newdup2);
/* /*
* If the old entry was in the table, we need to scan * If the old entry was in the table, we need to scan
* if the 3rd entry was valid, since these entries * if the 3rd entry was valid, since these entries

View File

@ -41,9 +41,10 @@
*/ */
static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp, static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp,
int *indexp, struct xfs_buf **dbpp); int *indexp, struct xfs_buf **dbpp);
static void xfs_dir3_leaf_log_bests(struct xfs_trans *tp, struct xfs_buf *bp, static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args,
int first, int last); struct xfs_buf *bp, int first, int last);
static void xfs_dir3_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp); static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args,
struct xfs_buf *bp);
/* /*
* Check the internal consistency of a leaf1 block. * Check the internal consistency of a leaf1 block.
@ -92,6 +93,7 @@ xfs_dir3_leaf_check_int(
int i; int i;
const struct xfs_dir_ops *ops; const struct xfs_dir_ops *ops;
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
struct xfs_da_geometry *geo = mp->m_dir_geo;
/* /*
* we can be passed a null dp here from a verifier, so we need to go the * we can be passed a null dp here from a verifier, so we need to go the
@ -105,14 +107,14 @@ xfs_dir3_leaf_check_int(
} }
ents = ops->leaf_ents_p(leaf); ents = ops->leaf_ents_p(leaf);
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(geo, leaf);
/* /*
* XXX (dgc): This value is not restrictive enough. * XXX (dgc): This value is not restrictive enough.
* Should factor in the size of the bests table as well. * Should factor in the size of the bests table as well.
* We can deduce a value for that from di_size. * We can deduce a value for that from di_size.
*/ */
if (hdr->count > ops->leaf_max_ents(mp)) if (hdr->count > ops->leaf_max_ents(geo))
return false; return false;
/* Leaves and bests don't overlap in leaf format. */ /* Leaves and bests don't overlap in leaf format. */
@ -323,7 +325,7 @@ xfs_dir3_leaf_init(
if (type == XFS_DIR2_LEAF1_MAGIC) { if (type == XFS_DIR2_LEAF1_MAGIC) {
struct xfs_dir2_leaf_tail *ltp; struct xfs_dir2_leaf_tail *ltp;
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(mp->m_dir_geo, leaf);
ltp->bestcount = 0; ltp->bestcount = 0;
bp->b_ops = &xfs_dir3_leaf1_buf_ops; bp->b_ops = &xfs_dir3_leaf1_buf_ops;
xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAF1_BUF); xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAF1_BUF);
@ -347,18 +349,18 @@ xfs_dir3_leaf_get_buf(
int error; int error;
ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC); ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC);
ASSERT(bno >= XFS_DIR2_LEAF_FIRSTDB(mp) && ASSERT(bno >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET) &&
bno < XFS_DIR2_FREE_FIRSTDB(mp)); bno < xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET));
error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp, error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, bno),
XFS_DATA_FORK); -1, &bp, XFS_DATA_FORK);
if (error) if (error)
return error; return error;
xfs_dir3_leaf_init(mp, tp, bp, dp->i_ino, magic); xfs_dir3_leaf_init(mp, tp, bp, dp->i_ino, magic);
xfs_dir3_leaf_log_header(tp, dp, bp); xfs_dir3_leaf_log_header(args, bp);
if (magic == XFS_DIR2_LEAF1_MAGIC) if (magic == XFS_DIR2_LEAF1_MAGIC)
xfs_dir3_leaf_log_tail(tp, bp); xfs_dir3_leaf_log_tail(args, bp);
*bpp = bp; *bpp = bp;
return 0; return 0;
} }
@ -403,8 +405,8 @@ xfs_dir2_block_to_leaf(
if ((error = xfs_da_grow_inode(args, &blkno))) { if ((error = xfs_da_grow_inode(args, &blkno))) {
return error; return error;
} }
ldb = xfs_dir2_da_to_db(mp, blkno); ldb = xfs_dir2_da_to_db(args->geo, blkno);
ASSERT(ldb == XFS_DIR2_LEAF_FIRSTDB(mp)); ASSERT(ldb == xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET));
/* /*
* Initialize the leaf block, get a buffer for it. * Initialize the leaf block, get a buffer for it.
*/ */
@ -415,7 +417,7 @@ xfs_dir2_block_to_leaf(
leaf = lbp->b_addr; leaf = lbp->b_addr;
hdr = dbp->b_addr; hdr = dbp->b_addr;
xfs_dir3_data_check(dp, dbp); xfs_dir3_data_check(dp, dbp);
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(args->geo, hdr);
blp = xfs_dir2_block_leaf_p(btp); blp = xfs_dir2_block_leaf_p(btp);
bf = dp->d_ops->data_bestfree_p(hdr); bf = dp->d_ops->data_bestfree_p(hdr);
ents = dp->d_ops->leaf_ents_p(leaf); ents = dp->d_ops->leaf_ents_p(leaf);
@ -427,23 +429,23 @@ xfs_dir2_block_to_leaf(
leafhdr.count = be32_to_cpu(btp->count); leafhdr.count = be32_to_cpu(btp->count);
leafhdr.stale = be32_to_cpu(btp->stale); leafhdr.stale = be32_to_cpu(btp->stale);
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
xfs_dir3_leaf_log_header(tp, dp, lbp); xfs_dir3_leaf_log_header(args, lbp);
/* /*
* Could compact these but I think we always do the conversion * Could compact these but I think we always do the conversion
* after squeezing out stale entries. * after squeezing out stale entries.
*/ */
memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t));
xfs_dir3_leaf_log_ents(tp, dp, lbp, 0, leafhdr.count - 1); xfs_dir3_leaf_log_ents(args, lbp, 0, leafhdr.count - 1);
needscan = 0; needscan = 0;
needlog = 1; needlog = 1;
/* /*
* Make the space formerly occupied by the leaf entries and block * Make the space formerly occupied by the leaf entries and block
* tail be free. * tail be free.
*/ */
xfs_dir2_data_make_free(tp, dp, dbp, xfs_dir2_data_make_free(args, dbp,
(xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
(xfs_dir2_data_aoff_t)((char *)hdr + mp->m_dirblksize - (xfs_dir2_data_aoff_t)((char *)hdr + args->geo->blksize -
(char *)blp), (char *)blp),
&needlog, &needscan); &needlog, &needscan);
/* /*
@ -461,7 +463,7 @@ xfs_dir2_block_to_leaf(
/* /*
* Set up leaf tail and bests table. * Set up leaf tail and bests table.
*/ */
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
ltp->bestcount = cpu_to_be32(1); ltp->bestcount = cpu_to_be32(1);
bestsp = xfs_dir2_leaf_bests_p(ltp); bestsp = xfs_dir2_leaf_bests_p(ltp);
bestsp[0] = bf[0].length; bestsp[0] = bf[0].length;
@ -469,10 +471,10 @@ xfs_dir2_block_to_leaf(
* Log the data header and leaf bests table. * Log the data header and leaf bests table.
*/ */
if (needlog) if (needlog)
xfs_dir2_data_log_header(tp, dp, dbp); xfs_dir2_data_log_header(args, dbp);
xfs_dir3_leaf_check(dp, lbp); xfs_dir3_leaf_check(dp, lbp);
xfs_dir3_data_check(dp, dbp); xfs_dir3_data_check(dp, dbp);
xfs_dir3_leaf_log_bests(tp, lbp, 0, 0); xfs_dir3_leaf_log_bests(args, lbp, 0, 0);
return 0; return 0;
} }
@ -641,7 +643,7 @@ xfs_dir2_leaf_addname(
tp = args->trans; tp = args->trans;
mp = dp->i_mount; mp = dp->i_mount;
error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp); error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
if (error) if (error)
return error; return error;
@ -653,7 +655,7 @@ xfs_dir2_leaf_addname(
*/ */
index = xfs_dir2_leaf_search_hash(args, lbp); index = xfs_dir2_leaf_search_hash(args, lbp);
leaf = lbp->b_addr; leaf = lbp->b_addr;
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
ents = dp->d_ops->leaf_ents_p(leaf); ents = dp->d_ops->leaf_ents_p(leaf);
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
bestsp = xfs_dir2_leaf_bests_p(ltp); bestsp = xfs_dir2_leaf_bests_p(ltp);
@ -670,7 +672,7 @@ xfs_dir2_leaf_addname(
index++, lep++) { index++, lep++) {
if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR) if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
continue; continue;
i = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); i = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
ASSERT(i < be32_to_cpu(ltp->bestcount)); ASSERT(i < be32_to_cpu(ltp->bestcount));
ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF)); ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF));
if (be16_to_cpu(bestsp[i]) >= length) { if (be16_to_cpu(bestsp[i]) >= length) {
@ -810,14 +812,15 @@ xfs_dir2_leaf_addname(
memmove(&bestsp[0], &bestsp[1], memmove(&bestsp[0], &bestsp[1],
be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0])); be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
be32_add_cpu(&ltp->bestcount, 1); be32_add_cpu(&ltp->bestcount, 1);
xfs_dir3_leaf_log_tail(tp, lbp); xfs_dir3_leaf_log_tail(args, lbp);
xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); xfs_dir3_leaf_log_bests(args, lbp, 0,
be32_to_cpu(ltp->bestcount) - 1);
} }
/* /*
* If we're filling in a previously empty block just log it. * If we're filling in a previously empty block just log it.
*/ */
else else
xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block); xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
hdr = dbp->b_addr; hdr = dbp->b_addr;
bf = dp->d_ops->data_bestfree_p(hdr); bf = dp->d_ops->data_bestfree_p(hdr);
bestsp[use_block] = bf[0].length; bestsp[use_block] = bf[0].length;
@ -828,8 +831,8 @@ xfs_dir2_leaf_addname(
* Just read that one in. * Just read that one in.
*/ */
error = xfs_dir3_data_read(tp, dp, error = xfs_dir3_data_read(tp, dp,
xfs_dir2_db_to_da(mp, use_block), xfs_dir2_db_to_da(args->geo, use_block),
-1, &dbp); -1, &dbp);
if (error) { if (error) {
xfs_trans_brelse(tp, lbp); xfs_trans_brelse(tp, lbp);
return error; return error;
@ -848,7 +851,7 @@ xfs_dir2_leaf_addname(
/* /*
* Mark the initial part of our freespace in use for the new entry. * Mark the initial part of our freespace in use for the new entry.
*/ */
xfs_dir2_data_use_free(tp, dp, dbp, dup, xfs_dir2_data_use_free(args, dbp, dup,
(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length, (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
&needlog, &needscan); &needlog, &needscan);
/* /*
@ -870,8 +873,8 @@ xfs_dir2_leaf_addname(
* Need to log the data block's header. * Need to log the data block's header.
*/ */
if (needlog) if (needlog)
xfs_dir2_data_log_header(tp, dp, dbp); xfs_dir2_data_log_header(args, dbp);
xfs_dir2_data_log_entry(tp, dp, dbp, dep); xfs_dir2_data_log_entry(args, dbp, dep);
/* /*
* If the bests table needs to be changed, do it. * If the bests table needs to be changed, do it.
* Log the change unless we've already done that. * Log the change unless we've already done that.
@ -879,7 +882,7 @@ xfs_dir2_leaf_addname(
if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) { if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) {
bestsp[use_block] = bf[0].length; bestsp[use_block] = bf[0].length;
if (!grown) if (!grown)
xfs_dir3_leaf_log_bests(tp, lbp, use_block, use_block); xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
} }
lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale, lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale,
@ -889,14 +892,15 @@ xfs_dir2_leaf_addname(
* Fill in the new leaf entry. * Fill in the new leaf entry.
*/ */
lep->hashval = cpu_to_be32(args->hashval); lep->hashval = cpu_to_be32(args->hashval);
lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, use_block, lep->address = cpu_to_be32(
xfs_dir2_db_off_to_dataptr(args->geo, use_block,
be16_to_cpu(*tagp))); be16_to_cpu(*tagp)));
/* /*
* Log the leaf fields and give up the buffers. * Log the leaf fields and give up the buffers.
*/ */
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
xfs_dir3_leaf_log_header(tp, dp, lbp); xfs_dir3_leaf_log_header(args, lbp);
xfs_dir3_leaf_log_ents(tp, dp, lbp, lfloglow, lfloghigh); xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh);
xfs_dir3_leaf_check(dp, lbp); xfs_dir3_leaf_check(dp, lbp);
xfs_dir3_data_check(dp, dbp); xfs_dir3_data_check(dp, dbp);
return 0; return 0;
@ -948,9 +952,9 @@ xfs_dir3_leaf_compact(
leafhdr->stale = 0; leafhdr->stale = 0;
dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr); dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr);
xfs_dir3_leaf_log_header(args->trans, dp, bp); xfs_dir3_leaf_log_header(args, bp);
if (loglow != -1) if (loglow != -1)
xfs_dir3_leaf_log_ents(args->trans, dp, bp, loglow, to - 1); xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1);
} }
/* /*
@ -1052,7 +1056,7 @@ xfs_dir3_leaf_compact_x1(
*/ */
static void static void
xfs_dir3_leaf_log_bests( xfs_dir3_leaf_log_bests(
xfs_trans_t *tp, /* transaction pointer */ struct xfs_da_args *args,
struct xfs_buf *bp, /* leaf buffer */ struct xfs_buf *bp, /* leaf buffer */
int first, /* first entry to log */ int first, /* first entry to log */
int last) /* last entry to log */ int last) /* last entry to log */
@ -1065,10 +1069,11 @@ xfs_dir3_leaf_log_bests(
ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC)); leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC));
ltp = xfs_dir2_leaf_tail_p(tp->t_mountp, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
firstb = xfs_dir2_leaf_bests_p(ltp) + first; firstb = xfs_dir2_leaf_bests_p(ltp) + first;
lastb = xfs_dir2_leaf_bests_p(ltp) + last; lastb = xfs_dir2_leaf_bests_p(ltp) + last;
xfs_trans_log_buf(tp, bp, (uint)((char *)firstb - (char *)leaf), xfs_trans_log_buf(args->trans, bp,
(uint)((char *)firstb - (char *)leaf),
(uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1)); (uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1));
} }
@ -1077,8 +1082,7 @@ xfs_dir3_leaf_log_bests(
*/ */
void void
xfs_dir3_leaf_log_ents( xfs_dir3_leaf_log_ents(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_inode *dp,
struct xfs_buf *bp, struct xfs_buf *bp,
int first, int first,
int last) int last)
@ -1093,10 +1097,11 @@ xfs_dir3_leaf_log_ents(
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
ents = dp->d_ops->leaf_ents_p(leaf); ents = args->dp->d_ops->leaf_ents_p(leaf);
firstlep = &ents[first]; firstlep = &ents[first];
lastlep = &ents[last]; lastlep = &ents[last];
xfs_trans_log_buf(tp, bp, (uint)((char *)firstlep - (char *)leaf), xfs_trans_log_buf(args->trans, bp,
(uint)((char *)firstlep - (char *)leaf),
(uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
} }
@ -1105,8 +1110,7 @@ xfs_dir3_leaf_log_ents(
*/ */
void void
xfs_dir3_leaf_log_header( xfs_dir3_leaf_log_header(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_inode *dp,
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_dir2_leaf *leaf = bp->b_addr; struct xfs_dir2_leaf *leaf = bp->b_addr;
@ -1116,8 +1120,9 @@ xfs_dir3_leaf_log_header(
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
xfs_trans_log_buf(tp, bp, (uint)((char *)&leaf->hdr - (char *)leaf), xfs_trans_log_buf(args->trans, bp,
dp->d_ops->leaf_hdr_size - 1); (uint)((char *)&leaf->hdr - (char *)leaf),
args->dp->d_ops->leaf_hdr_size - 1);
} }
/* /*
@ -1125,21 +1130,20 @@ xfs_dir3_leaf_log_header(
*/ */
STATIC void STATIC void
xfs_dir3_leaf_log_tail( xfs_dir3_leaf_log_tail(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_dir2_leaf *leaf = bp->b_addr; struct xfs_dir2_leaf *leaf = bp->b_addr;
xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */ xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
struct xfs_mount *mp = tp->t_mountp;
ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
xfs_trans_log_buf(tp, bp, (uint)((char *)ltp - (char *)leaf), xfs_trans_log_buf(args->trans, bp, (uint)((char *)ltp - (char *)leaf),
(uint)(mp->m_dirblksize - 1)); (uint)(args->geo->blksize - 1));
} }
/* /*
@ -1185,7 +1189,7 @@ xfs_dir2_leaf_lookup(
*/ */
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)
((char *)dbp->b_addr + ((char *)dbp->b_addr +
xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
/* /*
* Return the found inode number & CI name if appropriate * Return the found inode number & CI name if appropriate
*/ */
@ -1231,7 +1235,7 @@ xfs_dir2_leaf_lookup_int(
tp = args->trans; tp = args->trans;
mp = dp->i_mount; mp = dp->i_mount;
error = xfs_dir3_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp); error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
if (error) if (error)
return error; return error;
@ -1260,7 +1264,8 @@ xfs_dir2_leaf_lookup_int(
/* /*
* Get the new data block number. * Get the new data block number.
*/ */
newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); newdb = xfs_dir2_dataptr_to_db(args->geo,
be32_to_cpu(lep->address));
/* /*
* If it's not the same as the old data block number, * If it's not the same as the old data block number,
* need to pitch the old one and read the new one. * need to pitch the old one and read the new one.
@ -1269,8 +1274,8 @@ xfs_dir2_leaf_lookup_int(
if (dbp) if (dbp)
xfs_trans_brelse(tp, dbp); xfs_trans_brelse(tp, dbp);
error = xfs_dir3_data_read(tp, dp, error = xfs_dir3_data_read(tp, dp,
xfs_dir2_db_to_da(mp, newdb), xfs_dir2_db_to_da(args->geo, newdb),
-1, &dbp); -1, &dbp);
if (error) { if (error) {
xfs_trans_brelse(tp, lbp); xfs_trans_brelse(tp, lbp);
return error; return error;
@ -1281,7 +1286,8 @@ xfs_dir2_leaf_lookup_int(
* Point to the data entry. * Point to the data entry.
*/ */
dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr + dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr +
xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); xfs_dir2_dataptr_to_off(args->geo,
be32_to_cpu(lep->address)));
/* /*
* Compare name and if it's an exact match, return the index * Compare name and if it's an exact match, return the index
* and buffer. If it's the first case-insensitive match, store * and buffer. If it's the first case-insensitive match, store
@ -1310,8 +1316,8 @@ xfs_dir2_leaf_lookup_int(
if (cidb != curdb) { if (cidb != curdb) {
xfs_trans_brelse(tp, dbp); xfs_trans_brelse(tp, dbp);
error = xfs_dir3_data_read(tp, dp, error = xfs_dir3_data_read(tp, dp,
xfs_dir2_db_to_da(mp, cidb), xfs_dir2_db_to_da(args->geo, cidb),
-1, &dbp); -1, &dbp);
if (error) { if (error) {
xfs_trans_brelse(tp, lbp); xfs_trans_brelse(tp, lbp);
return error; return error;
@ -1380,18 +1386,18 @@ xfs_dir2_leaf_removename(
* Point to the leaf entry, use that to point to the data entry. * Point to the leaf entry, use that to point to the data entry.
*/ */
lep = &ents[index]; lep = &ents[index];
db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)((char *)hdr +
((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
needscan = needlog = 0; needscan = needlog = 0;
oldbest = be16_to_cpu(bf[0].length); oldbest = be16_to_cpu(bf[0].length);
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
bestsp = xfs_dir2_leaf_bests_p(ltp); bestsp = xfs_dir2_leaf_bests_p(ltp);
ASSERT(be16_to_cpu(bestsp[db]) == oldbest); ASSERT(be16_to_cpu(bestsp[db]) == oldbest);
/* /*
* Mark the former data entry unused. * Mark the former data entry unused.
*/ */
xfs_dir2_data_make_free(tp, dp, dbp, xfs_dir2_data_make_free(args, dbp,
(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
/* /*
@ -1399,10 +1405,10 @@ xfs_dir2_leaf_removename(
*/ */
leafhdr.stale++; leafhdr.stale++;
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
xfs_dir3_leaf_log_header(tp, dp, lbp); xfs_dir3_leaf_log_header(args, lbp);
lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
xfs_dir3_leaf_log_ents(tp, dp, lbp, index, index); xfs_dir3_leaf_log_ents(args, lbp, index, index);
/* /*
* Scan the freespace in the data block again if necessary, * Scan the freespace in the data block again if necessary,
@ -1411,22 +1417,22 @@ xfs_dir2_leaf_removename(
if (needscan) if (needscan)
xfs_dir2_data_freescan(dp, hdr, &needlog); xfs_dir2_data_freescan(dp, hdr, &needlog);
if (needlog) if (needlog)
xfs_dir2_data_log_header(tp, dp, dbp); xfs_dir2_data_log_header(args, dbp);
/* /*
* If the longest freespace in the data block has changed, * If the longest freespace in the data block has changed,
* put the new value in the bests table and log that. * put the new value in the bests table and log that.
*/ */
if (be16_to_cpu(bf[0].length) != oldbest) { if (be16_to_cpu(bf[0].length) != oldbest) {
bestsp[db] = bf[0].length; bestsp[db] = bf[0].length;
xfs_dir3_leaf_log_bests(tp, lbp, db, db); xfs_dir3_leaf_log_bests(args, lbp, db, db);
} }
xfs_dir3_data_check(dp, dbp); xfs_dir3_data_check(dp, dbp);
/* /*
* If the data block is now empty then get rid of the data block. * If the data block is now empty then get rid of the data block.
*/ */
if (be16_to_cpu(bf[0].length) == if (be16_to_cpu(bf[0].length) ==
mp->m_dirblksize - dp->d_ops->data_entry_offset) { args->geo->blksize - dp->d_ops->data_entry_offset) {
ASSERT(db != mp->m_dirdatablk); ASSERT(db != args->geo->datablk);
if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
/* /*
* Nope, can't get rid of it because it caused * Nope, can't get rid of it because it caused
@ -1459,15 +1465,16 @@ xfs_dir2_leaf_removename(
memmove(&bestsp[db - i], bestsp, memmove(&bestsp[db - i], bestsp,
(be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp)); (be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
be32_add_cpu(&ltp->bestcount, -(db - i)); be32_add_cpu(&ltp->bestcount, -(db - i));
xfs_dir3_leaf_log_tail(tp, lbp); xfs_dir3_leaf_log_tail(args, lbp);
xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); xfs_dir3_leaf_log_bests(args, lbp, 0,
be32_to_cpu(ltp->bestcount) - 1);
} else } else
bestsp[db] = cpu_to_be16(NULLDATAOFF); bestsp[db] = cpu_to_be16(NULLDATAOFF);
} }
/* /*
* If the data block was not the first one, drop it. * If the data block was not the first one, drop it.
*/ */
else if (db != mp->m_dirdatablk) else if (db != args->geo->datablk)
dbp = NULL; dbp = NULL;
xfs_dir3_leaf_check(dp, lbp); xfs_dir3_leaf_check(dp, lbp);
@ -1515,7 +1522,7 @@ xfs_dir2_leaf_replace(
*/ */
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)
((char *)dbp->b_addr + ((char *)dbp->b_addr +
xfs_dir2_dataptr_to_off(dp->i_mount, be32_to_cpu(lep->address))); xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
ASSERT(args->inumber != be64_to_cpu(dep->inumber)); ASSERT(args->inumber != be64_to_cpu(dep->inumber));
/* /*
* Put the new inode number in, log it. * Put the new inode number in, log it.
@ -1523,7 +1530,7 @@ xfs_dir2_leaf_replace(
dep->inumber = cpu_to_be64(args->inumber); dep->inumber = cpu_to_be64(args->inumber);
dp->d_ops->data_put_ftype(dep, args->filetype); dp->d_ops->data_put_ftype(dep, args->filetype);
tp = args->trans; tp = args->trans;
xfs_dir2_data_log_entry(tp, dp, dbp, dep); xfs_dir2_data_log_entry(args, dbp, dep);
xfs_dir3_leaf_check(dp, lbp); xfs_dir3_leaf_check(dp, lbp);
xfs_trans_brelse(tp, lbp); xfs_trans_brelse(tp, lbp);
return 0; return 0;
@ -1609,12 +1616,13 @@ xfs_dir2_leaf_trim_data(
/* /*
* Read the offending data block. We need its buffer. * Read the offending data block. We need its buffer.
*/ */
error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp); error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, db),
-1, &dbp);
if (error) if (error)
return error; return error;
leaf = lbp->b_addr; leaf = lbp->b_addr;
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
#ifdef DEBUG #ifdef DEBUG
{ {
@ -1624,7 +1632,7 @@ xfs_dir2_leaf_trim_data(
ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
ASSERT(be16_to_cpu(bf[0].length) == ASSERT(be16_to_cpu(bf[0].length) ==
mp->m_dirblksize - dp->d_ops->data_entry_offset); args->geo->blksize - dp->d_ops->data_entry_offset);
ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
} }
#endif #endif
@ -1643,8 +1651,8 @@ xfs_dir2_leaf_trim_data(
bestsp = xfs_dir2_leaf_bests_p(ltp); bestsp = xfs_dir2_leaf_bests_p(ltp);
be32_add_cpu(&ltp->bestcount, -1); be32_add_cpu(&ltp->bestcount, -1);
memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp)); memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
xfs_dir3_leaf_log_tail(tp, lbp); xfs_dir3_leaf_log_tail(args, lbp);
xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
return 0; return 0;
} }
@ -1711,19 +1719,19 @@ xfs_dir2_node_to_leaf(
if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK))) { if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK))) {
return error; return error;
} }
fo -= mp->m_dirblkfsbs; fo -= args->geo->fsbcount;
/* /*
* If there are freespace blocks other than the first one, * If there are freespace blocks other than the first one,
* take this opportunity to remove trailing empty freespace blocks * take this opportunity to remove trailing empty freespace blocks
* that may have been left behind during no-space-reservation * that may have been left behind during no-space-reservation
* operations. * operations.
*/ */
while (fo > mp->m_dirfreeblk) { while (fo > args->geo->freeblk) {
if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) { if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) {
return error; return error;
} }
if (rval) if (rval)
fo -= mp->m_dirblkfsbs; fo -= args->geo->fsbcount;
else else
return 0; return 0;
} }
@ -1736,7 +1744,7 @@ xfs_dir2_node_to_leaf(
/* /*
* If it's not the single leaf block, give up. * If it's not the single leaf block, give up.
*/ */
if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + mp->m_dirblksize) if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + args->geo->blksize)
return 0; return 0;
lbp = state->path.blk[0].bp; lbp = state->path.blk[0].bp;
leaf = lbp->b_addr; leaf = lbp->b_addr;
@ -1748,7 +1756,7 @@ xfs_dir2_node_to_leaf(
/* /*
* Read the freespace block. * Read the freespace block.
*/ */
error = xfs_dir2_free_read(tp, dp, mp->m_dirfreeblk, &fbp); error = xfs_dir2_free_read(tp, dp, args->geo->freeblk, &fbp);
if (error) if (error)
return error; return error;
free = fbp->b_addr; free = fbp->b_addr;
@ -1760,7 +1768,7 @@ xfs_dir2_node_to_leaf(
* Now see if the leafn and free data will fit in a leaf1. * Now see if the leafn and free data will fit in a leaf1.
* If not, release the buffer and give up. * If not, release the buffer and give up.
*/ */
if (xfs_dir3_leaf_size(&leafhdr, freehdr.nvalid) > mp->m_dirblksize) { if (xfs_dir3_leaf_size(&leafhdr, freehdr.nvalid) > args->geo->blksize) {
xfs_trans_brelse(tp, fbp); xfs_trans_brelse(tp, fbp);
return 0; return 0;
} }
@ -1780,7 +1788,7 @@ xfs_dir2_node_to_leaf(
/* /*
* Set up the leaf tail from the freespace block. * Set up the leaf tail from the freespace block.
*/ */
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
ltp->bestcount = cpu_to_be32(freehdr.nvalid); ltp->bestcount = cpu_to_be32(freehdr.nvalid);
/* /*
@ -1790,15 +1798,17 @@ xfs_dir2_node_to_leaf(
freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
xfs_dir3_leaf_log_header(tp, dp, lbp); xfs_dir3_leaf_log_header(args, lbp);
xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
xfs_dir3_leaf_log_tail(tp, lbp); xfs_dir3_leaf_log_tail(args, lbp);
xfs_dir3_leaf_check(dp, lbp); xfs_dir3_leaf_check(dp, lbp);
/* /*
* Get rid of the freespace block. * Get rid of the freespace block.
*/ */
error = xfs_dir2_shrink_inode(args, XFS_DIR2_FREE_FIRSTDB(mp), fbp); error = xfs_dir2_shrink_inode(args,
xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET),
fbp);
if (error) { if (error) {
/* /*
* This can't fail here because it can only happen when * This can't fail here because it can only happen when

View File

@ -195,17 +195,18 @@ xfs_dir2_free_try_read(
static int static int
xfs_dir3_free_get_buf( xfs_dir3_free_get_buf(
struct xfs_trans *tp, xfs_da_args_t *args,
struct xfs_inode *dp,
xfs_dir2_db_t fbno, xfs_dir2_db_t fbno,
struct xfs_buf **bpp) struct xfs_buf **bpp)
{ {
struct xfs_trans *tp = args->trans;
struct xfs_inode *dp = args->dp;
struct xfs_mount *mp = dp->i_mount; struct xfs_mount *mp = dp->i_mount;
struct xfs_buf *bp; struct xfs_buf *bp;
int error; int error;
struct xfs_dir3_icfree_hdr hdr; struct xfs_dir3_icfree_hdr hdr;
error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, fbno), error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, fbno),
-1, &bp, XFS_DATA_FORK); -1, &bp, XFS_DATA_FORK);
if (error) if (error)
return error; return error;
@ -240,8 +241,7 @@ xfs_dir3_free_get_buf(
*/ */
STATIC void STATIC void
xfs_dir2_free_log_bests( xfs_dir2_free_log_bests(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_inode *dp,
struct xfs_buf *bp, struct xfs_buf *bp,
int first, /* first entry to log */ int first, /* first entry to log */
int last) /* last entry to log */ int last) /* last entry to log */
@ -250,10 +250,10 @@ xfs_dir2_free_log_bests(
__be16 *bests; __be16 *bests;
free = bp->b_addr; free = bp->b_addr;
bests = dp->d_ops->free_bests_p(free); bests = args->dp->d_ops->free_bests_p(free);
ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
xfs_trans_log_buf(tp, bp, xfs_trans_log_buf(args->trans, bp,
(uint)((char *)&bests[first] - (char *)free), (uint)((char *)&bests[first] - (char *)free),
(uint)((char *)&bests[last] - (char *)free + (uint)((char *)&bests[last] - (char *)free +
sizeof(bests[0]) - 1)); sizeof(bests[0]) - 1));
@ -264,8 +264,7 @@ xfs_dir2_free_log_bests(
*/ */
static void static void
xfs_dir2_free_log_header( xfs_dir2_free_log_header(
struct xfs_trans *tp, struct xfs_da_args *args,
struct xfs_inode *dp,
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
#ifdef DEBUG #ifdef DEBUG
@ -275,7 +274,8 @@ xfs_dir2_free_log_header(
ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) || ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC) ||
free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC)); free->hdr.magic == cpu_to_be32(XFS_DIR3_FREE_MAGIC));
#endif #endif
xfs_trans_log_buf(tp, bp, 0, dp->d_ops->free_hdr_size - 1); xfs_trans_log_buf(args->trans, bp, 0,
args->dp->d_ops->free_hdr_size - 1);
} }
/* /*
@ -315,20 +315,20 @@ xfs_dir2_leaf_to_node(
if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) { if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_FREE_SPACE, &fdb))) {
return error; return error;
} }
ASSERT(fdb == XFS_DIR2_FREE_FIRSTDB(mp)); ASSERT(fdb == xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET));
/* /*
* Get the buffer for the new freespace block. * Get the buffer for the new freespace block.
*/ */
error = xfs_dir3_free_get_buf(tp, dp, fdb, &fbp); error = xfs_dir3_free_get_buf(args, fdb, &fbp);
if (error) if (error)
return error; return error;
free = fbp->b_addr; free = fbp->b_addr;
dp->d_ops->free_hdr_from_disk(&freehdr, free); dp->d_ops->free_hdr_from_disk(&freehdr, free);
leaf = lbp->b_addr; leaf = lbp->b_addr;
ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
ASSERT(be32_to_cpu(ltp->bestcount) <= ASSERT(be32_to_cpu(ltp->bestcount) <=
(uint)dp->i_d.di_size / mp->m_dirblksize); (uint)dp->i_d.di_size / args->geo->blksize);
/* /*
* Copy freespace entries from the leaf block to the new block. * Copy freespace entries from the leaf block to the new block.
@ -349,8 +349,8 @@ xfs_dir2_leaf_to_node(
freehdr.nvalid = be32_to_cpu(ltp->bestcount); freehdr.nvalid = be32_to_cpu(ltp->bestcount);
dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
xfs_dir2_free_log_bests(tp, dp, fbp, 0, freehdr.nvalid - 1); xfs_dir2_free_log_bests(args, fbp, 0, freehdr.nvalid - 1);
xfs_dir2_free_log_header(tp, dp, fbp); xfs_dir2_free_log_header(args, fbp);
/* /*
* Converting the leaf to a leafnode is just a matter of changing the * Converting the leaf to a leafnode is just a matter of changing the
@ -364,7 +364,7 @@ xfs_dir2_leaf_to_node(
leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC); leaf->hdr.info.magic = cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
lbp->b_ops = &xfs_dir3_leafn_buf_ops; lbp->b_ops = &xfs_dir3_leafn_buf_ops;
xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF); xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAFN_BUF);
xfs_dir3_leaf_log_header(tp, dp, lbp); xfs_dir3_leaf_log_header(args, lbp);
xfs_dir3_leaf_check(dp, lbp); xfs_dir3_leaf_check(dp, lbp);
return 0; return 0;
} }
@ -415,7 +415,7 @@ xfs_dir2_leafn_add(
* a compact. * a compact.
*/ */
if (leafhdr.count == dp->d_ops->leaf_max_ents(mp)) { if (leafhdr.count == dp->d_ops->leaf_max_ents(args->geo)) {
if (!leafhdr.stale) if (!leafhdr.stale)
return XFS_ERROR(ENOSPC); return XFS_ERROR(ENOSPC);
compact = leafhdr.stale > 1; compact = leafhdr.stale > 1;
@ -450,12 +450,12 @@ xfs_dir2_leafn_add(
highstale, &lfloglow, &lfloghigh); highstale, &lfloglow, &lfloghigh);
lep->hashval = cpu_to_be32(args->hashval); lep->hashval = cpu_to_be32(args->hashval);
lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(args->geo,
args->blkno, args->index)); args->blkno, args->index));
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
xfs_dir3_leaf_log_header(tp, dp, bp); xfs_dir3_leaf_log_header(args, bp);
xfs_dir3_leaf_log_ents(tp, dp, bp, lfloglow, lfloghigh); xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh);
xfs_dir3_leaf_check(dp, bp); xfs_dir3_leaf_check(dp, bp);
return 0; return 0;
} }
@ -471,7 +471,8 @@ xfs_dir2_free_hdr_check(
dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr); dp->d_ops->free_hdr_from_disk(&hdr, bp->b_addr);
ASSERT((hdr.firstdb % dp->d_ops->free_max_bests(dp->i_mount)) == 0); ASSERT((hdr.firstdb %
dp->d_ops->free_max_bests(dp->i_mount->m_dir_geo)) == 0);
ASSERT(hdr.firstdb <= db); ASSERT(hdr.firstdb <= db);
ASSERT(db < hdr.firstdb + hdr.nvalid); ASSERT(db < hdr.firstdb + hdr.nvalid);
} }
@ -576,7 +577,8 @@ xfs_dir2_leafn_lookup_for_addname(
/* /*
* Pull the data block number from the entry. * Pull the data block number from the entry.
*/ */
newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); newdb = xfs_dir2_dataptr_to_db(args->geo,
be32_to_cpu(lep->address));
/* /*
* For addname, we're looking for a place to put the new entry. * For addname, we're looking for a place to put the new entry.
* We want to use a data block with an entry of equal * We want to use a data block with an entry of equal
@ -593,7 +595,7 @@ xfs_dir2_leafn_lookup_for_addname(
* Convert the data block to the free block * Convert the data block to the free block
* holding its freespace information. * holding its freespace information.
*/ */
newfdb = dp->d_ops->db_to_fdb(mp, newdb); newfdb = dp->d_ops->db_to_fdb(args->geo, newdb);
/* /*
* If it's not the one we have in hand, read it in. * If it's not the one we have in hand, read it in.
*/ */
@ -605,7 +607,8 @@ xfs_dir2_leafn_lookup_for_addname(
xfs_trans_brelse(tp, curbp); xfs_trans_brelse(tp, curbp);
error = xfs_dir2_free_read(tp, dp, error = xfs_dir2_free_read(tp, dp,
xfs_dir2_db_to_da(mp, newfdb), xfs_dir2_db_to_da(args->geo,
newfdb),
&curbp); &curbp);
if (error) if (error)
return error; return error;
@ -616,7 +619,7 @@ xfs_dir2_leafn_lookup_for_addname(
/* /*
* Get the index for our entry. * Get the index for our entry.
*/ */
fi = dp->d_ops->db_to_fdindex(mp, curdb); fi = dp->d_ops->db_to_fdindex(args->geo, curdb);
/* /*
* If it has room, return it. * If it has room, return it.
*/ */
@ -721,7 +724,8 @@ xfs_dir2_leafn_lookup_for_entry(
/* /*
* Pull the data block number from the entry. * Pull the data block number from the entry.
*/ */
newdb = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); newdb = xfs_dir2_dataptr_to_db(args->geo,
be32_to_cpu(lep->address));
/* /*
* Not adding a new entry, so we really want to find * Not adding a new entry, so we really want to find
* the name given to us. * the name given to us.
@ -746,7 +750,8 @@ xfs_dir2_leafn_lookup_for_entry(
curbp = state->extrablk.bp; curbp = state->extrablk.bp;
} else { } else {
error = xfs_dir3_data_read(tp, dp, error = xfs_dir3_data_read(tp, dp,
xfs_dir2_db_to_da(mp, newdb), xfs_dir2_db_to_da(args->geo,
newdb),
-1, &curbp); -1, &curbp);
if (error) if (error)
return error; return error;
@ -758,7 +763,8 @@ xfs_dir2_leafn_lookup_for_entry(
* Point to the data entry. * Point to the data entry.
*/ */
dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr + dep = (xfs_dir2_data_entry_t *)((char *)curbp->b_addr +
xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); xfs_dir2_dataptr_to_off(args->geo,
be32_to_cpu(lep->address)));
/* /*
* Compare the entry and if it's an exact match, return * Compare the entry and if it's an exact match, return
* EEXIST immediately. If it's the first case-insensitive * EEXIST immediately. If it's the first case-insensitive
@ -844,7 +850,6 @@ xfs_dir3_leafn_moveents(
int start_d,/* destination leaf index */ int start_d,/* destination leaf index */
int count) /* count of leaves to copy */ int count) /* count of leaves to copy */
{ {
struct xfs_trans *tp = args->trans;
int stale; /* count stale leaves copied */ int stale; /* count stale leaves copied */
trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count); trace_xfs_dir2_leafn_moveents(args, start_s, start_d, count);
@ -863,7 +868,7 @@ xfs_dir3_leafn_moveents(
if (start_d < dhdr->count) { if (start_d < dhdr->count) {
memmove(&dents[start_d + count], &dents[start_d], memmove(&dents[start_d + count], &dents[start_d],
(dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t)); (dhdr->count - start_d) * sizeof(xfs_dir2_leaf_entry_t));
xfs_dir3_leaf_log_ents(tp, args->dp, bp_d, start_d + count, xfs_dir3_leaf_log_ents(args, bp_d, start_d + count,
count + dhdr->count - 1); count + dhdr->count - 1);
} }
/* /*
@ -885,8 +890,7 @@ xfs_dir3_leafn_moveents(
*/ */
memcpy(&dents[start_d], &sents[start_s], memcpy(&dents[start_d], &sents[start_s],
count * sizeof(xfs_dir2_leaf_entry_t)); count * sizeof(xfs_dir2_leaf_entry_t));
xfs_dir3_leaf_log_ents(tp, args->dp, bp_d, xfs_dir3_leaf_log_ents(args, bp_d, start_d, start_d + count - 1);
start_d, start_d + count - 1);
/* /*
* If there are source entries after the ones we copied, * If there are source entries after the ones we copied,
@ -895,8 +899,7 @@ xfs_dir3_leafn_moveents(
if (start_s + count < shdr->count) { if (start_s + count < shdr->count) {
memmove(&sents[start_s], &sents[start_s + count], memmove(&sents[start_s], &sents[start_s + count],
count * sizeof(xfs_dir2_leaf_entry_t)); count * sizeof(xfs_dir2_leaf_entry_t));
xfs_dir3_leaf_log_ents(tp, args->dp, bp_s, xfs_dir3_leaf_log_ents(args, bp_s, start_s, start_s + count - 1);
start_s, start_s + count - 1);
} }
/* /*
@ -1032,8 +1035,8 @@ xfs_dir2_leafn_rebalance(
/* log the changes made when moving the entries */ /* log the changes made when moving the entries */
dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1); dp->d_ops->leaf_hdr_to_disk(leaf1, &hdr1);
dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2); dp->d_ops->leaf_hdr_to_disk(leaf2, &hdr2);
xfs_dir3_leaf_log_header(args->trans, dp, blk1->bp); xfs_dir3_leaf_log_header(args, blk1->bp);
xfs_dir3_leaf_log_header(args->trans, dp, blk2->bp); xfs_dir3_leaf_log_header(args, blk2->bp);
xfs_dir3_leaf_check(dp, blk1->bp); xfs_dir3_leaf_check(dp, blk1->bp);
xfs_dir3_leaf_check(dp, blk2->bp); xfs_dir3_leaf_check(dp, blk2->bp);
@ -1076,7 +1079,6 @@ xfs_dir3_data_block_free(
struct xfs_buf *fbp, struct xfs_buf *fbp,
int longest) int longest)
{ {
struct xfs_trans *tp = args->trans;
int logfree = 0; int logfree = 0;
__be16 *bests; __be16 *bests;
struct xfs_dir3_icfree_hdr freehdr; struct xfs_dir3_icfree_hdr freehdr;
@ -1090,7 +1092,7 @@ xfs_dir3_data_block_free(
* value. * value.
*/ */
bests[findex] = cpu_to_be16(longest); bests[findex] = cpu_to_be16(longest);
xfs_dir2_free_log_bests(tp, dp, fbp, findex, findex); xfs_dir2_free_log_bests(args, fbp, findex, findex);
return 0; return 0;
} }
@ -1118,7 +1120,7 @@ xfs_dir3_data_block_free(
} }
dp->d_ops->free_hdr_to_disk(free, &freehdr); dp->d_ops->free_hdr_to_disk(free, &freehdr);
xfs_dir2_free_log_header(tp, dp, fbp); xfs_dir2_free_log_header(args, fbp);
/* /*
* If there are no useful entries left in the block, get rid of the * If there are no useful entries left in the block, get rid of the
@ -1142,7 +1144,7 @@ xfs_dir3_data_block_free(
/* Log the free entry that changed, unless we got rid of it. */ /* Log the free entry that changed, unless we got rid of it. */
if (logfree) if (logfree)
xfs_dir2_free_log_bests(tp, dp, fbp, findex, findex); xfs_dir2_free_log_bests(args, fbp, findex, findex);
return 0; return 0;
} }
@ -1193,9 +1195,9 @@ xfs_dir2_leafn_remove(
/* /*
* Extract the data block and offset from the entry. * Extract the data block and offset from the entry.
*/ */
db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
ASSERT(dblk->blkno == db); ASSERT(dblk->blkno == db);
off = xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)); off = xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address));
ASSERT(dblk->index == off); ASSERT(dblk->index == off);
/* /*
@ -1204,10 +1206,10 @@ xfs_dir2_leafn_remove(
*/ */
leafhdr.stale++; leafhdr.stale++;
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
xfs_dir3_leaf_log_header(tp, dp, bp); xfs_dir3_leaf_log_header(args, bp);
lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
xfs_dir3_leaf_log_ents(tp, dp, bp, index, index); xfs_dir3_leaf_log_ents(args, bp, index, index);
/* /*
* Make the data entry free. Keep track of the longest freespace * Make the data entry free. Keep track of the longest freespace
@ -1219,7 +1221,7 @@ xfs_dir2_leafn_remove(
bf = dp->d_ops->data_bestfree_p(hdr); bf = dp->d_ops->data_bestfree_p(hdr);
longest = be16_to_cpu(bf[0].length); longest = be16_to_cpu(bf[0].length);
needlog = needscan = 0; needlog = needscan = 0;
xfs_dir2_data_make_free(tp, dp, dbp, off, xfs_dir2_data_make_free(args, dbp, off,
dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
/* /*
* Rescan the data block freespaces for bestfree. * Rescan the data block freespaces for bestfree.
@ -1228,7 +1230,7 @@ xfs_dir2_leafn_remove(
if (needscan) if (needscan)
xfs_dir2_data_freescan(dp, hdr, &needlog); xfs_dir2_data_freescan(dp, hdr, &needlog);
if (needlog) if (needlog)
xfs_dir2_data_log_header(tp, dp, dbp); xfs_dir2_data_log_header(args, dbp);
xfs_dir3_data_check(dp, dbp); xfs_dir3_data_check(dp, dbp);
/* /*
* If the longest data block freespace changes, need to update * If the longest data block freespace changes, need to update
@ -1245,8 +1247,9 @@ xfs_dir2_leafn_remove(
* Convert the data block number to a free block, * Convert the data block number to a free block,
* read in the free block. * read in the free block.
*/ */
fdb = dp->d_ops->db_to_fdb(mp, db); fdb = dp->d_ops->db_to_fdb(args->geo, db);
error = xfs_dir2_free_read(tp, dp, xfs_dir2_db_to_da(mp, fdb), error = xfs_dir2_free_read(tp, dp,
xfs_dir2_db_to_da(args->geo, fdb),
&fbp); &fbp);
if (error) if (error)
return error; return error;
@ -1255,20 +1258,21 @@ xfs_dir2_leafn_remove(
{ {
struct xfs_dir3_icfree_hdr freehdr; struct xfs_dir3_icfree_hdr freehdr;
dp->d_ops->free_hdr_from_disk(&freehdr, free); dp->d_ops->free_hdr_from_disk(&freehdr, free);
ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(mp) * ASSERT(freehdr.firstdb == dp->d_ops->free_max_bests(args->geo) *
(fdb - XFS_DIR2_FREE_FIRSTDB(mp))); (fdb - xfs_dir2_byte_to_db(args->geo,
XFS_DIR2_FREE_OFFSET)));
} }
#endif #endif
/* /*
* Calculate which entry we need to fix. * Calculate which entry we need to fix.
*/ */
findex = dp->d_ops->db_to_fdindex(mp, db); findex = dp->d_ops->db_to_fdindex(args->geo, db);
longest = be16_to_cpu(bf[0].length); longest = be16_to_cpu(bf[0].length);
/* /*
* If the data block is now empty we can get rid of it * If the data block is now empty we can get rid of it
* (usually). * (usually).
*/ */
if (longest == mp->m_dirblksize - if (longest == args->geo->blksize -
dp->d_ops->data_entry_offset) { dp->d_ops->data_entry_offset) {
/* /*
* Try to punch out the data block. * Try to punch out the data block.
@ -1303,7 +1307,7 @@ xfs_dir2_leafn_remove(
*/ */
*rval = (dp->d_ops->leaf_hdr_size + *rval = (dp->d_ops->leaf_hdr_size +
(uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) < (uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) <
mp->m_dir_magicpct; args->geo->magicpct;
return 0; return 0;
} }
@ -1336,7 +1340,7 @@ xfs_dir2_leafn_split(
/* /*
* Initialize the new leaf block. * Initialize the new leaf block.
*/ */
error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(mp, blkno), error = xfs_dir3_leaf_get_buf(args, xfs_dir2_da_to_db(args->geo, blkno),
&newblk->bp, XFS_DIR2_LEAFN_MAGIC); &newblk->bp, XFS_DIR2_LEAFN_MAGIC);
if (error) if (error)
return error; return error;
@ -1410,7 +1414,7 @@ xfs_dir2_leafn_toosmall(
count = leafhdr.count - leafhdr.stale; count = leafhdr.count - leafhdr.stale;
bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]); bytes = dp->d_ops->leaf_hdr_size + count * sizeof(ents[0]);
if (bytes > (state->blocksize >> 1)) { if (bytes > (state->args->geo->blksize >> 1)) {
/* /*
* Blk over 50%, don't try to join. * Blk over 50%, don't try to join.
*/ */
@ -1463,7 +1467,8 @@ xfs_dir2_leafn_toosmall(
* Count bytes in the two blocks combined. * Count bytes in the two blocks combined.
*/ */
count = leafhdr.count - leafhdr.stale; count = leafhdr.count - leafhdr.stale;
bytes = state->blocksize - (state->blocksize >> 2); bytes = state->args->geo->blksize -
(state->args->geo->blksize >> 2);
leaf = bp->b_addr; leaf = bp->b_addr;
dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf); dp->d_ops->leaf_hdr_from_disk(&hdr2, leaf);
@ -1560,8 +1565,8 @@ xfs_dir2_leafn_unbalance(
/* log the changes made when moving the entries */ /* log the changes made when moving the entries */
dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr); dp->d_ops->leaf_hdr_to_disk(save_leaf, &savehdr);
dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr); dp->d_ops->leaf_hdr_to_disk(drop_leaf, &drophdr);
xfs_dir3_leaf_log_header(args->trans, dp, save_blk->bp); xfs_dir3_leaf_log_header(args, save_blk->bp);
xfs_dir3_leaf_log_header(args->trans, dp, drop_blk->bp); xfs_dir3_leaf_log_header(args, drop_blk->bp);
xfs_dir3_leaf_check(dp, save_blk->bp); xfs_dir3_leaf_check(dp, save_blk->bp);
xfs_dir3_leaf_check(dp, drop_blk->bp); xfs_dir3_leaf_check(dp, drop_blk->bp);
@ -1587,8 +1592,6 @@ xfs_dir2_node_addname(
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_dirblksize;
state->node_ents = state->mp->m_dir_node_ents;
/* /*
* Look up the name. We're not supposed to find it, but * Look up the name. We're not supposed to find it, but
* this gives us the insertion point. * this gives us the insertion point.
@ -1729,7 +1732,7 @@ xfs_dir2_node_addname_int(
if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK))) if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK)))
return error; return error;
lastfbno = xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo); lastfbno = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo);
fbno = ifbno; fbno = ifbno;
} }
/* /*
@ -1747,7 +1750,8 @@ xfs_dir2_node_addname_int(
* us a freespace block to start with. * us a freespace block to start with.
*/ */
if (++fbno == 0) if (++fbno == 0)
fbno = XFS_DIR2_FREE_FIRSTDB(mp); fbno = xfs_dir2_byte_to_db(args->geo,
XFS_DIR2_FREE_OFFSET);
/* /*
* If it's ifbno we already looked at it. * If it's ifbno we already looked at it.
*/ */
@ -1765,8 +1769,8 @@ xfs_dir2_node_addname_int(
* to avoid it. * to avoid it.
*/ */
error = xfs_dir2_free_try_read(tp, dp, error = xfs_dir2_free_try_read(tp, dp,
xfs_dir2_db_to_da(mp, fbno), xfs_dir2_db_to_da(args->geo, fbno),
&fbp); &fbp);
if (error) if (error)
return error; return error;
if (!fbp) if (!fbp)
@ -1834,10 +1838,10 @@ xfs_dir2_node_addname_int(
* Get the freespace block corresponding to the data block * Get the freespace block corresponding to the data block
* that was just allocated. * that was just allocated.
*/ */
fbno = dp->d_ops->db_to_fdb(mp, dbno); fbno = dp->d_ops->db_to_fdb(args->geo, dbno);
error = xfs_dir2_free_try_read(tp, dp, error = xfs_dir2_free_try_read(tp, dp,
xfs_dir2_db_to_da(mp, fbno), xfs_dir2_db_to_da(args->geo, fbno),
&fbp); &fbp);
if (error) if (error)
return error; return error;
@ -1851,12 +1855,13 @@ xfs_dir2_node_addname_int(
if (error) if (error)
return error; return error;
if (unlikely(dp->d_ops->db_to_fdb(mp, dbno) != fbno)) { if (dp->d_ops->db_to_fdb(args->geo, dbno) != fbno) {
xfs_alert(mp, xfs_alert(mp,
"%s: dir ino %llu needed freesp block %lld for\n" "%s: dir ino %llu needed freesp block %lld for\n"
" data block %lld, got %lld ifbno %llu lastfbno %d", " data block %lld, got %lld ifbno %llu lastfbno %d",
__func__, (unsigned long long)dp->i_ino, __func__, (unsigned long long)dp->i_ino,
(long long)dp->d_ops->db_to_fdb(mp, dbno), (long long)dp->d_ops->db_to_fdb(
args->geo, dbno),
(long long)dbno, (long long)fbno, (long long)dbno, (long long)fbno,
(unsigned long long)ifbno, lastfbno); (unsigned long long)ifbno, lastfbno);
if (fblk) { if (fblk) {
@ -1877,7 +1882,7 @@ xfs_dir2_node_addname_int(
/* /*
* Get a buffer for the new block. * Get a buffer for the new block.
*/ */
error = xfs_dir3_free_get_buf(tp, dp, fbno, &fbp); error = xfs_dir3_free_get_buf(args, fbno, &fbp);
if (error) if (error)
return error; return error;
free = fbp->b_addr; free = fbp->b_addr;
@ -1887,8 +1892,10 @@ xfs_dir2_node_addname_int(
/* /*
* Remember the first slot as our empty slot. * Remember the first slot as our empty slot.
*/ */
freehdr.firstdb = (fbno - XFS_DIR2_FREE_FIRSTDB(mp)) * freehdr.firstdb =
dp->d_ops->free_max_bests(mp); (fbno - xfs_dir2_byte_to_db(args->geo,
XFS_DIR2_FREE_OFFSET)) *
dp->d_ops->free_max_bests(args->geo);
} else { } else {
free = fbp->b_addr; free = fbp->b_addr;
bests = dp->d_ops->free_bests_p(free); bests = dp->d_ops->free_bests_p(free);
@ -1898,13 +1905,13 @@ xfs_dir2_node_addname_int(
/* /*
* Set the freespace block index from the data block number. * Set the freespace block index from the data block number.
*/ */
findex = dp->d_ops->db_to_fdindex(mp, dbno); findex = dp->d_ops->db_to_fdindex(args->geo, dbno);
/* /*
* If it's after the end of the current entries in the * If it's after the end of the current entries in the
* freespace block, extend that table. * freespace block, extend that table.
*/ */
if (findex >= freehdr.nvalid) { if (findex >= freehdr.nvalid) {
ASSERT(findex < dp->d_ops->free_max_bests(mp)); ASSERT(findex < dp->d_ops->free_max_bests(args->geo));
freehdr.nvalid = findex + 1; freehdr.nvalid = findex + 1;
/* /*
* Tag new entry so nused will go up. * Tag new entry so nused will go up.
@ -1918,7 +1925,7 @@ xfs_dir2_node_addname_int(
if (bests[findex] == cpu_to_be16(NULLDATAOFF)) { if (bests[findex] == cpu_to_be16(NULLDATAOFF)) {
freehdr.nused++; freehdr.nused++;
dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr); dp->d_ops->free_hdr_to_disk(fbp->b_addr, &freehdr);
xfs_dir2_free_log_header(tp, dp, fbp); xfs_dir2_free_log_header(args, fbp);
} }
/* /*
* Update the real value in the table. * Update the real value in the table.
@ -1943,7 +1950,8 @@ xfs_dir2_node_addname_int(
/* /*
* Read the data block in. * Read the data block in.
*/ */
error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno), error = xfs_dir3_data_read(tp, dp,
xfs_dir2_db_to_da(args->geo, dbno),
-1, &dbp); -1, &dbp);
if (error) if (error)
return error; return error;
@ -1961,7 +1969,7 @@ xfs_dir2_node_addname_int(
/* /*
* Mark the first part of the unused space, inuse for us. * Mark the first part of the unused space, inuse for us.
*/ */
xfs_dir2_data_use_free(tp, dp, dbp, dup, xfs_dir2_data_use_free(args, dbp, dup,
(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length, (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
&needlog, &needscan); &needlog, &needscan);
/* /*
@ -1974,7 +1982,7 @@ xfs_dir2_node_addname_int(
dp->d_ops->data_put_ftype(dep, args->filetype); dp->d_ops->data_put_ftype(dep, args->filetype);
tagp = dp->d_ops->data_entry_tag_p(dep); tagp = dp->d_ops->data_entry_tag_p(dep);
*tagp = cpu_to_be16((char *)dep - (char *)hdr); *tagp = cpu_to_be16((char *)dep - (char *)hdr);
xfs_dir2_data_log_entry(tp, dp, dbp, dep); xfs_dir2_data_log_entry(args, dbp, dep);
/* /*
* Rescan the block for bestfree if needed. * Rescan the block for bestfree if needed.
*/ */
@ -1984,7 +1992,7 @@ xfs_dir2_node_addname_int(
* Log the data block header if needed. * Log the data block header if needed.
*/ */
if (needlog) if (needlog)
xfs_dir2_data_log_header(tp, dp, dbp); xfs_dir2_data_log_header(args, dbp);
/* /*
* If the freespace entry is now wrong, update it. * If the freespace entry is now wrong, update it.
*/ */
@ -1997,7 +2005,7 @@ xfs_dir2_node_addname_int(
* Log the freespace entry if needed. * Log the freespace entry if needed.
*/ */
if (logfree) if (logfree)
xfs_dir2_free_log_bests(tp, dp, fbp, findex, findex); xfs_dir2_free_log_bests(args, fbp, findex, findex);
/* /*
* Return the data block and offset in args, then drop the data block. * Return the data block and offset in args, then drop the data block.
*/ */
@ -2028,8 +2036,6 @@ xfs_dir2_node_lookup(
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_dirblksize;
state->node_ents = state->mp->m_dir_node_ents;
/* /*
* Fill in the path to the entry in the cursor. * Fill in the path to the entry in the cursor.
*/ */
@ -2083,8 +2089,6 @@ xfs_dir2_node_removename(
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_dirblksize;
state->node_ents = state->mp->m_dir_node_ents;
/* Look up the entry we're deleting, set up the cursor. */ /* Look up the entry we're deleting, set up the cursor. */
error = xfs_da3_node_lookup_int(state, &rval); error = xfs_da3_node_lookup_int(state, &rval);
@ -2153,8 +2157,6 @@ xfs_dir2_node_replace(
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_dirblksize;
state->node_ents = state->mp->m_dir_node_ents;
inum = args->inumber; inum = args->inumber;
/* /*
* Lookup the entry to change in the btree. * Lookup the entry to change in the btree.
@ -2186,15 +2188,15 @@ xfs_dir2_node_replace(
hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)
((char *)hdr + ((char *)hdr +
xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); xfs_dir2_dataptr_to_off(args->geo,
be32_to_cpu(lep->address)));
ASSERT(inum != be64_to_cpu(dep->inumber)); ASSERT(inum != be64_to_cpu(dep->inumber));
/* /*
* Fill in the new inode number and log the entry. * Fill in the new inode number and log the entry.
*/ */
dep->inumber = cpu_to_be64(inum); dep->inumber = cpu_to_be64(inum);
args->dp->d_ops->data_put_ftype(dep, args->filetype); args->dp->d_ops->data_put_ftype(dep, args->filetype);
xfs_dir2_data_log_entry(args->trans, args->dp, xfs_dir2_data_log_entry(args, state->extrablk.bp, dep);
state->extrablk.bp, dep);
rval = 0; rval = 0;
} }
/* /*
@ -2262,9 +2264,9 @@ xfs_dir2_node_trim_free(
/* /*
* Blow the block away. * Blow the block away.
*/ */
if ((error = error = xfs_dir2_shrink_inode(args,
xfs_dir2_shrink_inode(args, xfs_dir2_da_to_db(mp, (xfs_dablk_t)fo), xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo), bp);
bp))) { if (error) {
/* /*
* Can't fail with ENOSPC since that only happens with no * Can't fail with ENOSPC since that only happens with no
* space reservation, when breaking up an extent into two * space reservation, when breaking up an extent into two

View File

@ -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,
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);

View File

@ -76,26 +76,25 @@ const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
STATIC int STATIC int
xfs_dir2_sf_getdents( xfs_dir2_sf_getdents(
xfs_inode_t *dp, /* incore directory inode */ struct xfs_da_args *args,
struct dir_context *ctx) struct dir_context *ctx)
{ {
int i; /* shortform entry number */ int i; /* shortform entry number */
xfs_mount_t *mp; /* filesystem mount point */ struct xfs_inode *dp = args->dp; /* incore directory inode */
xfs_dir2_dataptr_t off; /* current entry's offset */ xfs_dir2_dataptr_t off; /* current entry's offset */
xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */
xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
xfs_dir2_dataptr_t dot_offset; xfs_dir2_dataptr_t dot_offset;
xfs_dir2_dataptr_t dotdot_offset; xfs_dir2_dataptr_t dotdot_offset;
xfs_ino_t ino; xfs_ino_t ino;
struct xfs_da_geometry *geo = args->geo;
mp = dp->i_mount;
ASSERT(dp->i_df.if_flags & XFS_IFINLINE); ASSERT(dp->i_df.if_flags & XFS_IFINLINE);
/* /*
* Give up if the directory is way too short. * Give up if the directory is way too short.
*/ */
if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) {
ASSERT(XFS_FORCED_SHUTDOWN(mp)); ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount));
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
} }
@ -109,18 +108,18 @@ xfs_dir2_sf_getdents(
/* /*
* If the block number in the offset is out of range, we're done. * If the block number in the offset is out of range, we're done.
*/ */
if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk) if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)
return 0; return 0;
/* /*
* Precalculate offsets for . and .. as we will always need them. * Precalculate offsets for . and .. as we will always need them.
* *
* XXX(hch): the second argument is sometimes 0 and sometimes * XXX(hch): the second argument is sometimes 0 and sometimes
* mp->m_dirdatablk. * geo->datablk
*/ */
dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, dot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
dp->d_ops->data_dot_offset); dp->d_ops->data_dot_offset);
dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, dotdot_offset = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
dp->d_ops->data_dotdot_offset); dp->d_ops->data_dotdot_offset);
/* /*
@ -149,7 +148,7 @@ xfs_dir2_sf_getdents(
for (i = 0; i < sfp->count; i++) { for (i = 0; i < sfp->count; i++) {
__uint8_t filetype; __uint8_t filetype;
off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, off = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
xfs_dir2_sf_get_offset(sfep)); xfs_dir2_sf_get_offset(sfep));
if (ctx->pos > off) { if (ctx->pos > off) {
@ -161,13 +160,13 @@ xfs_dir2_sf_getdents(
filetype = dp->d_ops->sf_get_ftype(sfep); filetype = dp->d_ops->sf_get_ftype(sfep);
ctx->pos = off & 0x7fffffff; ctx->pos = off & 0x7fffffff;
if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
xfs_dir3_get_dtype(mp, filetype))) xfs_dir3_get_dtype(dp->i_mount, filetype)))
return 0; return 0;
sfep = dp->d_ops->sf_nextentry(sfp, sfep); sfep = dp->d_ops->sf_nextentry(sfp, sfep);
} }
ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
0x7fffffff; 0x7fffffff;
return 0; return 0;
} }
@ -176,9 +175,10 @@ xfs_dir2_sf_getdents(
*/ */
STATIC int STATIC int
xfs_dir2_block_getdents( xfs_dir2_block_getdents(
xfs_inode_t *dp, /* incore inode */ struct xfs_da_args *args,
struct dir_context *ctx) struct dir_context *ctx)
{ {
struct xfs_inode *dp = args->dp; /* incore directory inode */
xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_data_hdr_t *hdr; /* block header */
struct xfs_buf *bp; /* buffer for block */ struct xfs_buf *bp; /* buffer for block */
xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_block_tail_t *btp; /* block tail */
@ -186,16 +186,15 @@ xfs_dir2_block_getdents(
xfs_dir2_data_unused_t *dup; /* block unused entry */ xfs_dir2_data_unused_t *dup; /* block unused entry */
char *endptr; /* end of the data entries */ char *endptr; /* end of the data entries */
int error; /* error return value */ int error; /* error return value */
xfs_mount_t *mp; /* filesystem mount point */
char *ptr; /* current data entry */ char *ptr; /* current data entry */
int wantoff; /* starting block offset */ int wantoff; /* starting block offset */
xfs_off_t cook; xfs_off_t cook;
struct xfs_da_geometry *geo = args->geo;
mp = dp->i_mount;
/* /*
* If the block number in the offset is out of range, we're done. * If the block number in the offset is out of range, we're done.
*/ */
if (xfs_dir2_dataptr_to_db(mp, ctx->pos) > mp->m_dirdatablk) if (xfs_dir2_dataptr_to_db(geo, ctx->pos) > geo->datablk)
return 0; return 0;
error = xfs_dir3_block_read(NULL, dp, &bp); error = xfs_dir3_block_read(NULL, dp, &bp);
@ -206,13 +205,13 @@ xfs_dir2_block_getdents(
* Extract the byte offset we start at from the seek pointer. * Extract the byte offset we start at from the seek pointer.
* We'll skip entries before this. * We'll skip entries before this.
*/ */
wantoff = xfs_dir2_dataptr_to_off(mp, ctx->pos); wantoff = xfs_dir2_dataptr_to_off(geo, ctx->pos);
hdr = bp->b_addr; hdr = bp->b_addr;
xfs_dir3_data_check(dp, bp); xfs_dir3_data_check(dp, bp);
/* /*
* Set up values for the loop. * Set up values for the loop.
*/ */
btp = xfs_dir2_block_tail_p(mp, hdr); btp = xfs_dir2_block_tail_p(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);
@ -244,7 +243,7 @@ xfs_dir2_block_getdents(
if ((char *)dep - (char *)hdr < wantoff) if ((char *)dep - (char *)hdr < wantoff)
continue; continue;
cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, cook = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
(char *)dep - (char *)hdr); (char *)dep - (char *)hdr);
ctx->pos = cook & 0x7fffffff; ctx->pos = cook & 0x7fffffff;
@ -254,7 +253,7 @@ xfs_dir2_block_getdents(
*/ */
if (!dir_emit(ctx, (char *)dep->name, dep->namelen, if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
be64_to_cpu(dep->inumber), be64_to_cpu(dep->inumber),
xfs_dir3_get_dtype(mp, filetype))) { xfs_dir3_get_dtype(dp->i_mount, filetype))) {
xfs_trans_brelse(NULL, bp); xfs_trans_brelse(NULL, bp);
return 0; return 0;
} }
@ -264,8 +263,8 @@ xfs_dir2_block_getdents(
* Reached the end of the block. * Reached the end of the block.
* Set the offset to a non-existent block 1 and return. * Set the offset to a non-existent block 1 and return.
*/ */
ctx->pos = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk + 1, 0) & ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) &
0x7fffffff; 0x7fffffff;
xfs_trans_brelse(NULL, bp); xfs_trans_brelse(NULL, bp);
return 0; return 0;
} }
@ -286,13 +285,13 @@ struct xfs_dir2_leaf_map_info {
STATIC int STATIC int
xfs_dir2_leaf_readbuf( xfs_dir2_leaf_readbuf(
struct xfs_inode *dp, struct xfs_da_args *args,
size_t bufsize, size_t bufsize,
struct xfs_dir2_leaf_map_info *mip, struct xfs_dir2_leaf_map_info *mip,
xfs_dir2_off_t *curoff, xfs_dir2_off_t *curoff,
struct xfs_buf **bpp) struct xfs_buf **bpp)
{ {
struct xfs_mount *mp = dp->i_mount; struct xfs_inode *dp = args->dp;
struct xfs_buf *bp = *bpp; struct xfs_buf *bp = *bpp;
struct xfs_bmbt_irec *map = mip->map; struct xfs_bmbt_irec *map = mip->map;
struct blk_plug plug; struct blk_plug plug;
@ -300,6 +299,7 @@ xfs_dir2_leaf_readbuf(
int length; int length;
int i; int i;
int j; int j;
struct xfs_da_geometry *geo = args->geo;
/* /*
* If we have a buffer, we need to release it and * If we have a buffer, we need to release it and
@ -309,12 +309,12 @@ xfs_dir2_leaf_readbuf(
if (bp) { if (bp) {
xfs_trans_brelse(NULL, bp); xfs_trans_brelse(NULL, bp);
bp = NULL; bp = NULL;
mip->map_blocks -= mp->m_dirblkfsbs; mip->map_blocks -= geo->fsbcount;
/* /*
* Loop to get rid of the extents for the * Loop to get rid of the extents for the
* directory block. * directory block.
*/ */
for (i = mp->m_dirblkfsbs; i > 0; ) { for (i = geo->fsbcount; i > 0; ) {
j = min_t(int, map->br_blockcount, i); j = min_t(int, map->br_blockcount, i);
map->br_blockcount -= j; map->br_blockcount -= j;
map->br_startblock += j; map->br_startblock += j;
@ -333,8 +333,7 @@ xfs_dir2_leaf_readbuf(
/* /*
* Recalculate the readahead blocks wanted. * Recalculate the readahead blocks wanted.
*/ */
mip->ra_want = howmany(bufsize + mp->m_dirblksize, mip->ra_want = howmany(bufsize + geo->blksize, (1 << geo->fsblog)) - 1;
mp->m_sb.sb_blocksize) - 1;
ASSERT(mip->ra_want >= 0); ASSERT(mip->ra_want >= 0);
/* /*
@ -342,14 +341,14 @@ xfs_dir2_leaf_readbuf(
* run out of data blocks, get some more mappings. * run out of data blocks, get some more mappings.
*/ */
if (1 + mip->ra_want > mip->map_blocks && if (1 + mip->ra_want > mip->map_blocks &&
mip->map_off < xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET)) { mip->map_off < xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET)) {
/* /*
* Get more bmaps, fill in after the ones * Get more bmaps, fill in after the ones
* we already have in the table. * we already have in the table.
*/ */
mip->nmap = mip->map_size - mip->map_valid; mip->nmap = mip->map_size - mip->map_valid;
error = xfs_bmapi_read(dp, mip->map_off, error = xfs_bmapi_read(dp, mip->map_off,
xfs_dir2_byte_to_da(mp, XFS_DIR2_LEAF_OFFSET) - xfs_dir2_byte_to_da(geo, XFS_DIR2_LEAF_OFFSET) -
mip->map_off, mip->map_off,
&map[mip->map_valid], &mip->nmap, 0); &map[mip->map_valid], &mip->nmap, 0);
@ -370,7 +369,7 @@ xfs_dir2_leaf_readbuf(
i = mip->map_valid + mip->nmap - 1; i = mip->map_valid + mip->nmap - 1;
mip->map_off = map[i].br_startoff + map[i].br_blockcount; mip->map_off = map[i].br_startoff + map[i].br_blockcount;
} else } else
mip->map_off = xfs_dir2_byte_to_da(mp, mip->map_off = xfs_dir2_byte_to_da(geo,
XFS_DIR2_LEAF_OFFSET); XFS_DIR2_LEAF_OFFSET);
/* /*
@ -396,18 +395,18 @@ xfs_dir2_leaf_readbuf(
* No valid mappings, so no more data blocks. * No valid mappings, so no more data blocks.
*/ */
if (!mip->map_valid) { if (!mip->map_valid) {
*curoff = xfs_dir2_da_to_byte(mp, mip->map_off); *curoff = xfs_dir2_da_to_byte(geo, mip->map_off);
goto out; goto out;
} }
/* /*
* Read the directory block starting at the first mapping. * Read the directory block starting at the first mapping.
*/ */
mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff); mip->curdb = xfs_dir2_da_to_db(geo, map->br_startoff);
error = xfs_dir3_data_read(NULL, dp, map->br_startoff, error = xfs_dir3_data_read(NULL, dp, map->br_startoff,
map->br_blockcount >= mp->m_dirblkfsbs ? map->br_blockcount >= geo->fsbcount ?
XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp); XFS_FSB_TO_DADDR(dp->i_mount, map->br_startblock) :
-1, &bp);
/* /*
* Should just skip over the data block instead of giving up. * Should just skip over the data block instead of giving up.
*/ */
@ -419,7 +418,7 @@ xfs_dir2_leaf_readbuf(
* was previously ra. * was previously ra.
*/ */
if (mip->ra_current) if (mip->ra_current)
mip->ra_current -= mp->m_dirblkfsbs; mip->ra_current -= geo->fsbcount;
/* /*
* Do we need more readahead? * Do we need more readahead?
@ -427,16 +426,16 @@ xfs_dir2_leaf_readbuf(
blk_start_plug(&plug); blk_start_plug(&plug);
for (mip->ra_index = mip->ra_offset = i = 0; for (mip->ra_index = mip->ra_offset = i = 0;
mip->ra_want > mip->ra_current && i < mip->map_blocks; mip->ra_want > mip->ra_current && i < mip->map_blocks;
i += mp->m_dirblkfsbs) { i += geo->fsbcount) {
ASSERT(mip->ra_index < mip->map_valid); ASSERT(mip->ra_index < mip->map_valid);
/* /*
* Read-ahead a contiguous directory block. * Read-ahead a contiguous directory block.
*/ */
if (i > mip->ra_current && if (i > mip->ra_current &&
map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) { map[mip->ra_index].br_blockcount >= geo->fsbcount) {
xfs_dir3_data_readahead(dp, xfs_dir3_data_readahead(dp,
map[mip->ra_index].br_startoff + mip->ra_offset, map[mip->ra_index].br_startoff + mip->ra_offset,
XFS_FSB_TO_DADDR(mp, XFS_FSB_TO_DADDR(dp->i_mount,
map[mip->ra_index].br_startblock + map[mip->ra_index].br_startblock +
mip->ra_offset)); mip->ra_offset));
mip->ra_current = i; mip->ra_current = i;
@ -456,12 +455,12 @@ xfs_dir2_leaf_readbuf(
/* /*
* Advance offset through the mapping table. * Advance offset through the mapping table.
*/ */
for (j = 0; j < mp->m_dirblkfsbs; j += length ) { for (j = 0; j < geo->fsbcount; j += length ) {
/* /*
* The rest of this extent but not more than a dir * The rest of this extent but not more than a dir
* block. * block.
*/ */
length = min_t(int, mp->m_dirblkfsbs, length = min_t(int, geo->fsbcount,
map[mip->ra_index].br_blockcount - map[mip->ra_index].br_blockcount -
mip->ra_offset); mip->ra_offset);
mip->ra_offset += length; mip->ra_offset += length;
@ -488,22 +487,23 @@ out:
*/ */
STATIC int STATIC int
xfs_dir2_leaf_getdents( xfs_dir2_leaf_getdents(
xfs_inode_t *dp, /* incore directory inode */ struct xfs_da_args *args,
struct dir_context *ctx, struct dir_context *ctx,
size_t bufsize) size_t bufsize)
{ {
struct xfs_inode *dp = args->dp;
struct xfs_buf *bp = NULL; /* data block buffer */ struct xfs_buf *bp = NULL; /* data block buffer */
xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_hdr_t *hdr; /* data block header */
xfs_dir2_data_entry_t *dep; /* data entry */ xfs_dir2_data_entry_t *dep; /* data entry */
xfs_dir2_data_unused_t *dup; /* unused entry */ xfs_dir2_data_unused_t *dup; /* unused entry */
int error = 0; /* error return value */ int error = 0; /* error return value */
int length; /* temporary length value */ int length; /* temporary length value */
xfs_mount_t *mp; /* filesystem mount point */
int byteoff; /* offset in current block */ int byteoff; /* offset in current block */
xfs_dir2_off_t curoff; /* current overall offset */ xfs_dir2_off_t curoff; /* current overall offset */
xfs_dir2_off_t newoff; /* new curoff after new blk */ xfs_dir2_off_t newoff; /* new curoff after new blk */
char *ptr = NULL; /* pointer to current data */ char *ptr = NULL; /* pointer to current data */
struct xfs_dir2_leaf_map_info *map_info; struct xfs_dir2_leaf_map_info *map_info;
struct xfs_da_geometry *geo = args->geo;
/* /*
* If the offset is at or past the largest allowed value, * If the offset is at or past the largest allowed value,
@ -512,15 +512,12 @@ xfs_dir2_leaf_getdents(
if (ctx->pos >= XFS_DIR2_MAX_DATAPTR) if (ctx->pos >= XFS_DIR2_MAX_DATAPTR)
return 0; return 0;
mp = dp->i_mount;
/* /*
* Set up to bmap a number of blocks based on the caller's * Set up to bmap a number of blocks based on the caller's
* buffer size, the directory block size, and the filesystem * buffer size, the directory block size, and the filesystem
* block size. * block size.
*/ */
length = howmany(bufsize + mp->m_dirblksize, length = howmany(bufsize + geo->blksize, (1 << geo->fsblog));
mp->m_sb.sb_blocksize);
map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) + map_info = kmem_zalloc(offsetof(struct xfs_dir2_leaf_map_info, map) +
(length * sizeof(struct xfs_bmbt_irec)), (length * sizeof(struct xfs_bmbt_irec)),
KM_SLEEP | KM_NOFS); KM_SLEEP | KM_NOFS);
@ -536,8 +533,8 @@ xfs_dir2_leaf_getdents(
* Force this conversion through db so we truncate the offset * Force this conversion through db so we truncate the offset
* down to get the start of the data block. * down to get the start of the data block.
*/ */
map_info->map_off = xfs_dir2_db_to_da(mp, map_info->map_off = xfs_dir2_db_to_da(geo,
xfs_dir2_byte_to_db(mp, curoff)); xfs_dir2_byte_to_db(geo, curoff));
/* /*
* Loop over directory entries until we reach the end offset. * Loop over directory entries until we reach the end offset.
@ -550,9 +547,9 @@ xfs_dir2_leaf_getdents(
* If we have no buffer, or we're off the end of the * If we have no buffer, or we're off the end of the
* current buffer, need to get another one. * current buffer, need to get another one.
*/ */
if (!bp || ptr >= (char *)bp->b_addr + mp->m_dirblksize) { if (!bp || ptr >= (char *)bp->b_addr + geo->blksize) {
error = xfs_dir2_leaf_readbuf(dp, bufsize, map_info, error = xfs_dir2_leaf_readbuf(args, bufsize, map_info,
&curoff, &bp); &curoff, &bp);
if (error || !map_info->map_valid) if (error || !map_info->map_valid)
break; break;
@ -560,7 +557,8 @@ xfs_dir2_leaf_getdents(
/* /*
* Having done a read, we need to set a new offset. * Having done a read, we need to set a new offset.
*/ */
newoff = xfs_dir2_db_off_to_byte(mp, map_info->curdb, 0); newoff = xfs_dir2_db_off_to_byte(geo,
map_info->curdb, 0);
/* /*
* Start of the current block. * Start of the current block.
*/ */
@ -570,7 +568,7 @@ xfs_dir2_leaf_getdents(
* Make sure we're in the right block. * Make sure we're in the right block.
*/ */
else if (curoff > newoff) else if (curoff > newoff)
ASSERT(xfs_dir2_byte_to_db(mp, curoff) == ASSERT(xfs_dir2_byte_to_db(geo, curoff) ==
map_info->curdb); map_info->curdb);
hdr = bp->b_addr; hdr = bp->b_addr;
xfs_dir3_data_check(dp, bp); xfs_dir3_data_check(dp, bp);
@ -578,7 +576,7 @@ xfs_dir2_leaf_getdents(
* Find our position in the block. * Find our position in the block.
*/ */
ptr = (char *)dp->d_ops->data_entry_p(hdr); ptr = (char *)dp->d_ops->data_entry_p(hdr);
byteoff = xfs_dir2_byte_to_off(mp, curoff); byteoff = xfs_dir2_byte_to_off(geo, curoff);
/* /*
* Skip past the header. * Skip past the header.
*/ */
@ -607,10 +605,10 @@ xfs_dir2_leaf_getdents(
* Now set our real offset. * Now set our real offset.
*/ */
curoff = curoff =
xfs_dir2_db_off_to_byte(mp, xfs_dir2_db_off_to_byte(geo,
xfs_dir2_byte_to_db(mp, curoff), xfs_dir2_byte_to_db(geo, curoff),
(char *)ptr - (char *)hdr); (char *)ptr - (char *)hdr);
if (ptr >= (char *)hdr + mp->m_dirblksize) { if (ptr >= (char *)hdr + geo->blksize) {
continue; continue;
} }
} }
@ -637,7 +635,7 @@ xfs_dir2_leaf_getdents(
ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff;
if (!dir_emit(ctx, (char *)dep->name, dep->namelen, if (!dir_emit(ctx, (char *)dep->name, dep->namelen,
be64_to_cpu(dep->inumber), be64_to_cpu(dep->inumber),
xfs_dir3_get_dtype(mp, filetype))) xfs_dir3_get_dtype(dp->i_mount, filetype)))
break; break;
/* /*
@ -667,13 +665,14 @@ xfs_dir2_leaf_getdents(
*/ */
int int
xfs_readdir( xfs_readdir(
xfs_inode_t *dp, struct xfs_inode *dp,
struct dir_context *ctx, struct dir_context *ctx,
size_t bufsize) size_t bufsize)
{ {
int rval; /* return value */ struct xfs_da_args args = { NULL };
int v; /* type-checking value */ int rval;
uint lock_mode; int v;
uint lock_mode;
trace_xfs_readdir(dp); trace_xfs_readdir(dp);
@ -683,15 +682,18 @@ xfs_readdir(
ASSERT(S_ISDIR(dp->i_d.di_mode)); ASSERT(S_ISDIR(dp->i_d.di_mode));
XFS_STATS_INC(xs_dir_getdents); XFS_STATS_INC(xs_dir_getdents);
args.dp = dp;
args.geo = dp->i_mount->m_dir_geo;
lock_mode = xfs_ilock_data_map_shared(dp); lock_mode = xfs_ilock_data_map_shared(dp);
if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
rval = xfs_dir2_sf_getdents(dp, ctx); rval = xfs_dir2_sf_getdents(&args, ctx);
else if ((rval = xfs_dir2_isblock(dp, &v))) else if ((rval = xfs_dir2_isblock(&args, &v)))
; ;
else if (v) else if (v)
rval = xfs_dir2_block_getdents(dp, ctx); rval = xfs_dir2_block_getdents(&args, ctx);
else else
rval = xfs_dir2_leaf_getdents(dp, ctx, bufsize); rval = xfs_dir2_leaf_getdents(&args, ctx, bufsize);
xfs_iunlock(dp, lock_mode); xfs_iunlock(dp, lock_mode);
return rval; return rval;

View File

@ -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(
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(
/* /*
* 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(
/* /*
* 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(
/* 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(
* 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(
/* /*
* 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(
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 */

View File

@ -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(
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 |=

View File

@ -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);

View File

@ -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(
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(
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(
"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)

View File

@ -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 {
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 {
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 {
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

View File

@ -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"

View File

@ -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(
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),

View File

@ -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 @@
* 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 */