On Tue, Oct 22, 2019 at 09:35:18AM -0400, Brian Foster wrote: > On Wed, Oct 09, 2019 at 09:49:22AM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > > > Remove the for_each_xbitmap_ macros in favor of proper iterator > > functions. We'll soon be switching this data structure over to an > > interval tree implementation, which means that we can't allow callers to > > modify the bitmap during iteration without telling us. > > > > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > --- > > fs/xfs/scrub/agheader_repair.c | 73 ++++++++++++++++++++++++---------------- > > fs/xfs/scrub/bitmap.c | 59 ++++++++++++++++++++++++++++++++ > > fs/xfs/scrub/bitmap.h | 22 ++++++++---- > > fs/xfs/scrub/repair.c | 60 +++++++++++++++++---------------- > > 4 files changed, 148 insertions(+), 66 deletions(-) > > > > > ... > > diff --git a/fs/xfs/scrub/bitmap.h b/fs/xfs/scrub/bitmap.h > > index 900646b72de1..27fde5b4a753 100644 > > --- a/fs/xfs/scrub/bitmap.h > > +++ b/fs/xfs/scrub/bitmap.h > ... > > @@ -34,4 +27,19 @@ int xbitmap_set_btblocks(struct xbitmap *bitmap, > > struct xfs_btree_cur *cur); > > uint64_t xbitmap_hweight(struct xbitmap *bitmap); > > > > +/* > > + * Return codes for the bitmap iterator functions are 0 to continue iterating, > > + * and non-zero to stop iterating. Any non-zero value will be passed up to the > > + * iteration caller. The special value -ECANCELED can be used to stop > > + * iteration, because neither bitmap iterator ever generates that error code on > > + * its own. > > + */ > > +typedef int (*xbitmap_walk_run_fn)(uint64_t start, uint64_t len, void *priv); > > +int xbitmap_iter_set(struct xbitmap *bitmap, xbitmap_walk_run_fn fn, > > + void *priv); > > + > > +typedef int (*xbitmap_walk_bit_fn)(uint64_t bit, void *priv); > > +int xbitmap_iter_set_bits(struct xbitmap *bitmap, xbitmap_walk_bit_fn fn, > > + void *priv); > > + > > Somewhat of a nit, but I read "set" as a verb in the above function > names which tends to confuse me over what these functions do (i.e. > iterate bits, not set bits). Could we call them something a bit more > neutral, like xbitmap[_bit]_iter() perhaps? That aside the rest of the > patch looks Ok to me. Ok, will rename them. --D > Brian > > > #endif /* __XFS_SCRUB_BITMAP_H__ */ > > diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c > > index d41da4c44f10..588bc054db5c 100644 > > --- a/fs/xfs/scrub/repair.c > > +++ b/fs/xfs/scrub/repair.c > > @@ -507,15 +507,21 @@ xrep_reap_invalidate_block( > > xfs_trans_binval(sc->tp, bp); > > } > > > > +struct xrep_reap_block { > > + struct xfs_scrub *sc; > > + const struct xfs_owner_info *oinfo; > > + enum xfs_ag_resv_type resv; > > + unsigned int deferred; > > +}; > > + > > /* Dispose of a single block. */ > > STATIC int > > xrep_reap_block( > > - struct xfs_scrub *sc, > > - xfs_fsblock_t fsbno, > > - const struct xfs_owner_info *oinfo, > > - enum xfs_ag_resv_type resv, > > - unsigned int *deferred) > > + uint64_t fsbno, > > + void *priv) > > { > > + struct xrep_reap_block *rb = priv; > > + struct xfs_scrub *sc = rb->sc; > > struct xfs_btree_cur *cur; > > struct xfs_buf *agf_bp = NULL; > > xfs_agnumber_t agno; > > @@ -527,6 +533,10 @@ xrep_reap_block( > > agno = XFS_FSB_TO_AGNO(sc->mp, fsbno); > > agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno); > > > > + ASSERT(sc->ip != NULL || agno == sc->sa.agno); > > + > > + trace_xrep_dispose_btree_extent(sc->mp, agno, agbno, 1); > > + > > /* > > * If we are repairing per-inode metadata, we need to read in the AGF > > * buffer. Otherwise, we're repairing a per-AG structure, so reuse > > @@ -544,7 +554,8 @@ xrep_reap_block( > > cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, agf_bp, agno); > > > > /* Can we find any other rmappings? */ > > - error = xfs_rmap_has_other_keys(cur, agbno, 1, oinfo, &has_other_rmap); > > + error = xfs_rmap_has_other_keys(cur, agbno, 1, rb->oinfo, > > + &has_other_rmap); > > xfs_btree_del_cursor(cur, error); > > if (error) > > goto out_free; > > @@ -563,8 +574,9 @@ xrep_reap_block( > > * to run xfs_repair. > > */ > > if (has_other_rmap) { > > - error = xfs_rmap_free(sc->tp, agf_bp, agno, agbno, 1, oinfo); > > - } else if (resv == XFS_AG_RESV_AGFL) { > > + error = xfs_rmap_free(sc->tp, agf_bp, agno, agbno, 1, > > + rb->oinfo); > > + } else if (rb->resv == XFS_AG_RESV_AGFL) { > > xrep_reap_invalidate_block(sc, fsbno); > > error = xrep_put_freelist(sc, agbno); > > } else { > > @@ -576,16 +588,16 @@ xrep_reap_block( > > * reservation. > > */ > > xrep_reap_invalidate_block(sc, fsbno); > > - __xfs_bmap_add_free(sc->tp, fsbno, 1, oinfo, true); > > - (*deferred)++; > > - need_roll = *deferred > 100; > > + __xfs_bmap_add_free(sc->tp, fsbno, 1, rb->oinfo, true); > > + rb->deferred++; > > + need_roll = rb->deferred > 100; > > } > > if (agf_bp != sc->sa.agf_bp) > > xfs_trans_brelse(sc->tp, agf_bp); > > if (error || !need_roll) > > return error; > > > > - *deferred = 0; > > + rb->deferred = 0; > > if (sc->ip) > > return xfs_trans_roll_inode(&sc->tp, sc->ip); > > return xrep_roll_ag_trans(sc); > > @@ -604,27 +616,17 @@ xrep_reap_extents( > > const struct xfs_owner_info *oinfo, > > enum xfs_ag_resv_type type) > > { > > - struct xbitmap_range *bmr; > > - struct xbitmap_range *n; > > - xfs_fsblock_t fsbno; > > - unsigned int deferred = 0; > > + struct xrep_reap_block rb = { > > + .sc = sc, > > + .oinfo = oinfo, > > + .resv = type, > > + }; > > int error = 0; > > > > ASSERT(xfs_sb_version_hasrmapbt(&sc->mp->m_sb)); > > > > - for_each_xbitmap_block(fsbno, bmr, n, bitmap) { > > - ASSERT(sc->ip != NULL || > > - XFS_FSB_TO_AGNO(sc->mp, fsbno) == sc->sa.agno); > > - trace_xrep_dispose_btree_extent(sc->mp, > > - XFS_FSB_TO_AGNO(sc->mp, fsbno), > > - XFS_FSB_TO_AGBNO(sc->mp, fsbno), 1); > > - > > - error = xrep_reap_block(sc, fsbno, oinfo, type, &deferred); > > - if (error) > > - break; > > - } > > - > > - if (error || deferred == 0) > > + error = xbitmap_iter_set_bits(bitmap, xrep_reap_block, &rb); > > + if (error || rb.deferred == 0) > > return error; > > > > if (sc->ip) > > >