xfs: refactor btree pointer checks
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 18 Oct 2017 04:37:33 +0000 (21:37 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Thu, 26 Oct 2017 22:38:23 +0000 (15:38 -0700)
Refactor the btree pointer checks so that we can call them from the
scrub code without logging errors to dmesg.  Preserve the existing error
reporting for regular operations.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_btree.h

index dd6672b..7eac21a 100644 (file)
@@ -646,8 +646,8 @@ xfs_bmap_btree_to_extents(
        cbno = be64_to_cpu(*pp);
        *logflagsp = 0;
 #ifdef DEBUG
-       if ((error = xfs_btree_check_lptr(cur, cbno, 1)))
-               return error;
+       XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
+                       xfs_btree_check_lptr(cur, cbno, 1));
 #endif
        error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF,
                                &xfs_bmbt_buf_ops);
index 5bfb882..ae19f24 100644 (file)
@@ -177,59 +177,53 @@ xfs_btree_check_block(
                return xfs_btree_check_sblock(cur, block, level, bp);
 }
 
-/*
- * Check that (long) pointer is ok.
- */
-int                                    /* error (0 or EFSCORRUPTED) */
+/* Check that this long pointer is valid and points within the fs. */
+bool
 xfs_btree_check_lptr(
-       struct xfs_btree_cur    *cur,   /* btree cursor */
-       xfs_fsblock_t           bno,    /* btree block disk address */
-       int                     level)  /* btree block level */
+       struct xfs_btree_cur    *cur,
+       xfs_fsblock_t           fsbno,
+       int                     level)
 {
-       XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
-               level > 0 &&
-               bno != NULLFSBLOCK &&
-               XFS_FSB_SANITY_CHECK(cur->bc_mp, bno));
-       return 0;
+       if (level <= 0)
+               return false;
+       return xfs_verify_fsbno(cur->bc_mp, fsbno);
 }
 
-#ifdef DEBUG
-/*
- * Check that (short) pointer is ok.
- */
-STATIC int                             /* error (0 or EFSCORRUPTED) */
+/* Check that this short pointer is valid and points within the AG. */
+bool
 xfs_btree_check_sptr(
-       struct xfs_btree_cur    *cur,   /* btree cursor */
-       xfs_agblock_t           bno,    /* btree block disk address */
-       int                     level)  /* btree block level */
+       struct xfs_btree_cur    *cur,
+       xfs_agblock_t           agbno,
+       int                     level)
 {
-       xfs_agblock_t           agblocks = cur->bc_mp->m_sb.sb_agblocks;
-
-       XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
-               level > 0 &&
-               bno != NULLAGBLOCK &&
-               bno != 0 &&
-               bno < agblocks);
-       return 0;
+       if (level <= 0)
+               return false;
+       return xfs_verify_agbno(cur->bc_mp, cur->bc_private.a.agno, agbno);
 }
 
+#ifdef DEBUG
 /*
- * Check that block ptr is ok.
+ * Check that a given (indexed) btree pointer at a certain level of a
+ * btree is valid and doesn't point past where it should.
  */
-STATIC int                             /* error (0 or EFSCORRUPTED) */
+int
 xfs_btree_check_ptr(
-       struct xfs_btree_cur    *cur,   /* btree cursor */
-       union xfs_btree_ptr     *ptr,   /* btree block disk address */
-       int                     index,  /* offset from ptr to check */
-       int                     level)  /* btree block level */
+       struct xfs_btree_cur    *cur,
+       union xfs_btree_ptr     *ptr,
+       int                     index,
+       int                     level)
 {
        if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
-               return xfs_btree_check_lptr(cur,
-                               be64_to_cpu((&ptr->l)[index]), level);
+               XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
+                               xfs_btree_check_lptr(cur,
+                                       be64_to_cpu((&ptr->l)[index]), level));
        } else {
-               return xfs_btree_check_sptr(cur,
-                               be32_to_cpu((&ptr->s)[index]), level);
+               XFS_WANT_CORRUPTED_RETURN(cur->bc_mp,
+                               xfs_btree_check_sptr(cur,
+                                       be32_to_cpu((&ptr->s)[index]), level));
        }
+
+       return 0;
 }
 #endif
 
index f2a88c3..8f52eda 100644 (file)
@@ -269,10 +269,19 @@ xfs_btree_check_block(
 /*
  * Check that (long) pointer is ok.
  */
-int                                    /* error (0 or EFSCORRUPTED) */
+bool                                   /* error (0 or EFSCORRUPTED) */
 xfs_btree_check_lptr(
        struct xfs_btree_cur    *cur,   /* btree cursor */
-       xfs_fsblock_t           ptr,    /* btree block disk address */
+       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 */
 
 /*