summaryrefslogtreecommitdiff
path: root/fs/xfs/scrub/repair.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/scrub/repair.c')
-rw-r--r--fs/xfs/scrub/repair.c60
1 files changed, 31 insertions, 29 deletions
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)