mirror of
https://github.com/torvalds/linux.git
synced 2024-09-20 23:13:00 +00:00
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:
parent
fb0793f206
commit
57982d6c83
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue
Block a user