Commit 169c030a authored by Chandan Babu R's avatar Chandan Babu R

Merge tag 'btree-check-cleanups-6.9_2024-02-23' of...

Merge tag 'btree-check-cleanups-6.9_2024-02-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-6.9-mergeC

xfs: btree check cleanups

Minor cleanups for the btree block pointer checking code.
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandanbabu@kernel.org>

* tag 'btree-check-cleanups-6.9_2024-02-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
  xfs: factor out a __xfs_btree_check_lblock_hdr helper
  xfs: rename btree helpers that depends on the block number representation
  xfs: consolidate btree block verification
  xfs: tighten up validation of root block in inode forks
  xfs: remove the crc variable in __xfs_btree_check_lblock
  xfs: misc cleanups for __xfs_btree_check_sblock
  xfs: consolidate btree ptr checking
  xfs: open code xfs_btree_check_lptr in xfs_bmap_btree_to_extents
  xfs: simplify xfs_btree_check_lblock_siblings
  xfs: simplify xfs_btree_check_sblock_siblings
parents ee138217 79e72304
...@@ -322,7 +322,7 @@ xfs_allocbt_verify( ...@@ -322,7 +322,7 @@ xfs_allocbt_verify(
return __this_address; return __this_address;
if (xfs_has_crc(mp)) { if (xfs_has_crc(mp)) {
fa = xfs_btree_sblock_v5hdr_verify(bp); fa = xfs_btree_agblock_v5hdr_verify(bp);
if (fa) if (fa)
return fa; return fa;
} }
...@@ -362,7 +362,7 @@ xfs_allocbt_verify( ...@@ -362,7 +362,7 @@ xfs_allocbt_verify(
} else if (level >= mp->m_alloc_maxlevels) } else if (level >= mp->m_alloc_maxlevels)
return __this_address; return __this_address;
return xfs_btree_sblock_verify(bp, mp->m_alloc_mxr[level != 0]); return xfs_btree_agblock_verify(bp, mp->m_alloc_mxr[level != 0]);
} }
static void static void
...@@ -371,7 +371,7 @@ xfs_allocbt_read_verify( ...@@ -371,7 +371,7 @@ xfs_allocbt_read_verify(
{ {
xfs_failaddr_t fa; xfs_failaddr_t fa;
if (!xfs_btree_sblock_verify_crc(bp)) if (!xfs_btree_agblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address); xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else { else {
fa = xfs_allocbt_verify(bp); fa = xfs_allocbt_verify(bp);
...@@ -395,7 +395,7 @@ xfs_allocbt_write_verify( ...@@ -395,7 +395,7 @@ xfs_allocbt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa); xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return; return;
} }
xfs_btree_sblock_calc_crc(bp); xfs_btree_agblock_calc_crc(bp);
} }
......
...@@ -568,7 +568,7 @@ xfs_bmap_btree_to_extents( ...@@ -568,7 +568,7 @@ xfs_bmap_btree_to_extents(
pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes); pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes);
cbno = be64_to_cpu(*pp); cbno = be64_to_cpu(*pp);
#ifdef DEBUG #ifdef DEBUG
if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1))) { if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_verify_fsbno(mp, cbno))) {
xfs_btree_mark_sick(cur); xfs_btree_mark_sick(cur);
return -EFSCORRUPTED; return -EFSCORRUPTED;
} }
......
...@@ -420,7 +420,7 @@ xfs_bmbt_verify( ...@@ -420,7 +420,7 @@ xfs_bmbt_verify(
* XXX: need a better way of verifying the owner here. Right now * XXX: need a better way of verifying the owner here. Right now
* just make sure there has been one set. * just make sure there has been one set.
*/ */
fa = xfs_btree_lblock_v5hdr_verify(bp, XFS_RMAP_OWN_UNKNOWN); fa = xfs_btree_fsblock_v5hdr_verify(bp, XFS_RMAP_OWN_UNKNOWN);
if (fa) if (fa)
return fa; return fa;
} }
...@@ -436,7 +436,7 @@ xfs_bmbt_verify( ...@@ -436,7 +436,7 @@ xfs_bmbt_verify(
if (level > max(mp->m_bm_maxlevels[0], mp->m_bm_maxlevels[1])) if (level > max(mp->m_bm_maxlevels[0], mp->m_bm_maxlevels[1]))
return __this_address; return __this_address;
return xfs_btree_lblock_verify(bp, mp->m_bmap_dmxr[level != 0]); return xfs_btree_fsblock_verify(bp, mp->m_bmap_dmxr[level != 0]);
} }
static void static void
...@@ -445,7 +445,7 @@ xfs_bmbt_read_verify( ...@@ -445,7 +445,7 @@ xfs_bmbt_read_verify(
{ {
xfs_failaddr_t fa; xfs_failaddr_t fa;
if (!xfs_btree_lblock_verify_crc(bp)) if (!xfs_btree_fsblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address); xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else { else {
fa = xfs_bmbt_verify(bp); fa = xfs_bmbt_verify(bp);
...@@ -469,7 +469,7 @@ xfs_bmbt_write_verify( ...@@ -469,7 +469,7 @@ xfs_bmbt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa); xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return; return;
} }
xfs_btree_lblock_calc_crc(bp); xfs_btree_fsblock_calc_crc(bp);
} }
const struct xfs_buf_ops xfs_bmbt_buf_ops = { const struct xfs_buf_ops xfs_bmbt_buf_ops = {
......
...@@ -57,10 +57,8 @@ xfs_btree_magic( ...@@ -57,10 +57,8 @@ xfs_btree_magic(
* bytes. * bytes.
*/ */
static inline xfs_failaddr_t static inline xfs_failaddr_t
xfs_btree_check_lblock_siblings( xfs_btree_check_fsblock_siblings(
struct xfs_mount *mp, struct xfs_mount *mp,
struct xfs_btree_cur *cur,
int level,
xfs_fsblock_t fsb, xfs_fsblock_t fsb,
__be64 dsibling) __be64 dsibling)
{ {
...@@ -72,22 +70,14 @@ xfs_btree_check_lblock_siblings( ...@@ -72,22 +70,14 @@ xfs_btree_check_lblock_siblings(
sibling = be64_to_cpu(dsibling); sibling = be64_to_cpu(dsibling);
if (sibling == fsb) if (sibling == fsb)
return __this_address; return __this_address;
if (level >= 0) {
if (!xfs_btree_check_lptr(cur, sibling, level + 1))
return __this_address;
} else {
if (!xfs_verify_fsbno(mp, sibling)) if (!xfs_verify_fsbno(mp, sibling))
return __this_address; return __this_address;
}
return NULL; return NULL;
} }
static inline xfs_failaddr_t static inline xfs_failaddr_t
xfs_btree_check_sblock_siblings( xfs_btree_check_agblock_siblings(
struct xfs_perag *pag, struct xfs_perag *pag,
struct xfs_btree_cur *cur,
int level,
xfs_agblock_t agbno, xfs_agblock_t agbno,
__be32 dsibling) __be32 dsibling)
{ {
...@@ -99,33 +89,21 @@ xfs_btree_check_sblock_siblings( ...@@ -99,33 +89,21 @@ xfs_btree_check_sblock_siblings(
sibling = be32_to_cpu(dsibling); sibling = be32_to_cpu(dsibling);
if (sibling == agbno) if (sibling == agbno)
return __this_address; return __this_address;
if (level >= 0) {
if (!xfs_btree_check_sptr(cur, sibling, level + 1))
return __this_address;
} else {
if (!xfs_verify_agbno(pag, sibling)) if (!xfs_verify_agbno(pag, sibling))
return __this_address; return __this_address;
}
return NULL; return NULL;
} }
/* static xfs_failaddr_t
* Check a long btree block header. Return the address of the failing check, __xfs_btree_check_lblock_hdr(
* or NULL if everything is ok.
*/
xfs_failaddr_t
__xfs_btree_check_lblock(
struct xfs_btree_cur *cur, struct xfs_btree_cur *cur,
struct xfs_btree_block *block, struct xfs_btree_block *block,
int level, int level,
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_mount *mp = cur->bc_mp; struct xfs_mount *mp = cur->bc_mp;
bool crc = xfs_has_crc(mp);
xfs_failaddr_t fa;
xfs_fsblock_t fsb = NULLFSBLOCK;
if (crc) { if (xfs_has_crc(mp)) {
if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid)) if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
return __this_address; return __this_address;
if (block->bb_u.l.bb_blkno != if (block->bb_u.l.bb_blkno !=
...@@ -143,20 +121,15 @@ __xfs_btree_check_lblock( ...@@ -143,20 +121,15 @@ __xfs_btree_check_lblock(
cur->bc_ops->get_maxrecs(cur, level)) cur->bc_ops->get_maxrecs(cur, level))
return __this_address; return __this_address;
if (bp) return NULL;
fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
fa = xfs_btree_check_lblock_siblings(mp, cur, level, fsb,
block->bb_u.l.bb_leftsib);
if (!fa)
fa = xfs_btree_check_lblock_siblings(mp, cur, level, fsb,
block->bb_u.l.bb_rightsib);
return fa;
} }
/* Check a long btree block header. */ /*
static int * Check a long btree block header. Return the address of the failing check,
xfs_btree_check_lblock( * or NULL if everything is ok.
*/
static xfs_failaddr_t
__xfs_btree_check_fsblock(
struct xfs_btree_cur *cur, struct xfs_btree_cur *cur,
struct xfs_btree_block *block, struct xfs_btree_block *block,
int level, int level,
...@@ -164,24 +137,39 @@ xfs_btree_check_lblock( ...@@ -164,24 +137,39 @@ xfs_btree_check_lblock(
{ {
struct xfs_mount *mp = cur->bc_mp; struct xfs_mount *mp = cur->bc_mp;
xfs_failaddr_t fa; xfs_failaddr_t fa;
xfs_fsblock_t fsb;
fa = __xfs_btree_check_lblock(cur, block, level, bp); fa = __xfs_btree_check_lblock_hdr(cur, block, level, bp);
if (XFS_IS_CORRUPT(mp, fa != NULL) || if (fa)
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) { return fa;
if (bp)
trace_xfs_btree_corrupt(bp, _RET_IP_); /*
xfs_btree_mark_sick(cur); * For inode-rooted btrees, the root block sits in the inode fork. In
return -EFSCORRUPTED; * that case bp is NULL, and the block must not have any siblings.
*/
if (!bp) {
if (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK))
return __this_address;
if (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK))
return __this_address;
return NULL;
} }
return 0;
fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
fa = xfs_btree_check_fsblock_siblings(mp, fsb,
block->bb_u.l.bb_leftsib);
if (!fa)
fa = xfs_btree_check_fsblock_siblings(mp, fsb,
block->bb_u.l.bb_rightsib);
return fa;
} }
/* /*
* Check a short btree block header. Return the address of the failing check, * Check a short btree block header. Return the address of the failing check,
* or NULL if everything is ok. * or NULL if everything is ok.
*/ */
xfs_failaddr_t static xfs_failaddr_t
__xfs_btree_check_sblock( __xfs_btree_check_agblock(
struct xfs_btree_cur *cur, struct xfs_btree_cur *cur,
struct xfs_btree_block *block, struct xfs_btree_block *block,
int level, int level,
...@@ -189,15 +177,13 @@ __xfs_btree_check_sblock( ...@@ -189,15 +177,13 @@ __xfs_btree_check_sblock(
{ {
struct xfs_mount *mp = cur->bc_mp; struct xfs_mount *mp = cur->bc_mp;
struct xfs_perag *pag = cur->bc_ag.pag; struct xfs_perag *pag = cur->bc_ag.pag;
bool crc = xfs_has_crc(mp);
xfs_failaddr_t fa; xfs_failaddr_t fa;
xfs_agblock_t agbno = NULLAGBLOCK; xfs_agblock_t agbno;
if (crc) { if (xfs_has_crc(mp)) {
if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
return __this_address; return __this_address;
if (block->bb_u.s.bb_blkno != if (block->bb_u.s.bb_blkno != cpu_to_be64(xfs_buf_daddr(bp)))
cpu_to_be64(bp ? xfs_buf_daddr(bp) : XFS_BUF_DADDR_NULL))
return __this_address; return __this_address;
} }
...@@ -209,37 +195,37 @@ __xfs_btree_check_sblock( ...@@ -209,37 +195,37 @@ __xfs_btree_check_sblock(
cur->bc_ops->get_maxrecs(cur, level)) cur->bc_ops->get_maxrecs(cur, level))
return __this_address; return __this_address;
if (bp)
agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp)); agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
fa = xfs_btree_check_agblock_siblings(pag, agbno,
fa = xfs_btree_check_sblock_siblings(pag, cur, level, agbno,
block->bb_u.s.bb_leftsib); block->bb_u.s.bb_leftsib);
if (!fa) if (!fa)
fa = xfs_btree_check_sblock_siblings(pag, cur, level, agbno, fa = xfs_btree_check_agblock_siblings(pag, agbno,
block->bb_u.s.bb_rightsib); block->bb_u.s.bb_rightsib);
return fa; return fa;
} }
/* Check a short btree block header. */ /*
STATIC int * Internal btree block check.
xfs_btree_check_sblock( *
* 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_cur *cur,
struct xfs_btree_block *block, struct xfs_btree_block *block,
int level, int level,
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_mount *mp = cur->bc_mp; if (cur->bc_ops->type == XFS_BTREE_TYPE_AG)
xfs_failaddr_t fa; return __xfs_btree_check_agblock(cur, block, level, bp);
return __xfs_btree_check_fsblock(cur, block, level, bp);
}
fa = __xfs_btree_check_sblock(cur, block, level, bp); static inline unsigned int xfs_btree_block_errtag(struct xfs_btree_cur *cur)
if (XFS_IS_CORRUPT(mp, fa != NULL) || {
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) { if (cur->bc_ops->ptr_len == XFS_BTREE_SHORT_PTR_LEN)
if (bp) return XFS_ERRTAG_BTREE_CHECK_SBLOCK;
trace_xfs_btree_corrupt(bp, _RET_IP_); return XFS_ERRTAG_BTREE_CHECK_LBLOCK;
xfs_btree_mark_sick(cur);
return -EFSCORRUPTED;
}
return 0;
} }
/* /*
...@@ -252,34 +238,41 @@ xfs_btree_check_block( ...@@ -252,34 +238,41 @@ 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 */
{ {
if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) struct xfs_mount *mp = cur->bc_mp;
return xfs_btree_check_lblock(cur, block, level, bp); xfs_failaddr_t fa;
else
return xfs_btree_check_sblock(cur, block, level, bp);
}
/* Check that this long pointer is valid and points within the fs. */ fa = __xfs_btree_check_block(cur, block, level, bp);
bool if (XFS_IS_CORRUPT(mp, fa != NULL) ||
xfs_btree_check_lptr( XFS_TEST_ERROR(false, mp, xfs_btree_block_errtag(cur))) {
struct xfs_btree_cur *cur, if (bp)
xfs_fsblock_t fsbno, trace_xfs_btree_corrupt(bp, _RET_IP_);
int level) xfs_btree_mark_sick(cur);
{ return -EFSCORRUPTED;
if (level <= 0) }
return false; return 0;
return xfs_verify_fsbno(cur->bc_mp, fsbno);
} }
/* Check that this short pointer is valid and points within the AG. */ int
bool __xfs_btree_check_ptr(
xfs_btree_check_sptr(
struct xfs_btree_cur *cur, struct xfs_btree_cur *cur,
xfs_agblock_t agbno, const union xfs_btree_ptr *ptr,
int index,
int level) int level)
{ {
if (level <= 0) if (level <= 0)
return false; return -EFSCORRUPTED;
return xfs_verify_agbno(cur->bc_ag.pag, agbno);
if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
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;
} }
/* /*
...@@ -293,27 +286,26 @@ xfs_btree_check_ptr( ...@@ -293,27 +286,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) {
if (cur->bc_ops->type == XFS_BTREE_TYPE_INODE) {
xfs_err(cur->bc_mp, 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]),
level))
return 0;
xfs_err(cur->bc_mp, 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 -EFSCORRUPTED; }
return error;
} }
#ifdef DEBUG #ifdef DEBUG
...@@ -331,7 +323,7 @@ xfs_btree_check_ptr( ...@@ -331,7 +323,7 @@ xfs_btree_check_ptr(
* it to disk. * it to disk.
*/ */
void void
xfs_btree_lblock_calc_crc( xfs_btree_fsblock_calc_crc(
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
...@@ -345,7 +337,7 @@ xfs_btree_lblock_calc_crc( ...@@ -345,7 +337,7 @@ xfs_btree_lblock_calc_crc(
} }
bool bool
xfs_btree_lblock_verify_crc( xfs_btree_fsblock_verify_crc(
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
...@@ -369,7 +361,7 @@ xfs_btree_lblock_verify_crc( ...@@ -369,7 +361,7 @@ xfs_btree_lblock_verify_crc(
* it to disk. * it to disk.
*/ */
void void
xfs_btree_sblock_calc_crc( xfs_btree_agblock_calc_crc(
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
...@@ -383,7 +375,7 @@ xfs_btree_sblock_calc_crc( ...@@ -383,7 +375,7 @@ xfs_btree_sblock_calc_crc(
} }
bool bool
xfs_btree_sblock_verify_crc( xfs_btree_agblock_verify_crc(
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp);
...@@ -938,7 +930,7 @@ xfs_btree_reada_bufs( ...@@ -938,7 +930,7 @@ xfs_btree_reada_bufs(
} }
STATIC int STATIC int
xfs_btree_readahead_lblock( xfs_btree_readahead_fsblock(
struct xfs_btree_cur *cur, struct xfs_btree_cur *cur,
int lr, int lr,
struct xfs_btree_block *block) struct xfs_btree_block *block)
...@@ -963,7 +955,7 @@ xfs_btree_readahead_lblock( ...@@ -963,7 +955,7 @@ xfs_btree_readahead_lblock(
} }
STATIC int STATIC int
xfs_btree_readahead_sblock( xfs_btree_readahead_agblock(
struct xfs_btree_cur *cur, struct xfs_btree_cur *cur,
int lr, int lr,
struct xfs_btree_block *block) struct xfs_btree_block *block)
...@@ -1014,8 +1006,8 @@ xfs_btree_readahead( ...@@ -1014,8 +1006,8 @@ xfs_btree_readahead(
block = XFS_BUF_TO_BLOCK(cur->bc_levels[lev].bp); block = XFS_BUF_TO_BLOCK(cur->bc_levels[lev].bp);
if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) if (cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN)
return xfs_btree_readahead_lblock(cur, lr, block); return xfs_btree_readahead_fsblock(cur, lr, block);
return xfs_btree_readahead_sblock(cur, lr, block); return xfs_btree_readahead_agblock(cur, lr, block);
} }
STATIC int STATIC int
...@@ -4622,7 +4614,7 @@ xfs_btree_change_owner( ...@@ -4622,7 +4614,7 @@ xfs_btree_change_owner(
/* Verify the v5 fields of a long-format btree block. */ /* Verify the v5 fields of a long-format btree block. */
xfs_failaddr_t xfs_failaddr_t
xfs_btree_lblock_v5hdr_verify( xfs_btree_fsblock_v5hdr_verify(
struct xfs_buf *bp, struct xfs_buf *bp,
uint64_t owner) uint64_t owner)
{ {
...@@ -4643,7 +4635,7 @@ xfs_btree_lblock_v5hdr_verify( ...@@ -4643,7 +4635,7 @@ xfs_btree_lblock_v5hdr_verify(
/* Verify a long-format btree block. */ /* Verify a long-format btree block. */
xfs_failaddr_t xfs_failaddr_t
xfs_btree_lblock_verify( xfs_btree_fsblock_verify(
struct xfs_buf *bp, struct xfs_buf *bp,
unsigned int max_recs) unsigned int max_recs)
{ {
...@@ -4658,22 +4650,22 @@ xfs_btree_lblock_verify( ...@@ -4658,22 +4650,22 @@ xfs_btree_lblock_verify(
/* sibling pointer verification */ /* sibling pointer verification */
fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp)); fsb = XFS_DADDR_TO_FSB(mp, xfs_buf_daddr(bp));
fa = xfs_btree_check_lblock_siblings(mp, NULL, -1, fsb, fa = xfs_btree_check_fsblock_siblings(mp, fsb,
block->bb_u.l.bb_leftsib); block->bb_u.l.bb_leftsib);
if (!fa) if (!fa)
fa = xfs_btree_check_lblock_siblings(mp, NULL, -1, fsb, fa = xfs_btree_check_fsblock_siblings(mp, fsb,
block->bb_u.l.bb_rightsib); block->bb_u.l.bb_rightsib);
return fa; return fa;
} }
/** /**
* xfs_btree_sblock_v5hdr_verify() -- verify the v5 fields of a short-format * xfs_btree_agblock_v5hdr_verify() -- verify the v5 fields of a short-format
* btree block * btree block
* *
* @bp: buffer containing the btree block * @bp: buffer containing the btree block
*/ */
xfs_failaddr_t xfs_failaddr_t
xfs_btree_sblock_v5hdr_verify( xfs_btree_agblock_v5hdr_verify(
struct xfs_buf *bp) struct xfs_buf *bp)
{ {
struct xfs_mount *mp = bp->b_mount; struct xfs_mount *mp = bp->b_mount;
...@@ -4692,13 +4684,13 @@ xfs_btree_sblock_v5hdr_verify( ...@@ -4692,13 +4684,13 @@ xfs_btree_sblock_v5hdr_verify(
} }
/** /**
* xfs_btree_sblock_verify() -- verify a short-format btree block * xfs_btree_agblock_verify() -- verify a short-format btree block
* *
* @bp: buffer containing the btree block * @bp: buffer containing the btree block
* @max_recs: maximum records allowed in this btree node * @max_recs: maximum records allowed in this btree node
*/ */
xfs_failaddr_t xfs_failaddr_t
xfs_btree_sblock_verify( xfs_btree_agblock_verify(
struct xfs_buf *bp, struct xfs_buf *bp,
unsigned int max_recs) unsigned int max_recs)
{ {
...@@ -4713,10 +4705,10 @@ xfs_btree_sblock_verify( ...@@ -4713,10 +4705,10 @@ xfs_btree_sblock_verify(
/* sibling pointer verification */ /* sibling pointer verification */
agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp)); agbno = xfs_daddr_to_agbno(mp, xfs_buf_daddr(bp));
fa = xfs_btree_check_sblock_siblings(bp->b_pag, NULL, -1, agbno, fa = xfs_btree_check_agblock_siblings(bp->b_pag, agbno,
block->bb_u.s.bb_leftsib); block->bb_u.s.bb_leftsib);
if (!fa) if (!fa)
fa = xfs_btree_check_sblock_siblings(bp->b_pag, NULL, -1, agbno, fa = xfs_btree_check_agblock_siblings(bp->b_pag, agbno,
block->bb_u.s.bb_rightsib); block->bb_u.s.bb_rightsib);
return fa; return fa;
} }
......
...@@ -334,14 +334,10 @@ xfs_btree_cur_sizeof(unsigned int nlevels) ...@@ -334,14 +334,10 @@ xfs_btree_cur_sizeof(unsigned int nlevels)
*/ */
#define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr)) #define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr))
/* xfs_failaddr_t __xfs_btree_check_block(struct xfs_btree_cur *cur,
* 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,
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); 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 +349,6 @@ xfs_btree_check_block( ...@@ -353,24 +349,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.
*/ */
...@@ -463,10 +441,10 @@ int xfs_btree_change_owner(struct xfs_btree_cur *cur, uint64_t new_owner, ...@@ -463,10 +441,10 @@ int xfs_btree_change_owner(struct xfs_btree_cur *cur, uint64_t new_owner,
/* /*
* btree block CRC helpers * btree block CRC helpers
*/ */
void xfs_btree_lblock_calc_crc(struct xfs_buf *); void xfs_btree_fsblock_calc_crc(struct xfs_buf *);
bool xfs_btree_lblock_verify_crc(struct xfs_buf *); bool xfs_btree_fsblock_verify_crc(struct xfs_buf *);
void xfs_btree_sblock_calc_crc(struct xfs_buf *); void xfs_btree_agblock_calc_crc(struct xfs_buf *);
bool xfs_btree_sblock_verify_crc(struct xfs_buf *); bool xfs_btree_agblock_verify_crc(struct xfs_buf *);
/* /*
* Internal btree helpers also used by xfs_bmap.c. * Internal btree helpers also used by xfs_bmap.c.
...@@ -506,12 +484,12 @@ static inline int xfs_btree_get_level(const struct xfs_btree_block *block) ...@@ -506,12 +484,12 @@ static inline int xfs_btree_get_level(const struct xfs_btree_block *block)
#define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b)) #define XFS_FILBLKS_MIN(a,b) min_t(xfs_filblks_t, (a), (b))
#define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b)) #define XFS_FILBLKS_MAX(a,b) max_t(xfs_filblks_t, (a), (b))
xfs_failaddr_t xfs_btree_sblock_v5hdr_verify(struct xfs_buf *bp); xfs_failaddr_t xfs_btree_agblock_v5hdr_verify(struct xfs_buf *bp);
xfs_failaddr_t xfs_btree_sblock_verify(struct xfs_buf *bp, xfs_failaddr_t xfs_btree_agblock_verify(struct xfs_buf *bp,
unsigned int max_recs); unsigned int max_recs);
xfs_failaddr_t xfs_btree_lblock_v5hdr_verify(struct xfs_buf *bp, xfs_failaddr_t xfs_btree_fsblock_v5hdr_verify(struct xfs_buf *bp,
uint64_t owner); uint64_t owner);
xfs_failaddr_t xfs_btree_lblock_verify(struct xfs_buf *bp, xfs_failaddr_t xfs_btree_fsblock_verify(struct xfs_buf *bp,
unsigned int max_recs); unsigned int max_recs);
unsigned int xfs_btree_compute_maxlevels(const unsigned int *limits, unsigned int xfs_btree_compute_maxlevels(const unsigned int *limits,
......
...@@ -309,7 +309,7 @@ xfs_inobt_verify( ...@@ -309,7 +309,7 @@ xfs_inobt_verify(
* xfs_perag_initialised_agi(pag)) if we ever do. * xfs_perag_initialised_agi(pag)) if we ever do.
*/ */
if (xfs_has_crc(mp)) { if (xfs_has_crc(mp)) {
fa = xfs_btree_sblock_v5hdr_verify(bp); fa = xfs_btree_agblock_v5hdr_verify(bp);
if (fa) if (fa)
return fa; return fa;
} }
...@@ -319,7 +319,7 @@ xfs_inobt_verify( ...@@ -319,7 +319,7 @@ xfs_inobt_verify(
if (level >= M_IGEO(mp)->inobt_maxlevels) if (level >= M_IGEO(mp)->inobt_maxlevels)
return __this_address; return __this_address;
return xfs_btree_sblock_verify(bp, return xfs_btree_agblock_verify(bp,
M_IGEO(mp)->inobt_mxr[level != 0]); M_IGEO(mp)->inobt_mxr[level != 0]);
} }
...@@ -329,7 +329,7 @@ xfs_inobt_read_verify( ...@@ -329,7 +329,7 @@ xfs_inobt_read_verify(
{ {
xfs_failaddr_t fa; xfs_failaddr_t fa;
if (!xfs_btree_sblock_verify_crc(bp)) if (!xfs_btree_agblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address); xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else { else {
fa = xfs_inobt_verify(bp); fa = xfs_inobt_verify(bp);
...@@ -353,7 +353,7 @@ xfs_inobt_write_verify( ...@@ -353,7 +353,7 @@ xfs_inobt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa); xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return; return;
} }
xfs_btree_sblock_calc_crc(bp); xfs_btree_agblock_calc_crc(bp);
} }
......
...@@ -217,7 +217,7 @@ xfs_refcountbt_verify( ...@@ -217,7 +217,7 @@ xfs_refcountbt_verify(
if (!xfs_has_reflink(mp)) if (!xfs_has_reflink(mp))
return __this_address; return __this_address;
fa = xfs_btree_sblock_v5hdr_verify(bp); fa = xfs_btree_agblock_v5hdr_verify(bp);
if (fa) if (fa)
return fa; return fa;
...@@ -239,7 +239,7 @@ xfs_refcountbt_verify( ...@@ -239,7 +239,7 @@ xfs_refcountbt_verify(
} else if (level >= mp->m_refc_maxlevels) } else if (level >= mp->m_refc_maxlevels)
return __this_address; return __this_address;
return xfs_btree_sblock_verify(bp, mp->m_refc_mxr[level != 0]); return xfs_btree_agblock_verify(bp, mp->m_refc_mxr[level != 0]);
} }
STATIC void STATIC void
...@@ -248,7 +248,7 @@ xfs_refcountbt_read_verify( ...@@ -248,7 +248,7 @@ xfs_refcountbt_read_verify(
{ {
xfs_failaddr_t fa; xfs_failaddr_t fa;
if (!xfs_btree_sblock_verify_crc(bp)) if (!xfs_btree_agblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address); xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else { else {
fa = xfs_refcountbt_verify(bp); fa = xfs_refcountbt_verify(bp);
...@@ -272,7 +272,7 @@ xfs_refcountbt_write_verify( ...@@ -272,7 +272,7 @@ xfs_refcountbt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa); xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return; return;
} }
xfs_btree_sblock_calc_crc(bp); xfs_btree_agblock_calc_crc(bp);
} }
......
...@@ -336,7 +336,7 @@ xfs_rmapbt_verify( ...@@ -336,7 +336,7 @@ xfs_rmapbt_verify(
if (!xfs_has_rmapbt(mp)) if (!xfs_has_rmapbt(mp))
return __this_address; return __this_address;
fa = xfs_btree_sblock_v5hdr_verify(bp); fa = xfs_btree_agblock_v5hdr_verify(bp);
if (fa) if (fa)
return fa; return fa;
...@@ -347,7 +347,7 @@ xfs_rmapbt_verify( ...@@ -347,7 +347,7 @@ xfs_rmapbt_verify(
} else if (level >= mp->m_rmap_maxlevels) } else if (level >= mp->m_rmap_maxlevels)
return __this_address; return __this_address;
return xfs_btree_sblock_verify(bp, mp->m_rmap_mxr[level != 0]); return xfs_btree_agblock_verify(bp, mp->m_rmap_mxr[level != 0]);
} }
static void static void
...@@ -356,7 +356,7 @@ xfs_rmapbt_read_verify( ...@@ -356,7 +356,7 @@ xfs_rmapbt_read_verify(
{ {
xfs_failaddr_t fa; xfs_failaddr_t fa;
if (!xfs_btree_sblock_verify_crc(bp)) if (!xfs_btree_agblock_verify_crc(bp))
xfs_verifier_error(bp, -EFSBADCRC, __this_address); xfs_verifier_error(bp, -EFSBADCRC, __this_address);
else { else {
fa = xfs_rmapbt_verify(bp); fa = xfs_rmapbt_verify(bp);
...@@ -380,7 +380,7 @@ xfs_rmapbt_write_verify( ...@@ -380,7 +380,7 @@ xfs_rmapbt_write_verify(
xfs_verifier_error(bp, -EFSCORRUPTED, fa); xfs_verifier_error(bp, -EFSCORRUPTED, fa);
return; return;
} }
xfs_btree_sblock_calc_crc(bp); xfs_btree_agblock_calc_crc(bp);
} }
......
...@@ -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. */
...@@ -588,7 +584,6 @@ xchk_btree_get_block( ...@@ -588,7 +584,6 @@ xchk_btree_get_block(
struct xfs_btree_block **pblock, struct xfs_btree_block **pblock,
struct xfs_buf **pbp) struct xfs_buf **pbp)
{ {
xfs_failaddr_t failed_at;
int error; int error;
*pblock = NULL; *pblock = NULL;
...@@ -600,13 +595,7 @@ xchk_btree_get_block( ...@@ -600,13 +595,7 @@ xchk_btree_get_block(
return error; return error;
xfs_btree_get_block(bs->cur, level, pbp); xfs_btree_get_block(bs->cur, level, pbp);
if (bs->cur->bc_ops->ptr_len == XFS_BTREE_LONG_PTR_LEN) if (__xfs_btree_check_block(bs->cur, *pblock, level, *pbp)) {
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) {
xchk_btree_set_corrupt(bs->sc, bs->cur, level); xchk_btree_set_corrupt(bs->sc, bs->cur, level);
return 0; return 0;
} }
......
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