xfs: consolidate btree block verification
Add a __xfs_btree_check_block helper that can be called by the scrub code to validate a btree block of any form, and move the duplicate error handling code from xfs_btree_check_sblock and xfs_btree_check_lblock into xfs_btree_check_block and thus remove these two helpers. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
d477f1749f
commit
4ce0c711d9
@ -98,7 +98,7 @@ xfs_btree_check_sblock_siblings(
|
||||
* Check a long btree block header. Return the address of the failing check,
|
||||
* or NULL if everything is ok.
|
||||
*/
|
||||
xfs_failaddr_t
|
||||
static xfs_failaddr_t
|
||||
__xfs_btree_check_lblock(
|
||||
struct xfs_btree_cur *cur,
|
||||
struct xfs_btree_block *block,
|
||||
@ -147,33 +147,11 @@ __xfs_btree_check_lblock(
|
||||
return fa;
|
||||
}
|
||||
|
||||
/* Check a long btree block header. */
|
||||
static int
|
||||
xfs_btree_check_lblock(
|
||||
struct xfs_btree_cur *cur,
|
||||
struct xfs_btree_block *block,
|
||||
int level,
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_mount *mp = cur->bc_mp;
|
||||
xfs_failaddr_t fa;
|
||||
|
||||
fa = __xfs_btree_check_lblock(cur, block, level, bp);
|
||||
if (XFS_IS_CORRUPT(mp, fa != NULL) ||
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) {
|
||||
if (bp)
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check a short btree block header. Return the address of the failing check,
|
||||
* or NULL if everything is ok.
|
||||
*/
|
||||
xfs_failaddr_t
|
||||
static xfs_failaddr_t
|
||||
__xfs_btree_check_sblock(
|
||||
struct xfs_btree_cur *cur,
|
||||
struct xfs_btree_block *block,
|
||||
@ -209,26 +187,28 @@ __xfs_btree_check_sblock(
|
||||
return fa;
|
||||
}
|
||||
|
||||
/* Check a short btree block header. */
|
||||
STATIC int
|
||||
xfs_btree_check_sblock(
|
||||
/*
|
||||
* Internal btree block check.
|
||||
*
|
||||
* Return NULL if the block is ok or the address of the failed check otherwise.
|
||||
*/
|
||||
xfs_failaddr_t
|
||||
__xfs_btree_check_block(
|
||||
struct xfs_btree_cur *cur,
|
||||
struct xfs_btree_block *block,
|
||||
int level,
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_mount *mp = cur->bc_mp;
|
||||
xfs_failaddr_t fa;
|
||||
if (cur->bc_ops->ptr_len == XFS_BTREE_SHORT_PTR_LEN)
|
||||
return __xfs_btree_check_sblock(cur, block, level, bp);
|
||||
return __xfs_btree_check_lblock(cur, block, level, bp);
|
||||
}
|
||||
|
||||
fa = __xfs_btree_check_sblock(cur, block, level, bp);
|
||||
if (XFS_IS_CORRUPT(mp, fa != NULL) ||
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) {
|
||||
if (bp)
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
static inline unsigned int xfs_btree_block_errtag(struct xfs_btree_cur *cur)
|
||||
{
|
||||
if (cur->bc_ops->ptr_len == XFS_BTREE_SHORT_PTR_LEN)
|
||||
return XFS_ERRTAG_BTREE_CHECK_SBLOCK;
|
||||
return XFS_ERRTAG_BTREE_CHECK_LBLOCK;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -241,10 +221,18 @@ xfs_btree_check_block(
|
||||
int level, /* level of the btree block */
|
||||
struct xfs_buf *bp) /* buffer containing block, if any */
|
||||
{
|
||||
if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
|
||||
return xfs_btree_check_lblock(cur, block, level, bp);
|
||||
else
|
||||
return xfs_btree_check_sblock(cur, block, level, bp);
|
||||
struct xfs_mount *mp = cur->bc_mp;
|
||||
xfs_failaddr_t fa;
|
||||
|
||||
fa = __xfs_btree_check_block(cur, block, level, bp);
|
||||
if (XFS_IS_CORRUPT(mp, fa != NULL) ||
|
||||
XFS_TEST_ERROR(false, mp, xfs_btree_block_errtag(cur))) {
|
||||
if (bp)
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -334,15 +334,8 @@ xfs_btree_cur_sizeof(unsigned int nlevels)
|
||||
*/
|
||||
#define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr))
|
||||
|
||||
/*
|
||||
* Internal long and short btree block checks. They return NULL if the
|
||||
* block is ok or the address of the failed check otherwise.
|
||||
*/
|
||||
xfs_failaddr_t __xfs_btree_check_lblock(struct xfs_btree_cur *cur,
|
||||
xfs_failaddr_t __xfs_btree_check_block(struct xfs_btree_cur *cur,
|
||||
struct xfs_btree_block *block, int level, struct xfs_buf *bp);
|
||||
xfs_failaddr_t __xfs_btree_check_sblock(struct xfs_btree_cur *cur,
|
||||
struct xfs_btree_block *block, int level, struct xfs_buf *bp);
|
||||
|
||||
int __xfs_btree_check_ptr(struct xfs_btree_cur *cur,
|
||||
const union xfs_btree_ptr *ptr, int index, int level);
|
||||
|
||||
|
@ -584,7 +584,6 @@ xchk_btree_get_block(
|
||||
struct xfs_btree_block **pblock,
|
||||
struct xfs_buf **pbp)
|
||||
{
|
||||
xfs_failaddr_t failed_at;
|
||||
int error;
|
||||
|
||||
*pblock = NULL;
|
||||
@ -596,13 +595,7 @@ xchk_btree_get_block(
|
||||
return error;
|
||||
|
||||
xfs_btree_get_block(bs->cur, level, pbp);
|
||||
if (bs->cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
|
||||
failed_at = __xfs_btree_check_lblock(bs->cur, *pblock,
|
||||
level, *pbp);
|
||||
else
|
||||
failed_at = __xfs_btree_check_sblock(bs->cur, *pblock,
|
||||
level, *pbp);
|
||||
if (failed_at) {
|
||||
if (__xfs_btree_check_block(bs->cur, *pblock, level, *pbp)) {
|
||||
xchk_btree_set_corrupt(bs->sc, bs->cur, level);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user