xfs: consolidate btree ptr checking
authorChristoph Hellwig <hch@lst.de>
Thu, 22 Feb 2024 20:40:54 +0000 (12:40 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 22 Feb 2024 20:40:54 +0000 (12:40 -0800)
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>
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_btree.h
fs/xfs/scrub/btree.c

index fc877188919e3d1c04e5f827c9ce67c631d0a21e..1a0816aa5009109a8d0ac68d9c4e9ceeed0a2d53 100644 (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
index 9a264ffee30363b619fe7319fcafabdbe64f4bf4..ca4a305eb0711ac1787612238f1d594c9ef12cee 100644 (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.
  */
index 187d692a0b58ab04f24d614d2a79420e8589504c..6fe5dae06f23c8a54c8e66f949a04c0b5ede3c56 100644 (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. */