On Mon, Apr 26, 2021 at 08:02:32PM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <djwong@xxxxxxxxxx> > > 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: Darrick J. Wong <djwong@xxxxxxxxxx> > --- Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx> > Note: I /think/ the four patches on the list right now fix all the > obvious problems with !lazysbcount filesystems, except for xfs/49[12] > which fuzz the summary counters. > --- > fs/xfs/scrub/fscounters.c | 37 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > > diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c > index 318b81c0f90d..87476a00de9d 100644 > --- a/fs/xfs/scrub/fscounters.c > +++ b/fs/xfs/scrub/fscounters.c > @@ -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 > @@ -184,6 +214,13 @@ xchk_fscount_aggregate_agcounts( > fsc->fdblocks += pag->pagf_flcount; > 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, >