xfs: create a predicate to verify per-AG extents

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>
This commit is contained in:
Darrick J. Wong 2022-10-28 15:48:58 -07:00
parent f850995f60
commit b65e08f83b
7 changed files with 24 additions and 26 deletions

View 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.

View 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;

View 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)

View 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;
}

View 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);

View 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);

View 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)