xfs: create a predicate to verify per-AG extents
authorDarrick J. Wong <djwong@kernel.org>
Fri, 28 Oct 2022 22:48:58 +0000 (15:48 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 31 Oct 2022 15:58:20 +0000 (08:58 -0700)
Create a predicate function to verify that a given agbno/blockcount pair
fit entirely within a single allocation group and don't suffer
mathematical overflows.  Refactor the existng open-coded logic; we're
going to add more calls to this function in the next patch.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/libxfs/xfs_ag.h
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_refcount.c
fs/xfs/libxfs/xfs_rmap.c
fs/xfs/scrub/alloc.c
fs/xfs/scrub/ialloc.c
fs/xfs/scrub/refcount.c

index 517a138..191b22b 100644 (file)
@@ -133,6 +133,21 @@ xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno)
        return true;
 }
 
+static inline bool
+xfs_verify_agbext(
+       struct xfs_perag        *pag,
+       xfs_agblock_t           agbno,
+       xfs_agblock_t           len)
+{
+       if (agbno + len <= agbno)
+               return false;
+
+       if (!xfs_verify_agbno(pag, agbno))
+               return false;
+
+       return xfs_verify_agbno(pag, agbno + len - 1);
+}
+
 /*
  * Verify that an AG inode number pointer neither points outside the AG
  * nor points at static metadata.
index 6261599..de79f5d 100644 (file)
@@ -263,11 +263,7 @@ xfs_alloc_get_rec(
                goto out_bad_rec;
 
        /* check for valid extent range, including overflow */
-       if (!xfs_verify_agbno(pag, *bno))
-               goto out_bad_rec;
-       if (*bno > *bno + *len)
-               goto out_bad_rec;
-       if (!xfs_verify_agbno(pag, *bno + *len - 1))
+       if (!xfs_verify_agbext(pag, *bno, *len))
                goto out_bad_rec;
 
        return 0;
index 831353b..1a50ca5 100644 (file)
@@ -135,11 +135,7 @@ xfs_refcount_get_rec(
        }
 
        /* check for valid extent range, including overflow */
-       if (!xfs_verify_agbno(pag, realstart))
-               goto out_bad_rec;
-       if (realstart > realstart + irec->rc_blockcount)
-               goto out_bad_rec;
-       if (!xfs_verify_agbno(pag, realstart + irec->rc_blockcount - 1))
+       if (!xfs_verify_agbext(pag, realstart, irec->rc_blockcount))
                goto out_bad_rec;
 
        if (irec->rc_refcount == 0 || irec->rc_refcount > MAXREFCOUNT)
index 094dfc8..b56aca1 100644 (file)
@@ -235,13 +235,8 @@ xfs_rmap_get_rec(
                        goto out_bad_rec;
        } else {
                /* check for valid extent range, including overflow */
-               if (!xfs_verify_agbno(pag, irec->rm_startblock))
-                       goto out_bad_rec;
-               if (irec->rm_startblock >
-                               irec->rm_startblock + irec->rm_blockcount)
-                       goto out_bad_rec;
-               if (!xfs_verify_agbno(pag,
-                               irec->rm_startblock + irec->rm_blockcount - 1))
+               if (!xfs_verify_agbext(pag, irec->rm_startblock,
+                                           irec->rm_blockcount))
                        goto out_bad_rec;
        }
 
index ab427b4..3b38f4e 100644 (file)
@@ -100,9 +100,7 @@ xchk_allocbt_rec(
        bno = be32_to_cpu(rec->alloc.ar_startblock);
        len = be32_to_cpu(rec->alloc.ar_blockcount);
 
-       if (bno + len <= bno ||
-           !xfs_verify_agbno(pag, bno) ||
-           !xfs_verify_agbno(pag, bno + len - 1))
+       if (!xfs_verify_agbext(pag, bno, len))
                xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
 
        xchk_allocbt_xref(bs->sc, bno, len);
index e1026e0..e312be7 100644 (file)
@@ -108,9 +108,8 @@ xchk_iallocbt_chunk(
        xfs_agblock_t                   bno;
 
        bno = XFS_AGINO_TO_AGBNO(mp, agino);
-       if (bno + len <= bno ||
-           !xfs_verify_agbno(pag, bno) ||
-           !xfs_verify_agbno(pag, bno + len - 1))
+
+       if (!xfs_verify_agbext(pag, bno, len))
                xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
 
        xchk_iallocbt_chunk_xref(bs->sc, irec, agino, bno, len);
index c68b767..9959397 100644 (file)
@@ -354,9 +354,8 @@ xchk_refcountbt_rec(
 
        /* Check the extent. */
        bno &= ~XFS_REFC_COW_START;
-       if (bno + len <= bno ||
-           !xfs_verify_agbno(pag, bno) ||
-           !xfs_verify_agbno(pag, bno + len - 1))
+
+       if (!xfs_verify_agbext(pag, bno, len))
                xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
 
        if (refcount == 0)