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

xfs: count free space btree blocks when scrubbing pre-lazysbcount fses



Since agf_btreeblks didn't exist before the lazysbcount feature, the fs
summary count scrubber needs to walk the free space btrees to determine
the amount of space being used by those btrees.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarGao Xiang <hsiangkao@redhat.com>
parent 6543990a
Loading
Loading
Loading
Loading
+38 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include "xfs_alloc.h"
#include "xfs_ialloc.h"
#include "xfs_health.h"
#include "xfs_btree.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"
@@ -143,6 +144,35 @@ xchk_setup_fscounters(
	return xchk_trans_alloc(sc, 0);
}

/* Count free space btree blocks manually for pre-lazysbcount filesystems. */
static int
xchk_fscount_btreeblks(
	struct xfs_scrub	*sc,
	struct xchk_fscounters	*fsc,
	xfs_agnumber_t		agno)
{
	xfs_extlen_t		blocks;
	int			error;

	error = xchk_ag_init(sc, agno, &sc->sa);
	if (error)
		return error;

	error = xfs_btree_count_blocks(sc->sa.bno_cur, &blocks);
	if (error)
		goto out_free;
	fsc->fdblocks += blocks - 1;

	error = xfs_btree_count_blocks(sc->sa.cnt_cur, &blocks);
	if (error)
		goto out_free;
	fsc->fdblocks += blocks - 1;

out_free:
	xchk_ag_free(sc, &sc->sa);
	return error;
}

/*
 * Calculate what the global in-core counters ought to be from the incore
 * per-AG structure.  Callers can compare this to the actual in-core counters
@@ -182,8 +212,15 @@ xchk_fscount_aggregate_agcounts(
		/* Add up the free/freelist/bnobt/cntbt blocks */
		fsc->fdblocks += pag->pagf_freeblks;
		fsc->fdblocks += pag->pagf_flcount;
		if (xfs_sb_version_haslazysbcount(&sc->mp->m_sb))
		if (xfs_sb_version_haslazysbcount(&sc->mp->m_sb)) {
			fsc->fdblocks += pag->pagf_btreeblks;
		} else {
			error = xchk_fscount_btreeblks(sc, fsc, agno);
			if (error) {
				xfs_perag_put(pag);
				break;
			}
		}

		/*
		 * Per-AG reservations are taken out of the incore counters,