Commit b65e08f8 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

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: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent f850995f
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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.
+1 −5
Original line number Diff line number Diff line
@@ -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;
+1 −5
Original line number Diff line number Diff line
@@ -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)
+2 −7
Original line number Diff line number Diff line
@@ -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;
	}

+1 −3
Original line number Diff line number Diff line
@@ -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);
Loading