xfs: vectorise encoding/decoding directory headers
Conversion from on-disk structures to in-core header structures currently relies on magic number checks. If the magic number is wrong, but one of the supported values, we do the wrong thing with the encode/decode operation. Split these functions so that there are discrete operations for the specific directory format we are handling. In doing this, move all the header encode/decode functions to xfs_da_format.c as they are directly manipulating the on-disk format. It should be noted that all the growth in binary size is from xfs_da_format.c - the rest of the code actaully shrinks. text data bss dec hex filename 794490 96802 1096 892388 d9de4 fs/xfs/xfs.o.orig 792986 96802 1096 890884 d9804 fs/xfs/xfs.o.p1 792350 96802 1096 890248 d9588 fs/xfs/xfs.o.p2 789293 96802 1096 887191 d8997 fs/xfs/xfs.o.p3 789005 96802 1096 886903 d8997 fs/xfs/xfs.o.p4 789061 96802 1096 886959 d88af fs/xfs/xfs.o.p5 789733 96802 1096 887631 d8b4f fs/xfs/xfs.o.p6 791421 96802 1096 889319 d91e7 fs/xfs/xfs.o.p7 Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
This commit is contained in:
@@ -64,7 +64,7 @@ xfs_dir3_leaf1_check(
|
||||
struct xfs_dir2_leaf *leaf = bp->b_addr;
|
||||
struct xfs_dir3_icleaf_hdr leafhdr;
|
||||
|
||||
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
|
||||
if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) {
|
||||
struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
|
||||
@@ -79,62 +79,6 @@ xfs_dir3_leaf1_check(
|
||||
#define xfs_dir3_leaf_check(dp, bp)
|
||||
#endif
|
||||
|
||||
void
|
||||
xfs_dir3_leaf_hdr_from_disk(
|
||||
struct xfs_dir3_icleaf_hdr *to,
|
||||
struct xfs_dir2_leaf *from)
|
||||
{
|
||||
if (from->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
|
||||
from->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) {
|
||||
to->forw = be32_to_cpu(from->hdr.info.forw);
|
||||
to->back = be32_to_cpu(from->hdr.info.back);
|
||||
to->magic = be16_to_cpu(from->hdr.info.magic);
|
||||
to->count = be16_to_cpu(from->hdr.count);
|
||||
to->stale = be16_to_cpu(from->hdr.stale);
|
||||
} else {
|
||||
struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from;
|
||||
|
||||
to->forw = be32_to_cpu(hdr3->info.hdr.forw);
|
||||
to->back = be32_to_cpu(hdr3->info.hdr.back);
|
||||
to->magic = be16_to_cpu(hdr3->info.hdr.magic);
|
||||
to->count = be16_to_cpu(hdr3->count);
|
||||
to->stale = be16_to_cpu(hdr3->stale);
|
||||
}
|
||||
|
||||
ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC ||
|
||||
to->magic == XFS_DIR3_LEAF1_MAGIC ||
|
||||
to->magic == XFS_DIR2_LEAFN_MAGIC ||
|
||||
to->magic == XFS_DIR3_LEAFN_MAGIC);
|
||||
}
|
||||
|
||||
void
|
||||
xfs_dir3_leaf_hdr_to_disk(
|
||||
struct xfs_dir2_leaf *to,
|
||||
struct xfs_dir3_icleaf_hdr *from)
|
||||
{
|
||||
ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC ||
|
||||
from->magic == XFS_DIR3_LEAF1_MAGIC ||
|
||||
from->magic == XFS_DIR2_LEAFN_MAGIC ||
|
||||
from->magic == XFS_DIR3_LEAFN_MAGIC);
|
||||
|
||||
if (from->magic == XFS_DIR2_LEAF1_MAGIC ||
|
||||
from->magic == XFS_DIR2_LEAFN_MAGIC) {
|
||||
to->hdr.info.forw = cpu_to_be32(from->forw);
|
||||
to->hdr.info.back = cpu_to_be32(from->back);
|
||||
to->hdr.info.magic = cpu_to_be16(from->magic);
|
||||
to->hdr.count = cpu_to_be16(from->count);
|
||||
to->hdr.stale = cpu_to_be16(from->stale);
|
||||
} else {
|
||||
struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to;
|
||||
|
||||
hdr3->info.hdr.forw = cpu_to_be32(from->forw);
|
||||
hdr3->info.hdr.back = cpu_to_be32(from->back);
|
||||
hdr3->info.hdr.magic = cpu_to_be16(from->magic);
|
||||
hdr3->count = cpu_to_be16(from->count);
|
||||
hdr3->stale = cpu_to_be16(from->stale);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
xfs_dir3_leaf_check_int(
|
||||
struct xfs_mount *mp,
|
||||
@@ -147,6 +91,7 @@ xfs_dir3_leaf_check_int(
|
||||
int stale;
|
||||
int i;
|
||||
const struct xfs_dir_ops *ops;
|
||||
struct xfs_dir3_icleaf_hdr leafhdr;
|
||||
|
||||
/*
|
||||
* we can be passed a null dp here from a verifier, so we need to go the
|
||||
@@ -154,6 +99,11 @@ xfs_dir3_leaf_check_int(
|
||||
*/
|
||||
ops = xfs_dir_get_ops(mp, dp);
|
||||
|
||||
if (!hdr) {
|
||||
ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
hdr = &leafhdr;
|
||||
}
|
||||
|
||||
ents = ops->leaf_ents_p(leaf);
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
|
||||
@@ -198,7 +148,6 @@ xfs_dir3_leaf_verify(
|
||||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
struct xfs_dir2_leaf *leaf = bp->b_addr;
|
||||
struct xfs_dir3_icleaf_hdr leafhdr;
|
||||
|
||||
ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC);
|
||||
|
||||
@@ -220,8 +169,7 @@ xfs_dir3_leaf_verify(
|
||||
return false;
|
||||
}
|
||||
|
||||
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
return xfs_dir3_leaf_check_int(mp, NULL, &leafhdr, leaf);
|
||||
return xfs_dir3_leaf_check_int(mp, NULL, NULL, leaf);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -474,10 +422,10 @@ xfs_dir2_block_to_leaf(
|
||||
/*
|
||||
* Set the counts in the leaf header.
|
||||
*/
|
||||
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
leafhdr.count = be32_to_cpu(btp->count);
|
||||
leafhdr.stale = be32_to_cpu(btp->stale);
|
||||
xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
xfs_dir3_leaf_log_header(tp, dp, lbp);
|
||||
|
||||
/*
|
||||
@@ -706,7 +654,7 @@ xfs_dir2_leaf_addname(
|
||||
leaf = lbp->b_addr;
|
||||
ltp = xfs_dir2_leaf_tail_p(mp, leaf);
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
bestsp = xfs_dir2_leaf_bests_p(ltp);
|
||||
length = dp->d_ops->data_entsize(args->namelen);
|
||||
|
||||
@@ -945,7 +893,7 @@ xfs_dir2_leaf_addname(
|
||||
/*
|
||||
* Log the leaf fields and give up the buffers.
|
||||
*/
|
||||
xfs_dir3_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_ents(tp, dp, lbp, lfloglow, lfloghigh);
|
||||
xfs_dir3_leaf_check(dp, lbp);
|
||||
@@ -968,6 +916,7 @@ xfs_dir3_leaf_compact(
|
||||
int loglow; /* first leaf entry to log */
|
||||
int to; /* target leaf index */
|
||||
struct xfs_dir2_leaf_entry *ents;
|
||||
struct xfs_inode *dp = args->dp;
|
||||
|
||||
leaf = bp->b_addr;
|
||||
if (!leafhdr->stale)
|
||||
@@ -976,7 +925,7 @@ xfs_dir3_leaf_compact(
|
||||
/*
|
||||
* Compress out the stale entries in place.
|
||||
*/
|
||||
ents = args->dp->d_ops->leaf_ents_p(leaf);
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
for (from = to = 0, loglow = -1; from < leafhdr->count; from++) {
|
||||
if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
|
||||
continue;
|
||||
@@ -997,11 +946,10 @@ xfs_dir3_leaf_compact(
|
||||
leafhdr->count -= leafhdr->stale;
|
||||
leafhdr->stale = 0;
|
||||
|
||||
xfs_dir3_leaf_hdr_to_disk(leaf, leafhdr);
|
||||
xfs_dir3_leaf_log_header(args->trans, args->dp, bp);
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr);
|
||||
xfs_dir3_leaf_log_header(args->trans, dp, bp);
|
||||
if (loglow != -1)
|
||||
xfs_dir3_leaf_log_ents(args->trans, args->dp, bp,
|
||||
loglow, to - 1);
|
||||
xfs_dir3_leaf_log_ents(args->trans, dp, bp, loglow, to - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1290,7 +1238,7 @@ xfs_dir2_leaf_lookup_int(
|
||||
leaf = lbp->b_addr;
|
||||
xfs_dir3_leaf_check(dp, lbp);
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
|
||||
/*
|
||||
* Look for the first leaf entry with our hash value.
|
||||
@@ -1425,7 +1373,7 @@ xfs_dir2_leaf_removename(
|
||||
hdr = dbp->b_addr;
|
||||
xfs_dir3_data_check(dp, dbp);
|
||||
bf = dp->d_ops->data_bestfree_p(hdr);
|
||||
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
/*
|
||||
* Point to the leaf entry, use that to point to the data entry.
|
||||
@@ -1449,7 +1397,7 @@ xfs_dir2_leaf_removename(
|
||||
* We just mark the leaf entry stale by putting a null in it.
|
||||
*/
|
||||
leafhdr.stale++;
|
||||
xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
|
||||
xfs_dir3_leaf_log_header(tp, dp, lbp);
|
||||
|
||||
lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
|
||||
@@ -1602,7 +1550,7 @@ xfs_dir2_leaf_search_hash(
|
||||
|
||||
leaf = lbp->b_addr;
|
||||
ents = args->dp->d_ops->leaf_ents_p(leaf);
|
||||
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
args->dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
|
||||
/*
|
||||
* Note, the table cannot be empty, so we have to go through the loop.
|
||||
@@ -1791,7 +1739,7 @@ xfs_dir2_node_to_leaf(
|
||||
return 0;
|
||||
lbp = state->path.blk[0].bp;
|
||||
leaf = lbp->b_addr;
|
||||
xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
|
||||
ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
|
||||
leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);
|
||||
@@ -1803,7 +1751,7 @@ xfs_dir2_node_to_leaf(
|
||||
if (error)
|
||||
return error;
|
||||
free = fbp->b_addr;
|
||||
xfs_dir3_free_hdr_from_disk(&freehdr, free);
|
||||
dp->d_ops->free_hdr_from_disk(&freehdr, free);
|
||||
|
||||
ASSERT(!freehdr.firstdb);
|
||||
|
||||
@@ -1840,7 +1788,7 @@ xfs_dir2_node_to_leaf(
|
||||
memcpy(xfs_dir2_leaf_bests_p(ltp), xfs_dir3_free_bests_p(mp, free),
|
||||
freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
|
||||
|
||||
xfs_dir3_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_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
|
||||
xfs_dir3_leaf_log_tail(tp, lbp);
|
||||
|
Reference in New Issue
Block a user