Commit f135761a authored by Darrick J. Wong's avatar Darrick J. Wong

xfs: refactor btree pointer checks

Refactor the btree pointer checks so that we can call them from the
scrub code without logging errors to dmesg.  Preserve the existing error
reporting for regular operations.
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 21ec5416
......@@ -646,8 +646,8 @@ xfs_bmap_btree_to_extents(
cbno = be64_to_cpu(*pp);
*logflagsp = 0;
#ifdef DEBUG
if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
return error;
XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
xfs_btree_check_lptr(cur, cbno, 1));
#endif
error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF,
&xfs_bmbt_buf_ops);
......
......@@ -177,59 +177,53 @@ xfs_btree_check_block(
return xfs_btree_check_sblock(cur, block, level, bp);
}
/*
* Check that (long) pointer is ok.
*/
int /* error (0 or EFSCORRUPTED) */
/* Check that this long pointer is valid and points within the fs. */
bool
xfs_btree_check_lptr(
struct xfs_btree_cur *cur, /* btree cursor */
xfs_fsblock_t bno, /* btree block disk address */
int level) /* btree block level */
struct xfs_btree_cur *cur,
xfs_fsblock_t fsbno,
int level)
{
XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
level > 0 &&
bno != NULLFSBLOCK &&
XFS_FSB_SANITY_CHECK(cur->bc_mp, bno));
return 0;
if (level <= 0)
return false;
return xfs_verify_fsbno(cur->bc_mp, fsbno);
}
#ifdef DEBUG
/*
* Check that (short) pointer is ok.
*/
STATIC int /* error (0 or EFSCORRUPTED) */
/* Check that this short pointer is valid and points within the AG. */
bool
xfs_btree_check_sptr(
struct xfs_btree_cur *cur, /* btree cursor */
xfs_agblock_t bno, /* btree block disk address */
int level) /* btree block level */
struct xfs_btree_cur *cur,
xfs_agblock_t agbno,
int level)
{
xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks;
XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
level > 0 &&
bno != NULLAGBLOCK &&
bno != 0 &&
bno < agblocks);
return 0;
if (level <= 0)
return false;
return xfs_verify_agbno(cur->bc_mp, cur->bc_private.a.agno, agbno);
}
#ifdef DEBUG
/*
* Check that block ptr is ok.
* Check that a given (indexed) btree pointer at a certain level of a
* btree is valid and doesn't point past where it should.
*/
STATIC int /* error (0 or EFSCORRUPTED) */
int
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 */
struct xfs_btree_cur *cur,
union xfs_btree_ptr *ptr,
int index,
int level)
{
if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
return xfs_btree_check_lptr(cur,
be64_to_cpu((&ptr->l)[index]), level);
XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
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);
XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
xfs_btree_check_sptr(cur,
be32_to_cpu((&ptr->s)[index]), level));
}
return 0;
}
#endif
......
......@@ -269,10 +269,19 @@ xfs_btree_check_block(
/*
* Check that (long) pointer is ok.
*/
int /* error (0 or EFSCORRUPTED) */
bool /* error (0 or EFSCORRUPTED) */
xfs_btree_check_lptr(
struct xfs_btree_cur *cur, /* btree cursor */
xfs_fsblock_t ptr, /* btree block disk address */
xfs_fsblock_t fsbno, /* btree block disk address */
int level); /* btree block level */
/*
* Check that (short) pointer is ok.
*/
bool /* error (0 or EFSCORRUPTED) */
xfs_btree_check_sptr(
struct xfs_btree_cur *cur, /* btree cursor */
xfs_agblock_t agbno, /* btree block disk address */
int level); /* btree block level */
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment