xfs: refactor btree node scrubbing
Break up xchk_da_btree_entry and handle looking up leaf node entries in the attr / dir callbacks, so that only the generic node handling is left in the common core code. Note that the checks for the crc enabled blocks are removed, as the scrubbing code already remaps the magic numbers earlier. 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:
parent
b16be56187
commit
649d9d98c6
|
@ -398,15 +398,14 @@ out:
|
||||||
STATIC int
|
STATIC int
|
||||||
xchk_xattr_rec(
|
xchk_xattr_rec(
|
||||||
struct xchk_da_btree *ds,
|
struct xchk_da_btree *ds,
|
||||||
int level,
|
int level)
|
||||||
void *rec)
|
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = ds->state->mp;
|
struct xfs_mount *mp = ds->state->mp;
|
||||||
struct xfs_attr_leaf_entry *ent = rec;
|
struct xfs_da_state_blk *blk = &ds->state->path.blk[level];
|
||||||
struct xfs_da_state_blk *blk;
|
|
||||||
struct xfs_attr_leaf_name_local *lentry;
|
struct xfs_attr_leaf_name_local *lentry;
|
||||||
struct xfs_attr_leaf_name_remote *rentry;
|
struct xfs_attr_leaf_name_remote *rentry;
|
||||||
struct xfs_buf *bp;
|
struct xfs_buf *bp;
|
||||||
|
struct xfs_attr_leaf_entry *ent;
|
||||||
xfs_dahash_t calc_hash;
|
xfs_dahash_t calc_hash;
|
||||||
xfs_dahash_t hash;
|
xfs_dahash_t hash;
|
||||||
int nameidx;
|
int nameidx;
|
||||||
|
@ -414,7 +413,9 @@ xchk_xattr_rec(
|
||||||
unsigned int badflags;
|
unsigned int badflags;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
blk = &ds->state->path.blk[level];
|
ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
|
||||||
|
|
||||||
|
ent = xfs_attr3_leaf_entryp(blk->bp->b_addr) + blk->index;
|
||||||
|
|
||||||
/* Check the whole block, if necessary. */
|
/* Check the whole block, if necessary. */
|
||||||
error = xchk_xattr_block(ds, level);
|
error = xchk_xattr_block(ds, level);
|
||||||
|
|
|
@ -77,40 +77,17 @@ xchk_da_set_corrupt(
|
||||||
__return_address);
|
__return_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find an entry at a certain level in a da btree. */
|
static struct xfs_da_node_entry *
|
||||||
STATIC void *
|
xchk_da_btree_node_entry(
|
||||||
xchk_da_btree_entry(
|
|
||||||
struct xchk_da_btree *ds,
|
struct xchk_da_btree *ds,
|
||||||
int level,
|
int level)
|
||||||
int rec)
|
|
||||||
{
|
{
|
||||||
char *ents;
|
struct xfs_da_state_blk *blk = &ds->state->path.blk[level];
|
||||||
struct xfs_da_state_blk *blk;
|
|
||||||
void *baddr;
|
|
||||||
|
|
||||||
/* Dispatch the entry finding function. */
|
ASSERT(blk->magic == XFS_DA_NODE_MAGIC);
|
||||||
blk = &ds->state->path.blk[level];
|
|
||||||
baddr = blk->bp->b_addr;
|
|
||||||
switch (blk->magic) {
|
|
||||||
case XFS_ATTR_LEAF_MAGIC:
|
|
||||||
case XFS_ATTR3_LEAF_MAGIC:
|
|
||||||
ents = (char *)xfs_attr3_leaf_entryp(baddr);
|
|
||||||
return ents + (rec * sizeof(struct xfs_attr_leaf_entry));
|
|
||||||
case XFS_DIR2_LEAFN_MAGIC:
|
|
||||||
case XFS_DIR3_LEAFN_MAGIC:
|
|
||||||
ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr);
|
|
||||||
return ents + (rec * sizeof(struct xfs_dir2_leaf_entry));
|
|
||||||
case XFS_DIR2_LEAF1_MAGIC:
|
|
||||||
case XFS_DIR3_LEAF1_MAGIC:
|
|
||||||
ents = (char *)ds->dargs.dp->d_ops->leaf_ents_p(baddr);
|
|
||||||
return ents + (rec * sizeof(struct xfs_dir2_leaf_entry));
|
|
||||||
case XFS_DA_NODE_MAGIC:
|
|
||||||
case XFS_DA3_NODE_MAGIC:
|
|
||||||
ents = (char *)ds->dargs.dp->d_ops->node_tree_p(baddr);
|
|
||||||
return ents + (rec * sizeof(struct xfs_da_node_entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return (void *)ds->dargs.dp->d_ops->node_tree_p(blk->bp->b_addr) +
|
||||||
|
(blk->index * sizeof(struct xfs_da_node_entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scrub a da btree hash (key). */
|
/* Scrub a da btree hash (key). */
|
||||||
|
@ -120,7 +97,6 @@ xchk_da_btree_hash(
|
||||||
int level,
|
int level,
|
||||||
__be32 *hashp)
|
__be32 *hashp)
|
||||||
{
|
{
|
||||||
struct xfs_da_state_blk *blks;
|
|
||||||
struct xfs_da_node_entry *entry;
|
struct xfs_da_node_entry *entry;
|
||||||
xfs_dahash_t hash;
|
xfs_dahash_t hash;
|
||||||
xfs_dahash_t parent_hash;
|
xfs_dahash_t parent_hash;
|
||||||
|
@ -135,8 +111,7 @@ xchk_da_btree_hash(
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Is this hash no larger than the parent hash? */
|
/* Is this hash no larger than the parent hash? */
|
||||||
blks = ds->state->path.blk;
|
entry = xchk_da_btree_node_entry(ds, level - 1);
|
||||||
entry = xchk_da_btree_entry(ds, level - 1, blks[level - 1].index);
|
|
||||||
parent_hash = be32_to_cpu(entry->hashval);
|
parent_hash = be32_to_cpu(entry->hashval);
|
||||||
if (parent_hash < hash)
|
if (parent_hash < hash)
|
||||||
xchk_da_set_corrupt(ds, level);
|
xchk_da_set_corrupt(ds, level);
|
||||||
|
@ -479,7 +454,6 @@ xchk_da_btree(
|
||||||
struct xfs_mount *mp = sc->mp;
|
struct xfs_mount *mp = sc->mp;
|
||||||
struct xfs_da_state_blk *blks;
|
struct xfs_da_state_blk *blks;
|
||||||
struct xfs_da_node_entry *key;
|
struct xfs_da_node_entry *key;
|
||||||
void *rec;
|
|
||||||
xfs_dablk_t blkno;
|
xfs_dablk_t blkno;
|
||||||
int level;
|
int level;
|
||||||
int error;
|
int error;
|
||||||
|
@ -537,9 +511,7 @@ xchk_da_btree(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dispatch record scrubbing. */
|
/* Dispatch record scrubbing. */
|
||||||
rec = xchk_da_btree_entry(&ds, level,
|
error = scrub_fn(&ds, level);
|
||||||
blks[level].index);
|
|
||||||
error = scrub_fn(&ds, level, rec);
|
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
if (xchk_should_terminate(sc, &error) ||
|
if (xchk_should_terminate(sc, &error) ||
|
||||||
|
@ -561,7 +533,7 @@ xchk_da_btree(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hashes in order for scrub? */
|
/* Hashes in order for scrub? */
|
||||||
key = xchk_da_btree_entry(&ds, level, blks[level].index);
|
key = xchk_da_btree_node_entry(&ds, level);
|
||||||
error = xchk_da_btree_hash(&ds, level, &key->hashval);
|
error = xchk_da_btree_hash(&ds, level, &key->hashval);
|
||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -28,8 +28,7 @@ struct xchk_da_btree {
|
||||||
int tree_level;
|
int tree_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds,
|
typedef int (*xchk_da_btree_rec_fn)(struct xchk_da_btree *ds, int level);
|
||||||
int level, void *rec);
|
|
||||||
|
|
||||||
/* Check for da btree operation errors. */
|
/* Check for da btree operation errors. */
|
||||||
bool xchk_da_process_error(struct xchk_da_btree *ds, int level, int *error);
|
bool xchk_da_process_error(struct xchk_da_btree *ds, int level, int *error);
|
||||||
|
|
|
@ -182,14 +182,14 @@ out:
|
||||||
STATIC int
|
STATIC int
|
||||||
xchk_dir_rec(
|
xchk_dir_rec(
|
||||||
struct xchk_da_btree *ds,
|
struct xchk_da_btree *ds,
|
||||||
int level,
|
int level)
|
||||||
void *rec)
|
|
||||||
{
|
{
|
||||||
|
struct xfs_da_state_blk *blk = &ds->state->path.blk[level];
|
||||||
struct xfs_mount *mp = ds->state->mp;
|
struct xfs_mount *mp = ds->state->mp;
|
||||||
struct xfs_dir2_leaf_entry *ent = rec;
|
|
||||||
struct xfs_inode *dp = ds->dargs.dp;
|
struct xfs_inode *dp = ds->dargs.dp;
|
||||||
struct xfs_dir2_data_entry *dent;
|
struct xfs_dir2_data_entry *dent;
|
||||||
struct xfs_buf *bp;
|
struct xfs_buf *bp;
|
||||||
|
struct xfs_dir2_leaf_entry *ent;
|
||||||
char *p, *endp;
|
char *p, *endp;
|
||||||
xfs_ino_t ino;
|
xfs_ino_t ino;
|
||||||
xfs_dablk_t rec_bno;
|
xfs_dablk_t rec_bno;
|
||||||
|
@ -201,6 +201,12 @@ xchk_dir_rec(
|
||||||
unsigned int tag;
|
unsigned int tag;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC ||
|
||||||
|
blk->magic == XFS_DIR2_LEAFN_MAGIC);
|
||||||
|
|
||||||
|
ent = (void *)ds->dargs.dp->d_ops->leaf_ents_p(blk->bp->b_addr) +
|
||||||
|
(blk->index * sizeof(struct xfs_dir2_leaf_entry));
|
||||||
|
|
||||||
/* 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);
|
||||||
if (error)
|
if (error)
|
||||||
|
|
Loading…
Reference in New Issue