Commit 57982d6c authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
parent fb0793f2
...@@ -242,28 +242,27 @@ xfs_btree_check_block( ...@@ -242,28 +242,27 @@ xfs_btree_check_block(
return xfs_btree_check_sblock(cur, block, level, bp); return xfs_btree_check_sblock(cur, block, level, bp);
} }
/* Check that this long pointer is valid and points within the fs. */ int
bool __xfs_btree_check_ptr(
xfs_btree_check_lptr( struct xfs_btree_cur *cur,
struct xfs_btree_cur *cur, const union xfs_btree_ptr *ptr,
xfs_fsblock_t fsbno, int index,
int level) int level)
{ {
if (level <= 0) if (level <= 0)
return false; return -EFSCORRUPTED;
return xfs_verify_fsbno(cur->bc_mp, fsbno);
}
/* Check that this short pointer is valid and points within the AG. */ if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) {
bool if (!xfs_verify_fsbno(cur->bc_mp,
xfs_btree_check_sptr( be64_to_cpu((&ptr->l)[index])))
struct xfs_btree_cur *cur, return -EFSCORRUPTED;
xfs_agblock_t agbno, } else {
int level) if (!xfs_verify_agbno(cur->bc_ag.pag,
{ be32_to_cpu((&ptr->s)[index])))
if (level <= 0) return -EFSCORRUPTED;
return false; }
return xfs_verify_agbno(cur->bc_ag.pag, agbno);
return 0;
} }
/* /*
...@@ -277,27 +276,26 @@ xfs_btree_check_ptr( ...@@ -277,27 +276,26 @@ xfs_btree_check_ptr(
int index, int index,
int level) int level)
{ {
if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) { int error;
if (xfs_btree_check_lptr(cur, be64_to_cpu((&ptr->l)[index]),
level)) error = __xfs_btree_check_ptr(cur, ptr, index, level);
return 0; if (error) {
xfs_err(cur->bc_mp, 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.", "Inode %llu fork %d: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ino.ip->i_ino, cur->bc_ino.ip->i_ino,
cur->bc_ino.whichfork, cur->bc_ops->name, cur->bc_ino.whichfork, cur->bc_ops->name,
level, index); level, index);
} else { } else {
if (xfs_btree_check_sptr(cur, be32_to_cpu((&ptr->s)[index]), xfs_err(cur->bc_mp,
level))
return 0;
xfs_err(cur->bc_mp,
"AG %u: Corrupt %sbt pointer at level %d index %d.", "AG %u: Corrupt %sbt pointer at level %d index %d.",
cur->bc_ag.pag->pag_agno, cur->bc_ops->name, cur->bc_ag.pag->pag_agno, cur->bc_ops->name,
level, index); level, index);
}
xfs_btree_mark_sick(cur);
} }
xfs_btree_mark_sick(cur); return error;
return -EFSCORRUPTED;
} }
#ifdef DEBUG #ifdef DEBUG
......
...@@ -343,6 +343,9 @@ xfs_failaddr_t __xfs_btree_check_lblock(struct xfs_btree_cur *cur, ...@@ -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, xfs_failaddr_t __xfs_btree_check_sblock(struct xfs_btree_cur *cur,
struct xfs_btree_block *block, int level, struct xfs_buf *bp); 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. * Check that block header is ok.
*/ */
...@@ -353,24 +356,6 @@ xfs_btree_check_block( ...@@ -353,24 +356,6 @@ xfs_btree_check_block(
int level, /* level of the btree block */ int level, /* level of the btree block */
struct xfs_buf *bp); /* buffer containing block, if any */ 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. * Delete the btree cursor.
*/ */
......
...@@ -236,22 +236,18 @@ xchk_btree_ptr_ok( ...@@ -236,22 +236,18 @@ xchk_btree_ptr_ok(
int level, int level,
union xfs_btree_ptr *ptr) union xfs_btree_ptr *ptr)
{ {
bool res;
/* A btree rooted in an inode has no block pointer to the root. */ /* A btree rooted in an inode has no block pointer to the root. */
if (bs->cur->bc_ops->type == XFS_BTREE_TYPE_INODE && if (bs->cur->bc_ops->type == XFS_BTREE_TYPE_INODE &&
level == bs->cur->bc_nlevels) level == bs->cur->bc_nlevels)
return true; return true;
/* Otherwise, check the pointers. */ /* Otherwise, check the pointers. */
if (bs->cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) if (__xfs_btree_check_ptr(bs->cur, ptr, 0, level)) {
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)
xchk_btree_set_corrupt(bs->sc, bs->cur, 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. */ /* Check that a btree block's sibling matches what we expect it. */
......
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