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

xfs: refactor refcount record usage in xchk_refcountbt_rec



Consolidate the open-coded xfs_refcount_irec fields into an actual
struct and use the existing _btrec_to_irec to decode the ondisk record.
This will reduce code churn in the next patch.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent 9e7e2436
Loading
Loading
Loading
Loading
+24 −30
Original line number Diff line number Diff line
@@ -269,15 +269,13 @@ xchk_refcountbt_process_rmap_fragments(
STATIC void
xchk_refcountbt_xref_rmap(
	struct xfs_scrub		*sc,
	xfs_agblock_t			bno,
	xfs_extlen_t			len,
	xfs_nlink_t			refcount)
	const struct xfs_refcount_irec	*irec)
{
	struct xchk_refcnt_check	refchk = {
		.sc			= sc,
		.bno = bno,
		.len = len,
		.refcount = refcount,
		.bno			= irec->rc_startblock,
		.len			= irec->rc_blockcount,
		.refcount		= irec->rc_refcount,
		.seen = 0,
	};
	struct xfs_rmap_irec		low;
@@ -291,9 +289,9 @@ xchk_refcountbt_xref_rmap(

	/* Cross-reference with the rmapbt to confirm the refcount. */
	memset(&low, 0, sizeof(low));
	low.rm_startblock = bno;
	low.rm_startblock = irec->rc_startblock;
	memset(&high, 0xFF, sizeof(high));
	high.rm_startblock = bno + len - 1;
	high.rm_startblock = irec->rc_startblock + irec->rc_blockcount - 1;

	INIT_LIST_HEAD(&refchk.fragments);
	error = xfs_rmap_query_range(sc->sa.rmap_cur, &low, &high,
@@ -302,7 +300,7 @@ xchk_refcountbt_xref_rmap(
		goto out_free;

	xchk_refcountbt_process_rmap_fragments(&refchk);
	if (refcount != refchk.seen)
	if (irec->rc_refcount != refchk.seen)
		xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);

out_free:
@@ -316,16 +314,15 @@ xchk_refcountbt_xref_rmap(
STATIC void
xchk_refcountbt_xref(
	struct xfs_scrub		*sc,
	xfs_agblock_t		agbno,
	xfs_extlen_t		len,
	xfs_nlink_t		refcount)
	const struct xfs_refcount_irec	*irec)
{
	if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
		return;

	xchk_xref_is_used_space(sc, agbno, len);
	xchk_xref_is_not_inode_chunk(sc, agbno, len);
	xchk_refcountbt_xref_rmap(sc, agbno, len, refcount);
	xchk_xref_is_used_space(sc, irec->rc_startblock, irec->rc_blockcount);
	xchk_xref_is_not_inode_chunk(sc, irec->rc_startblock,
			irec->rc_blockcount);
	xchk_refcountbt_xref_rmap(sc, irec);
}

/* Scrub a refcountbt record. */
@@ -334,34 +331,31 @@ xchk_refcountbt_rec(
	struct xchk_btree	*bs,
	const union xfs_btree_rec *rec)
{
	struct xfs_refcount_irec irec;
	xfs_agblock_t		*cow_blocks = bs->private;
	struct xfs_perag	*pag = bs->cur->bc_ag.pag;
	xfs_agblock_t		bno;
	xfs_extlen_t		len;
	xfs_nlink_t		refcount;
	bool			has_cowflag;

	bno = be32_to_cpu(rec->refc.rc_startblock);
	len = be32_to_cpu(rec->refc.rc_blockcount);
	refcount = be32_to_cpu(rec->refc.rc_refcount);
	xfs_refcount_btrec_to_irec(rec, &irec);

	/* Only CoW records can have refcount == 1. */
	has_cowflag = (bno & XFS_REFC_COW_START);
	if ((refcount == 1 && !has_cowflag) || (refcount != 1 && has_cowflag))
	has_cowflag = (irec.rc_startblock & XFS_REFC_COW_START);
	if ((irec.rc_refcount == 1 && !has_cowflag) ||
	    (irec.rc_refcount != 1 && has_cowflag))
		xchk_btree_set_corrupt(bs->sc, bs->cur, 0);
	if (has_cowflag)
		(*cow_blocks) += len;
		(*cow_blocks) += irec.rc_blockcount;

	/* Check the extent. */
	bno &= ~XFS_REFC_COW_START;
	irec.rc_startblock &= ~XFS_REFC_COW_START;

	if (!xfs_verify_agbext(pag, bno, len))
	if (!xfs_verify_agbext(pag, irec.rc_startblock, irec.rc_blockcount))
		xchk_btree_set_corrupt(bs->sc, bs->cur, 0);

	if (refcount == 0)
	if (irec.rc_refcount == 0)
		xchk_btree_set_corrupt(bs->sc, bs->cur, 0);

	xchk_refcountbt_xref(bs->sc, bno, len, refcount);
	xchk_refcountbt_xref(bs->sc, &irec);

	return 0;
}