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: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
committed by
Darrick J. Wong
parent
163fbbb356
commit
787b0893ad
@@ -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(
|
|||||||
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)
|
|||||||
(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)
|
|||||||
(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 = {
|
|||||||
|
|
||||||
.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 = {
|
|||||||
|
|
||||||
.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 = {
|
|||||||
|
|
||||||
.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 {
|
|||||||
|
|
||||||
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(
|
|||||||
__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(
|
|||||||
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(
|
|||||||
*/
|
*/
|
||||||
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 @@
|
|||||||
* 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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
/* 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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
* 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(
|
|||||||
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(
|
|||||||
*/
|
*/
|
||||||
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(
|
|||||||
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(
|
|||||||
/*
|
/*
|
||||||
* 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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
*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(
|
|||||||
* 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(
|
|||||||
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(
|
|||||||
/*
|
/*
|
||||||
* 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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
*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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
/*
|
/*
|
||||||
* 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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
/*
|
/*
|
||||||
* 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(
|
|||||||
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(
|
|||||||
*/
|
*/
|
||||||
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(
|
|||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
* 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(
|
|||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
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(
|
|||||||
* 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(
|
|||||||
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 {
|
|||||||
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,
|
|||||||
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(
|
|||||||
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(
|
|||||||
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(
|
|||||||
|
|
||||||
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(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
|
|||||||
Reference in New Issue
Block a user