xfs: consolidate btree ptr checking

Merge xfs_btree_check_sptr and xfs_btree_check_lptr into a single
__xfs_btree_check_ptr that can be shared between xfs_btree_check_ptr
and the scrub code.

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:
Christoph Hellwig 2024-02-22 12:40:54 -08:00 committed by Darrick J. Wong
parent fb0793f206
commit 57982d6c83
3 changed files with 36 additions and 57 deletions

View File

@ -242,28 +242,27 @@ xfs_btree_check_block(
return xfs_btree_check_sblock(cur, block, level, bp);
}
/* Check that this long pointer is valid and points within the fs. */
bool
xfs_btree_check_lptr(
struct xfs_btree_cur *cur,
xfs_fsblock_t fsbno,
int level)
int
__xfs_btree_check_ptr(
struct xfs_btree_cur *cur,
const union xfs_btree_ptr *ptr,
int index,
int level)
{
if (level <= 0)
return false;
return xfs_verify_fsbno(cur->bc_mp, fsbno);
}
return -EFSCORRUPTED;
/* Check that this short pointer is valid and points within the AG. */
bool
xfs_btree_check_sptr(
struct xfs_btree_cur *cur,
xfs_agblock_t agbno,
int level)
{
if (level <= 0)
return false;
return xfs_verify_agbno(cur->bc_ag.pag, agbno);
if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (!xfs_verify_fsbno(cur->bc_mp,
be64_to_cpu((&ptr->l)[index])))
return -EFSCORRUPTED;
} else {
if (!xfs_verify_agbno(cur->bc_ag.pag,
be32_to_cpu((&ptr->s)[index])))
return -EFSCORRUPTED;
}
return 0;
}
/*
@ -277,27 +276,26 @@ xfs_btree_check_ptr(
int index,
int level)
{
if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
if (xfs_btree_check_lptr(cur, be64_to_cpu((&ptr->l)[index]),
level))
return 0;
xfs_err(cur->bc_mp,
int error;
error = __xfs_btree_check_ptr(cur, ptr, index, level);
if (error) {
if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
xfs_err(cur->bc_mp,
"Inode %llu fork %d: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ino.ip->i_ino,
cur->bc_ino.whichfork, cur->bc_ops->name,
level, index);
} else {
if (xfs_btree_check_sptr(cur, be32_to_cpu((&ptr->s)[index]),
level))
return 0;
xfs_err(cur->bc_mp,
} else {
xfs_err(cur->bc_mp,
"AG %u: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ag.pag->pag_agno, cur->bc_ops->name,
level, index);
}
xfs_btree_mark_sick(cur);
}
xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
return error;
}
#ifdef DEBUG

View File

@ -343,6 +343,9 @@ xfs_failaddr_t __xfs_btree_check_lblock(struct xfs_btree_cur *cur,
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);
/*
* Check that block header is ok.
*/
@ -353,24 +356,6 @@ xfs_btree_check_block(
int level, /* level of the btree block */
struct xfs_buf *bp); /* buffer containing block, if any */
/*
* Check that (long) pointer is ok.
*/
bool /* error (0 or EFSCORRUPTED) */
xfs_btree_check_lptr(
struct xfs_btree_cur *cur, /* btree cursor */
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 */
/*
* Delete the btree cursor.
*/

View File

@ -236,22 +236,18 @@ xchk_btree_ptr_ok(
int level,
union xfs_btree_ptr *ptr)
{
bool res;
/* A btree rooted in an inode has no block pointer to the root. */
if (bs->cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
level == bs->cur->bc_nlevels)
return true;
/* Otherwise, check the pointers. */
if (bs->cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
res = xfs_btree_check_lptr(bs->cur, be64_to_cpu(ptr->l), level);
else
res = xfs_btree_check_sptr(bs->cur, be32_to_cpu(ptr->s), level);
if (!res)
if (__xfs_btree_check_ptr(bs->cur, ptr, 0, level)) {
xchk_btree_set_corrupt(bs->sc, bs->cur, level);
return false;
}
return res;
return true;
}
/* Check that a btree block's sibling matches what we expect it. */