mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 02:34:01 +08:00
[XFS] refactor btree validation helpers
Move the various btree validation helpers around in xfs_btree.c so that they are close to each other and in common #ifdef DEBUG sections. Also add a new xfs_btree_check_ptr helper to check a btree ptr that can be either long or short form. Split out from a bigger patch from Dave Chinner with various small changes applied by me. SGI-PV: 985583 SGI-Modid: xfs-linux-melb:xfs-kern:32183a Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Bill O'Donnell <billodo@sgi.com> Signed-off-by: David Chinner <david@fromorbit.com>
This commit is contained in:
parent
b524bfeee2
commit
a23f6ef8ce
@ -80,24 +80,6 @@ xfs_btree_maxrecs(
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Debug routine: check that block header is ok.
|
||||
*/
|
||||
void
|
||||
xfs_btree_check_block(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_btree_block_t *block, /* generic btree block pointer */
|
||||
int level, /* level of the btree block */
|
||||
xfs_buf_t *bp) /* buffer containing block, if any */
|
||||
{
|
||||
if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
|
||||
xfs_btree_check_lblock(cur, (xfs_btree_lblock_t *)block, level,
|
||||
bp);
|
||||
else
|
||||
xfs_btree_check_sblock(cur, (xfs_btree_sblock_t *)block, level,
|
||||
bp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Debug routine: check that keys are in the right order.
|
||||
*/
|
||||
@ -150,65 +132,7 @@ xfs_btree_check_key(
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Checking routine: check that long form block header is ok.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_lblock(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_btree_lblock_t *block, /* btree long form block pointer */
|
||||
int level, /* level of the btree block */
|
||||
xfs_buf_t *bp) /* buffer for block, if any */
|
||||
{
|
||||
int lblock_ok; /* block passes checks */
|
||||
xfs_mount_t *mp; /* file system mount point */
|
||||
|
||||
mp = cur->bc_mp;
|
||||
lblock_ok =
|
||||
be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
|
||||
be16_to_cpu(block->bb_level) == level &&
|
||||
be16_to_cpu(block->bb_numrecs) <=
|
||||
xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
|
||||
block->bb_leftsib &&
|
||||
(be64_to_cpu(block->bb_leftsib) == NULLDFSBNO ||
|
||||
XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) &&
|
||||
block->bb_rightsib &&
|
||||
(be64_to_cpu(block->bb_rightsib) == NULLDFSBNO ||
|
||||
XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib)));
|
||||
if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK,
|
||||
XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
|
||||
if (bp)
|
||||
xfs_buftrace("LBTREE ERROR", bp);
|
||||
XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW,
|
||||
mp);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checking routine: check that (long) pointer is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_lptr(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_dfsbno_t ptr, /* btree block disk address */
|
||||
int level) /* btree block level */
|
||||
{
|
||||
xfs_mount_t *mp; /* file system mount point */
|
||||
|
||||
mp = cur->bc_mp;
|
||||
XFS_WANT_CORRUPTED_RETURN(
|
||||
level > 0 &&
|
||||
ptr != NULLDFSBNO &&
|
||||
XFS_FSB_SANITY_CHECK(mp, ptr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Debug routine: check that records are in the right order.
|
||||
*/
|
||||
@ -268,19 +192,49 @@ xfs_btree_check_rec(
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Checking routine: check that block header is ok.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_lblock(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
struct xfs_btree_lblock *block, /* btree long form block pointer */
|
||||
int level, /* level of the btree block */
|
||||
struct xfs_buf *bp) /* buffer for block, if any */
|
||||
{
|
||||
int lblock_ok; /* block passes checks */
|
||||
struct xfs_mount *mp; /* file system mount point */
|
||||
|
||||
mp = cur->bc_mp;
|
||||
lblock_ok =
|
||||
be32_to_cpu(block->bb_magic) == xfs_magics[cur->bc_btnum] &&
|
||||
be16_to_cpu(block->bb_level) == level &&
|
||||
be16_to_cpu(block->bb_numrecs) <=
|
||||
xfs_btree_maxrecs(cur, (xfs_btree_block_t *)block) &&
|
||||
block->bb_leftsib &&
|
||||
(be64_to_cpu(block->bb_leftsib) == NULLDFSBNO ||
|
||||
XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) &&
|
||||
block->bb_rightsib &&
|
||||
(be64_to_cpu(block->bb_rightsib) == NULLDFSBNO ||
|
||||
XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib)));
|
||||
if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp,
|
||||
XFS_ERRTAG_BTREE_CHECK_LBLOCK,
|
||||
XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
|
||||
if (bp)
|
||||
xfs_buftrace("LBTREE ERROR", bp);
|
||||
XFS_ERROR_REPORT("xfs_btree_check_lblock", XFS_ERRLEVEL_LOW,
|
||||
mp);
|
||||
return XFS_ERROR(EFSCORRUPTED);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_sblock(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_btree_sblock_t *block, /* btree short form block pointer */
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
struct xfs_btree_sblock *block, /* btree short form block pointer */
|
||||
int level, /* level of the btree block */
|
||||
xfs_buf_t *bp) /* buffer containing block */
|
||||
struct xfs_buf *bp) /* buffer containing block */
|
||||
{
|
||||
xfs_buf_t *agbp; /* buffer for ag. freespace struct */
|
||||
xfs_agf_t *agf; /* ag. freespace structure */
|
||||
struct xfs_buf *agbp; /* buffer for ag. freespace struct */
|
||||
struct xfs_agf *agf; /* ag. freespace structure */
|
||||
xfs_agblock_t agflen; /* native ag. freespace length */
|
||||
int sblock_ok; /* block passes checks */
|
||||
|
||||
@ -311,26 +265,78 @@ xfs_btree_check_sblock(
|
||||
}
|
||||
|
||||
/*
|
||||
* Checking routine: check that (short) pointer is ok.
|
||||
* Debug routine: check that block header is ok.
|
||||
*/
|
||||
int
|
||||
xfs_btree_check_block(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
struct xfs_btree_block *block, /* generic btree block pointer */
|
||||
int level, /* level of the btree block */
|
||||
struct xfs_buf *bp) /* buffer containing block, if any */
|
||||
{
|
||||
if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
|
||||
return xfs_btree_check_lblock(cur,
|
||||
(struct xfs_btree_lblock *)block, level, bp);
|
||||
} else {
|
||||
return xfs_btree_check_sblock(cur,
|
||||
(struct xfs_btree_sblock *)block, level, bp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that (long) pointer is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_lptr(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
xfs_dfsbno_t bno, /* btree block disk address */
|
||||
int level) /* btree block level */
|
||||
{
|
||||
XFS_WANT_CORRUPTED_RETURN(
|
||||
level > 0 &&
|
||||
bno != NULLDFSBNO &&
|
||||
XFS_FSB_SANITY_CHECK(cur->bc_mp, bno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that (short) pointer is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_sptr(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_agblock_t ptr, /* btree block disk address */
|
||||
int level) /* btree block level */
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
xfs_agblock_t bno, /* btree block disk address */
|
||||
int level) /* btree block level */
|
||||
{
|
||||
xfs_buf_t *agbp; /* buffer for ag. freespace struct */
|
||||
xfs_agf_t *agf; /* ag. freespace structure */
|
||||
xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks;
|
||||
|
||||
agbp = cur->bc_private.a.agbp;
|
||||
agf = XFS_BUF_TO_AGF(agbp);
|
||||
XFS_WANT_CORRUPTED_RETURN(
|
||||
level > 0 &&
|
||||
ptr != NULLAGBLOCK && ptr != 0 &&
|
||||
ptr < be32_to_cpu(agf->agf_length));
|
||||
bno != NULLAGBLOCK &&
|
||||
bno != 0 &&
|
||||
bno < agblocks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that block ptr is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_ptr(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
union xfs_btree_ptr *ptr, /* btree block disk address */
|
||||
int index, /* offset from ptr to check */
|
||||
int level) /* btree block level */
|
||||
{
|
||||
if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
|
||||
return xfs_btree_check_lptr(cur,
|
||||
be64_to_cpu((&ptr->l)[index]), level);
|
||||
} else {
|
||||
return xfs_btree_check_sptr(cur,
|
||||
be32_to_cpu((&ptr->s)[index]), level);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete the btree cursor.
|
||||
*/
|
||||
|
@ -215,17 +215,70 @@ typedef struct xfs_btree_cur
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Debug routine: check that block header is ok.
|
||||
* Check that long form block header is ok.
|
||||
*/
|
||||
void
|
||||
xfs_btree_check_block(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_btree_block_t *block, /* generic btree block pointer */
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_lblock(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
struct xfs_btree_lblock *block, /* btree long form block pointer */
|
||||
int level, /* level of the btree block */
|
||||
struct xfs_buf *bp); /* buffer containing block, if any */
|
||||
|
||||
/*
|
||||
* Check that short form block header is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_sblock(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
struct xfs_btree_sblock *block, /* btree short form block pointer */
|
||||
int level, /* level of the btree block */
|
||||
struct xfs_buf *bp); /* buffer containing block */
|
||||
|
||||
/*
|
||||
* Check that block header is ok.
|
||||
*/
|
||||
int
|
||||
xfs_btree_check_block(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
struct xfs_btree_block *block, /* generic btree block pointer */
|
||||
int level, /* level of the btree block */
|
||||
struct xfs_buf *bp); /* buffer containing block, if any */
|
||||
|
||||
/*
|
||||
* Check that (long) pointer is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_lptr(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
xfs_dfsbno_t ptr, /* btree block disk address */
|
||||
int level); /* btree block level */
|
||||
|
||||
#define xfs_btree_check_lptr_disk(cur, ptr, level) \
|
||||
xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level)
|
||||
|
||||
|
||||
/*
|
||||
* Check that (short) pointer is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_sptr(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
xfs_agblock_t ptr, /* btree block disk address */
|
||||
int level); /* btree block level */
|
||||
|
||||
/*
|
||||
* Check that (short) pointer is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_ptr(
|
||||
struct xfs_btree_cur *cur, /* btree cursor */
|
||||
union xfs_btree_ptr *ptr, /* btree block disk address */
|
||||
int index, /* offset from ptr to check */
|
||||
int level); /* btree block level */
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/*
|
||||
* Debug routine: check that keys are in the right order.
|
||||
*/
|
||||
@ -244,52 +297,10 @@ xfs_btree_check_rec(
|
||||
void *ar1, /* pointer to left (lower) record */
|
||||
void *ar2); /* pointer to right (higher) record */
|
||||
#else
|
||||
#define xfs_btree_check_block(a,b,c,d)
|
||||
#define xfs_btree_check_key(a,b,c)
|
||||
#define xfs_btree_check_rec(a,b,c)
|
||||
#define xfs_btree_check_key(a, b, c)
|
||||
#define xfs_btree_check_rec(a, b, c)
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* Checking routine: check that long form block header is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_lblock(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_btree_lblock_t *block, /* btree long form block pointer */
|
||||
int level, /* level of the btree block */
|
||||
struct xfs_buf *bp); /* buffer containing block, if any */
|
||||
|
||||
/*
|
||||
* Checking routine: check that (long) pointer is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_lptr(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_dfsbno_t ptr, /* btree block disk address */
|
||||
int level); /* btree block level */
|
||||
|
||||
#define xfs_btree_check_lptr_disk(cur, ptr, level) \
|
||||
xfs_btree_check_lptr(cur, be64_to_cpu(ptr), level)
|
||||
|
||||
/*
|
||||
* Checking routine: check that short form block header is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_sblock(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_btree_sblock_t *block, /* btree short form block pointer */
|
||||
int level, /* level of the btree block */
|
||||
struct xfs_buf *bp); /* buffer containing block */
|
||||
|
||||
/*
|
||||
* Checking routine: check that (short) pointer is ok.
|
||||
*/
|
||||
int /* error (0 or EFSCORRUPTED) */
|
||||
xfs_btree_check_sptr(
|
||||
xfs_btree_cur_t *cur, /* btree cursor */
|
||||
xfs_agblock_t ptr, /* btree block disk address */
|
||||
int level); /* btree block level */
|
||||
|
||||
/*
|
||||
* Delete the btree cursor.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user