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:
parent
f850995f60
commit
b65e08f83b
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user