Commit 787b0893 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong

xfs: add an entries pointer to struct xfs_dir3_icleaf_hdr

All callers of the ->node_tree_p dir operation already have a struct
xfs_dir3_icleaf_hdr from a previous call to xfs_da_leaf_hdr_from_disk at
hand, or just need slight changes to the calling conventions to do so.
Add a pointer to the entries to struct xfs_dir3_icleaf_hdr to clean up
this pattern.  To make this possible the xfs_dir3_leaf_log_ents function
grow a new argument to pass the xfs_dir3_icleaf_hdr that call callers
already have, and xfs_dir2_leaf_lookup_int returns the
xfs_dir3_icleaf_hdr to the callers so that they can later use it.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 163fbbb3
...@@ -640,15 +640,14 @@ xfs_da3_root_split( ...@@ -640,15 +640,14 @@ xfs_da3_root_split(
xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF); xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DA_NODE_BUF);
} else { } else {
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
struct xfs_dir2_leaf_entry *ents;
leaf = (xfs_dir2_leaf_t *)oldroot; leaf = (xfs_dir2_leaf_t *)oldroot;
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
ents = dp->d_ops->leaf_ents_p(leaf);
ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
size = (int)((char *)&ents[leafhdr.count] - (char *)leaf); size = (int)((char *)&leafhdr.ents[leafhdr.count] -
(char *)leaf);
level = 0; level = 0;
/* /*
...@@ -2297,7 +2296,7 @@ xfs_da3_swap_lastblock( ...@@ -2297,7 +2296,7 @@ xfs_da3_swap_lastblock(
dead_leaf2 = (xfs_dir2_leaf_t *)dead_info; dead_leaf2 = (xfs_dir2_leaf_t *)dead_info;
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr,
dead_leaf2); dead_leaf2);
ents = dp->d_ops->leaf_ents_p(dead_leaf2); ents = leafhdr.ents;
dead_level = 0; dead_level = 0;
dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval); dead_hash = be32_to_cpu(ents[leafhdr.count - 1].hashval);
} else { } else {
......
...@@ -411,12 +411,6 @@ xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo) ...@@ -411,12 +411,6 @@ xfs_dir2_max_leaf_ents(struct xfs_da_geometry *geo)
(uint)sizeof(struct xfs_dir2_leaf_entry); (uint)sizeof(struct xfs_dir2_leaf_entry);
} }
static struct xfs_dir2_leaf_entry *
xfs_dir2_leaf_ents_p(struct xfs_dir2_leaf *lp)
{
return lp->__ents;
}
static int static int
xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo) xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
{ {
...@@ -424,12 +418,6 @@ xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo) ...@@ -424,12 +418,6 @@ xfs_dir3_max_leaf_ents(struct xfs_da_geometry *geo)
(uint)sizeof(struct xfs_dir2_leaf_entry); (uint)sizeof(struct xfs_dir2_leaf_entry);
} }
static struct xfs_dir2_leaf_entry *
xfs_dir3_leaf_ents_p(struct xfs_dir2_leaf *lp)
{
return ((struct xfs_dir3_leaf *)lp)->__ents;
}
/* /*
* Directory free space block operations * Directory free space block operations
*/ */
...@@ -584,7 +572,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = { ...@@ -584,7 +572,6 @@ static const struct xfs_dir_ops xfs_dir2_ops = {
.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
.leaf_max_ents = xfs_dir2_max_leaf_ents, .leaf_max_ents = xfs_dir2_max_leaf_ents,
.leaf_ents_p = xfs_dir2_leaf_ents_p,
.free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
...@@ -627,7 +614,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = { ...@@ -627,7 +614,6 @@ static const struct xfs_dir_ops xfs_dir2_ftype_ops = {
.leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr), .leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr),
.leaf_max_ents = xfs_dir2_max_leaf_ents, .leaf_max_ents = xfs_dir2_max_leaf_ents,
.leaf_ents_p = xfs_dir2_leaf_ents_p,
.free_hdr_size = sizeof(struct xfs_dir2_free_hdr), .free_hdr_size = sizeof(struct xfs_dir2_free_hdr),
.free_hdr_to_disk = xfs_dir2_free_hdr_to_disk, .free_hdr_to_disk = xfs_dir2_free_hdr_to_disk,
...@@ -670,7 +656,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = { ...@@ -670,7 +656,6 @@ static const struct xfs_dir_ops xfs_dir3_ops = {
.leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr), .leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr),
.leaf_max_ents = xfs_dir3_max_leaf_ents, .leaf_max_ents = xfs_dir3_max_leaf_ents,
.leaf_ents_p = xfs_dir3_leaf_ents_p,
.free_hdr_size = sizeof(struct xfs_dir3_free_hdr), .free_hdr_size = sizeof(struct xfs_dir3_free_hdr),
.free_hdr_to_disk = xfs_dir3_free_hdr_to_disk, .free_hdr_to_disk = xfs_dir3_free_hdr_to_disk,
......
...@@ -74,8 +74,6 @@ struct xfs_dir_ops { ...@@ -74,8 +74,6 @@ struct xfs_dir_ops {
int leaf_hdr_size; int leaf_hdr_size;
int (*leaf_max_ents)(struct xfs_da_geometry *geo); int (*leaf_max_ents)(struct xfs_da_geometry *geo);
struct xfs_dir2_leaf_entry *
(*leaf_ents_p)(struct xfs_dir2_leaf *lp);
int free_hdr_size; int free_hdr_size;
void (*free_hdr_to_disk)(struct xfs_dir2_free *to, void (*free_hdr_to_disk)(struct xfs_dir2_free *to,
......
...@@ -914,7 +914,6 @@ xfs_dir2_leaf_to_block( ...@@ -914,7 +914,6 @@ xfs_dir2_leaf_to_block(
__be16 *tagp; /* end of entry (tag) */ __be16 *tagp; /* end of entry (tag) */
int to; /* block/leaf to index */ int to; /* block/leaf to index */
xfs_trans_t *tp; /* transaction pointer */ xfs_trans_t *tp; /* transaction pointer */
struct xfs_dir2_leaf_entry *ents;
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
trace_xfs_dir2_leaf_to_block(args); trace_xfs_dir2_leaf_to_block(args);
...@@ -924,7 +923,6 @@ xfs_dir2_leaf_to_block( ...@@ -924,7 +923,6 @@ xfs_dir2_leaf_to_block(
mp = dp->i_mount; mp = dp->i_mount;
leaf = lbp->b_addr; leaf = lbp->b_addr;
xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
ents = dp->d_ops->leaf_ents_p(leaf);
ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC || ASSERT(leafhdr.magic == XFS_DIR2_LEAF1_MAGIC ||
...@@ -1004,9 +1002,10 @@ xfs_dir2_leaf_to_block( ...@@ -1004,9 +1002,10 @@ xfs_dir2_leaf_to_block(
*/ */
lep = xfs_dir2_block_leaf_p(btp); lep = xfs_dir2_block_leaf_p(btp);
for (from = to = 0; from < leafhdr.count; from++) { for (from = to = 0; from < leafhdr.count; from++) {
if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) if (leafhdr.ents[from].address ==
cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
continue; continue;
lep[to++] = ents[from]; lep[to++] = leafhdr.ents[from];
} }
ASSERT(to == be32_to_cpu(btp->count)); ASSERT(to == be32_to_cpu(btp->count));
xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1); xfs_dir2_block_log_leaf(tp, dbp, 0, be32_to_cpu(btp->count) - 1);
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
* Local function declarations. * Local function declarations.
*/ */
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,
struct xfs_dir3_icleaf_hdr *leafhdr);
static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args, static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args,
struct xfs_buf *bp, int first, int last); struct xfs_buf *bp, int first, int last);
static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args, static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args,
...@@ -44,6 +45,7 @@ xfs_dir2_leaf_hdr_from_disk( ...@@ -44,6 +45,7 @@ xfs_dir2_leaf_hdr_from_disk(
to->magic = be16_to_cpu(from3->hdr.info.hdr.magic); to->magic = be16_to_cpu(from3->hdr.info.hdr.magic);
to->count = be16_to_cpu(from3->hdr.count); to->count = be16_to_cpu(from3->hdr.count);
to->stale = be16_to_cpu(from3->hdr.stale); to->stale = be16_to_cpu(from3->hdr.stale);
to->ents = from3->__ents;
ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC || ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC ||
to->magic == XFS_DIR3_LEAFN_MAGIC); to->magic == XFS_DIR3_LEAFN_MAGIC);
...@@ -53,6 +55,7 @@ xfs_dir2_leaf_hdr_from_disk( ...@@ -53,6 +55,7 @@ xfs_dir2_leaf_hdr_from_disk(
to->magic = be16_to_cpu(from->hdr.info.magic); to->magic = be16_to_cpu(from->hdr.info.magic);
to->count = be16_to_cpu(from->hdr.count); to->count = be16_to_cpu(from->hdr.count);
to->stale = be16_to_cpu(from->hdr.stale); to->stale = be16_to_cpu(from->hdr.stale);
to->ents = from->__ents;
ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
to->magic == XFS_DIR2_LEAFN_MAGIC); to->magic == XFS_DIR2_LEAFN_MAGIC);
...@@ -139,7 +142,6 @@ xfs_dir3_leaf_check_int( ...@@ -139,7 +142,6 @@ xfs_dir3_leaf_check_int(
struct xfs_dir3_icleaf_hdr *hdr, struct xfs_dir3_icleaf_hdr *hdr,
struct xfs_dir2_leaf *leaf) struct xfs_dir2_leaf *leaf)
{ {
struct xfs_dir2_leaf_entry *ents;
xfs_dir2_leaf_tail_t *ltp; xfs_dir2_leaf_tail_t *ltp;
int stale; int stale;
int i; int i;
...@@ -158,7 +160,6 @@ xfs_dir3_leaf_check_int( ...@@ -158,7 +160,6 @@ xfs_dir3_leaf_check_int(
hdr = &leafhdr; hdr = &leafhdr;
} }
ents = ops->leaf_ents_p(leaf);
ltp = xfs_dir2_leaf_tail_p(geo, leaf); ltp = xfs_dir2_leaf_tail_p(geo, leaf);
/* /*
...@@ -172,17 +173,17 @@ xfs_dir3_leaf_check_int( ...@@ -172,17 +173,17 @@ xfs_dir3_leaf_check_int(
/* Leaves and bests don't overlap in leaf format. */ /* Leaves and bests don't overlap in leaf format. */
if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC || if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
hdr->magic == XFS_DIR3_LEAF1_MAGIC) && hdr->magic == XFS_DIR3_LEAF1_MAGIC) &&
(char *)&ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp)) (char *)&hdr->ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp))
return __this_address; return __this_address;
/* Check hash value order, count stale entries. */ /* Check hash value order, count stale entries. */
for (i = stale = 0; i < hdr->count; i++) { for (i = stale = 0; i < hdr->count; i++) {
if (i + 1 < hdr->count) { if (i + 1 < hdr->count) {
if (be32_to_cpu(ents[i].hashval) > if (be32_to_cpu(hdr->ents[i].hashval) >
be32_to_cpu(ents[i + 1].hashval)) be32_to_cpu(hdr->ents[i + 1].hashval))
return __this_address; return __this_address;
} }
if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
stale++; stale++;
} }
if (hdr->stale != stale) if (hdr->stale != stale)
...@@ -404,7 +405,6 @@ xfs_dir2_block_to_leaf( ...@@ -404,7 +405,6 @@ xfs_dir2_block_to_leaf(
int needscan; /* need to rescan bestfree */ int needscan; /* need to rescan bestfree */
xfs_trans_t *tp; /* transaction pointer */ xfs_trans_t *tp; /* transaction pointer */
struct xfs_dir2_data_free *bf; struct xfs_dir2_data_free *bf;
struct xfs_dir2_leaf_entry *ents;
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
trace_xfs_dir2_block_to_leaf(args); trace_xfs_dir2_block_to_leaf(args);
...@@ -434,7 +434,6 @@ xfs_dir2_block_to_leaf( ...@@ -434,7 +434,6 @@ xfs_dir2_block_to_leaf(
btp = xfs_dir2_block_tail_p(args->geo, 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);
/* /*
* Set the counts in the leaf header. * Set the counts in the leaf header.
...@@ -449,8 +448,9 @@ xfs_dir2_block_to_leaf( ...@@ -449,8 +448,9 @@ xfs_dir2_block_to_leaf(
* 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(leafhdr.ents, blp,
xfs_dir3_leaf_log_ents(args, lbp, 0, leafhdr.count - 1); be32_to_cpu(btp->count) * sizeof(struct xfs_dir2_leaf_entry));
xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, 0, leafhdr.count - 1);
needscan = 0; needscan = 0;
needlog = 1; needlog = 1;
/* /*
...@@ -665,8 +665,8 @@ xfs_dir2_leaf_addname( ...@@ -665,8 +665,8 @@ 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(args->geo, leaf); ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
ents = dp->d_ops->leaf_ents_p(leaf);
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
ents = leafhdr.ents;
bestsp = xfs_dir2_leaf_bests_p(ltp); bestsp = xfs_dir2_leaf_bests_p(ltp);
length = dp->d_ops->data_entsize(args->namelen); length = dp->d_ops->data_entsize(args->namelen);
...@@ -912,7 +912,7 @@ xfs_dir2_leaf_addname( ...@@ -912,7 +912,7 @@ xfs_dir2_leaf_addname(
*/ */
xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
xfs_dir3_leaf_log_header(args, lbp); xfs_dir3_leaf_log_header(args, lbp);
xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh); xfs_dir3_leaf_log_ents(args, &leafhdr, 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;
...@@ -932,7 +932,6 @@ xfs_dir3_leaf_compact( ...@@ -932,7 +932,6 @@ xfs_dir3_leaf_compact(
xfs_dir2_leaf_t *leaf; /* leaf structure */ xfs_dir2_leaf_t *leaf; /* leaf structure */
int loglow; /* first leaf entry to log */ int loglow; /* first leaf entry to log */
int to; /* target leaf index */ int to; /* target leaf index */
struct xfs_dir2_leaf_entry *ents;
struct xfs_inode *dp = args->dp; struct xfs_inode *dp = args->dp;
leaf = bp->b_addr; leaf = bp->b_addr;
...@@ -942,9 +941,9 @@ xfs_dir3_leaf_compact( ...@@ -942,9 +941,9 @@ xfs_dir3_leaf_compact(
/* /*
* Compress out the stale entries in place. * Compress out the stale entries in place.
*/ */
ents = dp->d_ops->leaf_ents_p(leaf);
for (from = to = 0, loglow = -1; from < leafhdr->count; from++) { for (from = to = 0, loglow = -1; from < leafhdr->count; from++) {
if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) if (leafhdr->ents[from].address ==
cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
continue; continue;
/* /*
* Only actually copy the entries that are different. * Only actually copy the entries that are different.
...@@ -952,7 +951,7 @@ xfs_dir3_leaf_compact( ...@@ -952,7 +951,7 @@ xfs_dir3_leaf_compact(
if (from > to) { if (from > to) {
if (loglow == -1) if (loglow == -1)
loglow = to; loglow = to;
ents[to] = ents[from]; leafhdr->ents[to] = leafhdr->ents[from];
} }
to++; to++;
} }
...@@ -966,7 +965,7 @@ xfs_dir3_leaf_compact( ...@@ -966,7 +965,7 @@ xfs_dir3_leaf_compact(
xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, leafhdr); xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, leafhdr);
xfs_dir3_leaf_log_header(args, bp); xfs_dir3_leaf_log_header(args, bp);
if (loglow != -1) if (loglow != -1)
xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1); xfs_dir3_leaf_log_ents(args, leafhdr, bp, loglow, to - 1);
} }
/* /*
...@@ -1095,6 +1094,7 @@ xfs_dir3_leaf_log_bests( ...@@ -1095,6 +1094,7 @@ xfs_dir3_leaf_log_bests(
void void
xfs_dir3_leaf_log_ents( xfs_dir3_leaf_log_ents(
struct xfs_da_args *args, struct xfs_da_args *args,
struct xfs_dir3_icleaf_hdr *hdr,
struct xfs_buf *bp, struct xfs_buf *bp,
int first, int first,
int last) int last)
...@@ -1102,16 +1102,14 @@ xfs_dir3_leaf_log_ents( ...@@ -1102,16 +1102,14 @@ xfs_dir3_leaf_log_ents(
xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */ xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */
xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */
struct xfs_dir2_leaf *leaf = bp->b_addr; struct xfs_dir2_leaf *leaf = bp->b_addr;
struct xfs_dir2_leaf_entry *ents;
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));
ents = args->dp->d_ops->leaf_ents_p(leaf); firstlep = &hdr->ents[first];
firstlep = &ents[first]; lastlep = &hdr->ents[last];
lastlep = &ents[last];
xfs_trans_log_buf(args->trans, bp, xfs_trans_log_buf(args->trans, bp,
(uint)((char *)firstlep - (char *)leaf), (uint)((char *)firstlep - (char *)leaf),
(uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
...@@ -1173,28 +1171,27 @@ xfs_dir2_leaf_lookup( ...@@ -1173,28 +1171,27 @@ xfs_dir2_leaf_lookup(
int error; /* error return code */ int error; /* error return code */
int index; /* found entry index */ int index; /* found entry index */
struct xfs_buf *lbp; /* leaf buffer */ struct xfs_buf *lbp; /* leaf buffer */
xfs_dir2_leaf_t *leaf; /* leaf structure */
xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */
xfs_trans_t *tp; /* transaction pointer */ xfs_trans_t *tp; /* transaction pointer */
struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr;
trace_xfs_dir2_leaf_lookup(args); trace_xfs_dir2_leaf_lookup(args);
/* /*
* Look up name in the leaf block, returning both buffers and index. * Look up name in the leaf block, returning both buffers and index.
*/ */
if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr);
if (error)
return error; return error;
}
tp = args->trans; tp = args->trans;
dp = args->dp; dp = args->dp;
xfs_dir3_leaf_check(dp, lbp); xfs_dir3_leaf_check(dp, lbp);
leaf = lbp->b_addr;
ents = dp->d_ops->leaf_ents_p(leaf);
/* /*
* Get to the leaf entry and contained data entry address. * Get to the leaf entry and contained data entry address.
*/ */
lep = &ents[index]; lep = &leafhdr.ents[index];
/* /*
* Point to the data entry. * Point to the data entry.
...@@ -1224,7 +1221,8 @@ xfs_dir2_leaf_lookup_int( ...@@ -1224,7 +1221,8 @@ xfs_dir2_leaf_lookup_int(
xfs_da_args_t *args, /* operation arguments */ xfs_da_args_t *args, /* operation arguments */
struct xfs_buf **lbpp, /* out: leaf buffer */ struct xfs_buf **lbpp, /* out: leaf buffer */
int *indexp, /* out: index in leaf block */ int *indexp, /* out: index in leaf block */
struct xfs_buf **dbpp) /* out: data buffer */ struct xfs_buf **dbpp, /* out: data buffer */
struct xfs_dir3_icleaf_hdr *leafhdr)
{ {
xfs_dir2_db_t curdb = -1; /* current data block number */ xfs_dir2_db_t curdb = -1; /* current data block number */
struct xfs_buf *dbp = NULL; /* data buffer */ struct xfs_buf *dbp = NULL; /* data buffer */
...@@ -1240,8 +1238,6 @@ xfs_dir2_leaf_lookup_int( ...@@ -1240,8 +1238,6 @@ xfs_dir2_leaf_lookup_int(
xfs_trans_t *tp; /* transaction pointer */ xfs_trans_t *tp; /* transaction pointer */
xfs_dir2_db_t cidb = -1; /* case match data block no. */ xfs_dir2_db_t cidb = -1; /* case match data block no. */
enum xfs_dacmp cmp; /* name compare result */ enum xfs_dacmp cmp; /* name compare result */
struct xfs_dir2_leaf_entry *ents;
struct xfs_dir3_icleaf_hdr leafhdr;
dp = args->dp; dp = args->dp;
tp = args->trans; tp = args->trans;
...@@ -1254,8 +1250,7 @@ xfs_dir2_leaf_lookup_int( ...@@ -1254,8 +1250,7 @@ xfs_dir2_leaf_lookup_int(
*lbpp = lbp; *lbpp = lbp;
leaf = lbp->b_addr; leaf = lbp->b_addr;
xfs_dir3_leaf_check(dp, lbp); xfs_dir3_leaf_check(dp, lbp);
ents = dp->d_ops->leaf_ents_p(leaf); xfs_dir2_leaf_hdr_from_disk(mp, leafhdr, leaf);
xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
/* /*
* Look for the first leaf entry with our hash value. * Look for the first leaf entry with our hash value.
...@@ -1265,8 +1260,9 @@ xfs_dir2_leaf_lookup_int( ...@@ -1265,8 +1260,9 @@ xfs_dir2_leaf_lookup_int(
* Loop over all the entries with the right hash value * Loop over all the entries with the right hash value
* looking to match the name. * looking to match the name.
*/ */
for (lep = &ents[index]; for (lep = &leafhdr->ents[index];
index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; index < leafhdr->count &&
be32_to_cpu(lep->hashval) == args->hashval;
lep++, index++) { lep++, index++) {
/* /*
* Skip over stale leaf entries. * Skip over stale leaf entries.
...@@ -1372,7 +1368,6 @@ xfs_dir2_leaf_removename( ...@@ -1372,7 +1368,6 @@ xfs_dir2_leaf_removename(
int needscan; /* need to rescan data frees */ int needscan; /* need to rescan data frees */
xfs_dir2_data_off_t oldbest; /* old value of best free */ xfs_dir2_data_off_t oldbest; /* old value of best free */
struct xfs_dir2_data_free *bf; /* bestfree table */ struct xfs_dir2_data_free *bf; /* bestfree table */
struct xfs_dir2_leaf_entry *ents;
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
trace_xfs_dir2_leaf_removename(args); trace_xfs_dir2_leaf_removename(args);
...@@ -1380,20 +1375,20 @@ xfs_dir2_leaf_removename( ...@@ -1380,20 +1375,20 @@ xfs_dir2_leaf_removename(
/* /*
* Lookup the leaf entry, get the leaf and data blocks read in. * Lookup the leaf entry, get the leaf and data blocks read in.
*/ */
if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr);
if (error)
return error; return error;
}
dp = args->dp; dp = args->dp;
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);
bf = dp->d_ops->data_bestfree_p(hdr); bf = dp->d_ops->data_bestfree_p(hdr);
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
ents = dp->d_ops->leaf_ents_p(leaf);
/* /*
* 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 = &leafhdr.ents[index];
db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address)); db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
dep = (xfs_dir2_data_entry_t *)((char *)hdr + dep = (xfs_dir2_data_entry_t *)((char *)hdr +
xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address))); xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
...@@ -1419,7 +1414,7 @@ xfs_dir2_leaf_removename( ...@@ -1419,7 +1414,7 @@ xfs_dir2_leaf_removename(
xfs_dir3_leaf_log_header(args, 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(args, lbp, index, index); xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, index, index);
/* /*
* Scan the freespace in the data block again if necessary, * Scan the freespace in the data block again if necessary,
...@@ -1508,26 +1503,24 @@ xfs_dir2_leaf_replace( ...@@ -1508,26 +1503,24 @@ xfs_dir2_leaf_replace(
int error; /* error return code */ int error; /* error return code */
int index; /* index of leaf entry */ int index; /* index of leaf entry */
struct xfs_buf *lbp; /* leaf buffer */ struct xfs_buf *lbp; /* leaf buffer */
xfs_dir2_leaf_t *leaf; /* leaf structure */
xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */
xfs_trans_t *tp; /* transaction pointer */ xfs_trans_t *tp; /* transaction pointer */
struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr;
trace_xfs_dir2_leaf_replace(args); trace_xfs_dir2_leaf_replace(args);
/* /*
* Look up the entry. * Look up the entry.
*/ */
if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr);
if (error)
return error; return error;
}
dp = args->dp; dp = args->dp;
leaf = lbp->b_addr;
ents = dp->d_ops->leaf_ents_p(leaf);
/* /*
* Point to the leaf entry, get data address from it. * Point to the leaf entry, get data address from it.
*/ */
lep = &ents[index]; lep = &leafhdr.ents[index];
/* /*
* Point to the data entry. * Point to the data entry.
*/ */
...@@ -1561,21 +1554,17 @@ xfs_dir2_leaf_search_hash( ...@@ -1561,21 +1554,17 @@ xfs_dir2_leaf_search_hash(
xfs_dahash_t hashwant; /* hash value looking for */ xfs_dahash_t hashwant; /* hash value looking for */
int high; /* high leaf index */ int high; /* high leaf index */
int low; /* low leaf index */ int low; /* low leaf index */
xfs_dir2_leaf_t *leaf; /* leaf structure */
xfs_dir2_leaf_entry_t *lep; /* leaf entry */ xfs_dir2_leaf_entry_t *lep; /* leaf entry */
int mid=0; /* current leaf index */ int mid=0; /* current leaf index */
struct xfs_dir2_leaf_entry *ents;
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
leaf = lbp->b_addr; xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, lbp->b_addr);
ents = args->dp->d_ops->leaf_ents_p(leaf);
xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, leaf);
/* /*
* Note, the table cannot be empty, so we have to go through the loop. * Note, the table cannot be empty, so we have to go through the loop.
* Binary search the leaf entries looking for our hash value. * Binary search the leaf entries looking for our hash value.
*/ */
for (lep = ents, low = 0, high = leafhdr.count - 1, for (lep = leafhdr.ents, low = 0, high = leafhdr.count - 1,
hashwant = args->hashval; hashwant = args->hashval;
low <= high; ) { low <= high; ) {
mid = (low + high) >> 1; mid = (low + high) >> 1;
......
...@@ -441,7 +441,7 @@ xfs_dir2_leafn_add( ...@@ -441,7 +441,7 @@ xfs_dir2_leafn_add(
trace_xfs_dir2_leafn_add(args, index); trace_xfs_dir2_leafn_add(args, index);
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
ents = dp->d_ops->leaf_ents_p(leaf); ents = leafhdr.ents;
/* /*
* Quick check just to make sure we are not going to index * Quick check just to make sure we are not going to index
...@@ -499,7 +499,7 @@ xfs_dir2_leafn_add( ...@@ -499,7 +499,7 @@ xfs_dir2_leafn_add(
xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr);
xfs_dir3_leaf_log_header(args, bp); xfs_dir3_leaf_log_header(args, bp);
xfs_dir3_leaf_log_ents(args, bp, lfloglow, lfloghigh); xfs_dir3_leaf_log_ents(args, &leafhdr, bp, lfloglow, lfloghigh);
xfs_dir3_leaf_check(dp, bp); xfs_dir3_leaf_check(dp, bp);
return 0; return 0;
} }
...@@ -534,11 +534,9 @@ xfs_dir2_leaf_lasthash( ...@@ -534,11 +534,9 @@ xfs_dir2_leaf_lasthash(
struct xfs_buf *bp, /* leaf buffer */ struct xfs_buf *bp, /* leaf buffer */
int *count) /* count of entries in leaf */ int *count) /* count of entries in leaf */
{ {
struct xfs_dir2_leaf *leaf = bp->b_addr;
struct xfs_dir2_leaf_entry *ents;
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, bp->b_addr);
ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
leafhdr.magic == XFS_DIR3_LEAFN_MAGIC || leafhdr.magic == XFS_DIR3_LEAFN_MAGIC ||
...@@ -549,9 +547,7 @@ xfs_dir2_leaf_lasthash( ...@@ -549,9 +547,7 @@ xfs_dir2_leaf_lasthash(
*count = leafhdr.count; *count = leafhdr.count;
if (!leafhdr.count) if (!leafhdr.count)
return 0; return 0;
return be32_to_cpu(leafhdr.ents[leafhdr.count - 1].hashval);
ents = dp->d_ops->leaf_ents_p(leaf);
return be32_to_cpu(ents[leafhdr.count - 1].hashval);
} }
/* /*
...@@ -580,7 +576,6 @@ xfs_dir2_leafn_lookup_for_addname( ...@@ -580,7 +576,6 @@ xfs_dir2_leafn_lookup_for_addname(
xfs_dir2_db_t newdb; /* new data block number */ xfs_dir2_db_t newdb; /* new data block number */
xfs_dir2_db_t newfdb; /* new free block number */ xfs_dir2_db_t newfdb; /* new free block number */
xfs_trans_t *tp; /* transaction pointer */ xfs_trans_t *tp; /* transaction pointer */
struct xfs_dir2_leaf_entry *ents;
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
dp = args->dp; dp = args->dp;
...@@ -588,7 +583,6 @@ xfs_dir2_leafn_lookup_for_addname( ...@@ -588,7 +583,6 @@ xfs_dir2_leafn_lookup_for_addname(
mp = dp->i_mount; mp = dp->i_mount;
leaf = bp->b_addr; leaf = bp->b_addr;
xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
ents = dp->d_ops->leaf_ents_p(leaf);
xfs_dir3_leaf_check(dp, bp); xfs_dir3_leaf_check(dp, bp);
ASSERT(leafhdr.count > 0); ASSERT(leafhdr.count > 0);
...@@ -612,7 +606,7 @@ xfs_dir2_leafn_lookup_for_addname( ...@@ -612,7 +606,7 @@ xfs_dir2_leafn_lookup_for_addname(
/* /*
* Loop over leaf entries with the right hash value. * Loop over leaf entries with the right hash value.
*/ */
for (lep = &ents[index]; for (lep = &leafhdr.ents[index];
index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
lep++, index++) { lep++, index++) {
/* /*
...@@ -732,7 +726,6 @@ xfs_dir2_leafn_lookup_for_entry( ...@@ -732,7 +726,6 @@ xfs_dir2_leafn_lookup_for_entry(
xfs_dir2_db_t newdb; /* new data block number */ xfs_dir2_db_t newdb; /* new data block number */
xfs_trans_t *tp; /* transaction pointer */ xfs_trans_t *tp; /* transaction pointer */
enum xfs_dacmp cmp; /* comparison result */ enum xfs_dacmp cmp; /* comparison result */
struct xfs_dir2_leaf_entry *ents;
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
dp = args->dp; dp = args->dp;
...@@ -740,7 +733,6 @@ xfs_dir2_leafn_lookup_for_entry( ...@@ -740,7 +733,6 @@ xfs_dir2_leafn_lookup_for_entry(
mp = dp->i_mount; mp = dp->i_mount;
leaf = bp->b_addr; leaf = bp->b_addr;
xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf);
ents = dp->d_ops->leaf_ents_p(leaf);
xfs_dir3_leaf_check(dp, bp); xfs_dir3_leaf_check(dp, bp);
if (leafhdr.count <= 0) { if (leafhdr.count <= 0) {
...@@ -762,7 +754,7 @@ xfs_dir2_leafn_lookup_for_entry( ...@@ -762,7 +754,7 @@ xfs_dir2_leafn_lookup_for_entry(
/* /*
* Loop over leaf entries with the right hash value. * Loop over leaf entries with the right hash value.
*/ */
for (lep = &ents[index]; for (lep = &leafhdr.ents[index];
index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
lep++, index++) { lep++, index++) {
/* /*
...@@ -917,7 +909,7 @@ xfs_dir3_leafn_moveents( ...@@ -917,7 +909,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(args, bp_d, start_d + count, xfs_dir3_leaf_log_ents(args, dhdr, bp_d, start_d + count,
count + dhdr->count - 1); count + dhdr->count - 1);
} }
/* /*
...@@ -939,7 +931,7 @@ xfs_dir3_leafn_moveents( ...@@ -939,7 +931,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(args, bp_d, start_d, start_d + count - 1); xfs_dir3_leaf_log_ents(args, dhdr, bp_d, 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,
...@@ -948,7 +940,8 @@ xfs_dir3_leafn_moveents( ...@@ -948,7 +940,8 @@ 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(args, bp_s, start_s, start_s + count - 1); xfs_dir3_leaf_log_ents(args, shdr, bp_s, start_s,
start_s + count - 1);
} }
/* /*
...@@ -979,8 +972,8 @@ xfs_dir2_leafn_order( ...@@ -979,8 +972,8 @@ xfs_dir2_leafn_order(
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1);
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2);
ents1 = dp->d_ops->leaf_ents_p(leaf1); ents1 = hdr1.ents;
ents2 = dp->d_ops->leaf_ents_p(leaf2); ents2 = hdr2.ents;
if (hdr1.count > 0 && hdr2.count > 0 && if (hdr1.count > 0 && hdr2.count > 0 &&
(be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) || (be32_to_cpu(ents2[0].hashval) < be32_to_cpu(ents1[0].hashval) ||
...@@ -1032,8 +1025,8 @@ xfs_dir2_leafn_rebalance( ...@@ -1032,8 +1025,8 @@ xfs_dir2_leafn_rebalance(
leaf2 = blk2->bp->b_addr; leaf2 = blk2->bp->b_addr;
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr1, leaf1);
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf2);
ents1 = dp->d_ops->leaf_ents_p(leaf1); ents1 = hdr1.ents;
ents2 = dp->d_ops->leaf_ents_p(leaf2); ents2 = hdr2.ents;
oldsum = hdr1.count + hdr2.count; oldsum = hdr1.count + hdr2.count;
#if defined(DEBUG) || defined(XFS_WARN) #if defined(DEBUG) || defined(XFS_WARN)
...@@ -1221,7 +1214,6 @@ xfs_dir2_leafn_remove( ...@@ -1221,7 +1214,6 @@ xfs_dir2_leafn_remove(
xfs_trans_t *tp; /* transaction pointer */ xfs_trans_t *tp; /* transaction pointer */
struct xfs_dir2_data_free *bf; /* bestfree table */ struct xfs_dir2_data_free *bf; /* bestfree table */
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
struct xfs_dir2_leaf_entry *ents;
trace_xfs_dir2_leafn_remove(args, index); trace_xfs_dir2_leafn_remove(args, index);
...@@ -1229,12 +1221,11 @@ xfs_dir2_leafn_remove( ...@@ -1229,12 +1221,11 @@ xfs_dir2_leafn_remove(
tp = args->trans; tp = args->trans;
leaf = bp->b_addr; leaf = bp->b_addr;
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
ents = dp->d_ops->leaf_ents_p(leaf);
/* /*
* Point to the entry we're removing. * Point to the entry we're removing.
*/ */
lep = &ents[index]; lep = &leafhdr.ents[index];
/* /*
* Extract the data block and offset from the entry. * Extract the data block and offset from the entry.
...@@ -1253,7 +1244,7 @@ xfs_dir2_leafn_remove( ...@@ -1253,7 +1244,7 @@ xfs_dir2_leafn_remove(
xfs_dir3_leaf_log_header(args, 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(args, bp, index, index); xfs_dir3_leaf_log_ents(args, &leafhdr, 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
...@@ -1350,7 +1341,7 @@ xfs_dir2_leafn_remove( ...@@ -1350,7 +1341,7 @@ xfs_dir2_leafn_remove(
* to justify trying to join it with a neighbor. * to justify trying to join it with a neighbor.
*/ */
*rval = (dp->d_ops->leaf_hdr_size + *rval = (dp->d_ops->leaf_hdr_size +
(uint)sizeof(ents[0]) * (leafhdr.count - leafhdr.stale)) < (uint)sizeof(leafhdr.ents) * (leafhdr.count - leafhdr.stale)) <
args->geo->magicpct; args->geo->magicpct;
return 0; return 0;
} }
...@@ -1451,7 +1442,7 @@ xfs_dir2_leafn_toosmall( ...@@ -1451,7 +1442,7 @@ xfs_dir2_leafn_toosmall(
blk = &state->path.blk[state->path.active - 1]; blk = &state->path.blk[state->path.active - 1];
leaf = blk->bp->b_addr; leaf = blk->bp->b_addr;
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf);
ents = dp->d_ops->leaf_ents_p(leaf); ents = leafhdr.ents;
xfs_dir3_leaf_check(dp, blk->bp); xfs_dir3_leaf_check(dp, blk->bp);
count = leafhdr.count - leafhdr.stale; count = leafhdr.count - leafhdr.stale;
...@@ -1514,7 +1505,7 @@ xfs_dir2_leafn_toosmall( ...@@ -1514,7 +1505,7 @@ xfs_dir2_leafn_toosmall(
leaf = bp->b_addr; leaf = bp->b_addr;
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &hdr2, leaf);
ents = dp->d_ops->leaf_ents_p(leaf); ents = hdr2.ents;
count += hdr2.count - hdr2.stale; count += hdr2.count - hdr2.stale;
bytes -= count * sizeof(ents[0]); bytes -= count * sizeof(ents[0]);
...@@ -1578,8 +1569,8 @@ xfs_dir2_leafn_unbalance( ...@@ -1578,8 +1569,8 @@ xfs_dir2_leafn_unbalance(
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &savehdr, save_leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &savehdr, save_leaf);
xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &drophdr, drop_leaf); xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &drophdr, drop_leaf);
sents = dp->d_ops->leaf_ents_p(save_leaf); sents = savehdr.ents;
dents = dp->d_ops->leaf_ents_p(drop_leaf); dents = drophdr.ents;
/* /*
* If there are any stale leaf entries, take this opportunity * If there are any stale leaf entries, take this opportunity
...@@ -2161,8 +2152,6 @@ xfs_dir2_node_replace( ...@@ -2161,8 +2152,6 @@ xfs_dir2_node_replace(
int i; /* btree level */ int i; /* btree level */
xfs_ino_t inum; /* new inode number */ xfs_ino_t inum; /* new inode number */
int ftype; /* new file type */ int ftype; /* new file type */
xfs_dir2_leaf_t *leaf; /* leaf structure */
xfs_dir2_leaf_entry_t *lep; /* leaf entry being changed */
int rval; /* internal return value */ int rval; /* internal return value */
xfs_da_state_t *state; /* btree cursor */ xfs_da_state_t *state; /* btree cursor */
...@@ -2194,16 +2183,17 @@ xfs_dir2_node_replace( ...@@ -2194,16 +2183,17 @@ xfs_dir2_node_replace(
* and locked it. But paranoia is good. * and locked it. But paranoia is good.
*/ */
if (rval == -EEXIST) { if (rval == -EEXIST) {
struct xfs_dir2_leaf_entry *ents; struct xfs_dir3_icleaf_hdr leafhdr;
/* /*
* Find the leaf entry. * Find the leaf entry.
*/ */
blk = &state->path.blk[state->path.active - 1]; blk = &state->path.blk[state->path.active - 1];
ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC); ASSERT(blk->magic == XFS_DIR2_LEAFN_MAGIC);
leaf = blk->bp->b_addr;
ents = args->dp->d_ops->leaf_ents_p(leaf);
lep = &ents[blk->index];
ASSERT(state->extravalid); ASSERT(state->extravalid);
xfs_dir2_leaf_hdr_from_disk(state->mp, &leafhdr,
blk->bp->b_addr);
/* /*
* Point to the data entry. * Point to the data entry.
*/ */
...@@ -2213,7 +2203,7 @@ xfs_dir2_node_replace( ...@@ -2213,7 +2203,7 @@ xfs_dir2_node_replace(
dep = (xfs_dir2_data_entry_t *) dep = (xfs_dir2_data_entry_t *)
((char *)hdr + ((char *)hdr +
xfs_dir2_dataptr_to_off(args->geo, xfs_dir2_dataptr_to_off(args->geo,
be32_to_cpu(lep->address))); be32_to_cpu(leafhdr.ents[blk->index].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.
......
...@@ -18,6 +18,12 @@ struct xfs_dir3_icleaf_hdr { ...@@ -18,6 +18,12 @@ struct xfs_dir3_icleaf_hdr {
uint16_t magic; uint16_t magic;
uint16_t count; uint16_t count;
uint16_t stale; uint16_t stale;
/*
* Pointer to the on-disk format entries, which are behind the
* variable size (v4 vs v5) header in the on-disk block.
*/
struct xfs_dir2_leaf_entry *ents;
}; };
struct xfs_dir3_icfree_hdr { struct xfs_dir3_icfree_hdr {
...@@ -85,7 +91,8 @@ extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr, ...@@ -85,7 +91,8 @@ extern void xfs_dir3_leaf_compact_x1(struct xfs_dir3_icleaf_hdr *leafhdr,
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_da_args *args, extern void xfs_dir3_leaf_log_ents(struct xfs_da_args *args,
struct xfs_buf *bp, int first, int last); struct xfs_dir3_icleaf_hdr *hdr, struct xfs_buf *bp, int first,
int last);
extern void xfs_dir3_leaf_log_header(struct xfs_da_args *args, 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);
......
...@@ -198,14 +198,15 @@ xchk_dir_rec( ...@@ -198,14 +198,15 @@ xchk_dir_rec(
xfs_dir2_dataptr_t ptr; xfs_dir2_dataptr_t ptr;
xfs_dahash_t calc_hash; xfs_dahash_t calc_hash;
xfs_dahash_t hash; xfs_dahash_t hash;
struct xfs_dir3_icleaf_hdr hdr;
unsigned int tag; unsigned int tag;
int error; int error;
ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC || ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC ||
blk->magic == XFS_DIR2_LEAFN_MAGIC); blk->magic == XFS_DIR2_LEAFN_MAGIC);
ent = (void *)ds->dargs.dp->d_ops->leaf_ents_p(blk->bp->b_addr) + xfs_dir2_leaf_hdr_from_disk(mp, &hdr, blk->bp->b_addr);
(blk->index * sizeof(struct xfs_dir2_leaf_entry)); ent = hdr.ents + blk->index;
/* Check the hash of the entry. */ /* Check the hash of the entry. */
error = xchk_da_btree_hash(ds, level, &ent->hashval); error = xchk_da_btree_hash(ds, level, &ent->hashval);
...@@ -484,7 +485,6 @@ xchk_directory_leaf1_bestfree( ...@@ -484,7 +485,6 @@ xchk_directory_leaf1_bestfree(
xfs_dablk_t lblk) xfs_dablk_t lblk)
{ {
struct xfs_dir3_icleaf_hdr leafhdr; struct xfs_dir3_icleaf_hdr leafhdr;
struct xfs_dir2_leaf_entry *ents;
struct xfs_dir2_leaf_tail *ltp; struct xfs_dir2_leaf_tail *ltp;
struct xfs_dir2_leaf *leaf; struct xfs_dir2_leaf *leaf;
struct xfs_buf *dbp; struct xfs_buf *dbp;
...@@ -508,7 +508,6 @@ xchk_directory_leaf1_bestfree( ...@@ -508,7 +508,6 @@ xchk_directory_leaf1_bestfree(
leaf = bp->b_addr; leaf = bp->b_addr;
xfs_dir2_leaf_hdr_from_disk(sc->ip->i_mount, &leafhdr, leaf); xfs_dir2_leaf_hdr_from_disk(sc->ip->i_mount, &leafhdr, leaf);
ents = d_ops->leaf_ents_p(leaf);
ltp = xfs_dir2_leaf_tail_p(geo, leaf); ltp = xfs_dir2_leaf_tail_p(geo, leaf);
bestcount = be32_to_cpu(ltp->bestcount); bestcount = be32_to_cpu(ltp->bestcount);
bestp = xfs_dir2_leaf_bests_p(ltp); bestp = xfs_dir2_leaf_bests_p(ltp);
...@@ -536,18 +535,19 @@ xchk_directory_leaf1_bestfree( ...@@ -536,18 +535,19 @@ xchk_directory_leaf1_bestfree(
} }
/* Leaves and bests don't overlap in leaf format. */ /* Leaves and bests don't overlap in leaf format. */
if ((char *)&ents[leafhdr.count] > (char *)bestp) { if ((char *)&leafhdr.ents[leafhdr.count] > (char *)bestp) {
xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
goto out; goto out;
} }
/* Check hash value order, count stale entries. */ /* Check hash value order, count stale entries. */
for (i = 0; i < leafhdr.count; i++) { for (i = 0; i < leafhdr.count; i++) {
hash = be32_to_cpu(ents[i].hashval); hash = be32_to_cpu(leafhdr.ents[i].hashval);
if (i > 0 && lasthash > hash) if (i > 0 && lasthash > hash)
xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk); xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, lblk);
lasthash = hash; lasthash = hash;
if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) if (leafhdr.ents[i].address ==
cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
stale++; stale++;
} }
if (leafhdr.stale != stale) if (leafhdr.stale != stale)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment