summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-01 10:45:54 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-09-17 18:54:52 -0700
commiteb751c4562dcec64638e914b7d8286de528f8dce (patch)
treed6a927dfc98b0b0a8e885c88051890b03a231fa8
parent88687a1baa6621ac2509b2d0e1d3d29ed54de536 (diff)
xfs: reintroduce reaping of file extents to xrep_reap_extents
Reintroduce to xrep_reap_extents the ability to reap extents from any AG. We dropped this before because it was buggy, but in the next patch we will gain the ability to reap old bmap btrees, which can have blocks in any AG. To do this, we require that sc->sa is uninitialized, so that we can use it to hold all the per-AG context for a given extent. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/scrub/repair.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c
index ea7b88a0c693..b10f95c22caa 100644
--- a/fs/xfs/scrub/repair.c
+++ b/fs/xfs/scrub/repair.c
@@ -1015,6 +1015,20 @@ xrep_reap_ag_extent(
return error;
rs->deferred = 0;
+ if (sc->ip) {
+ /*
+ * If we're reaping file data, hold the AGF buffer across the
+ * transaction roll so that we don't have to reattach it to the
+ * xchk_ag structure.
+ */
+ xfs_trans_bhold(sc->tp, sc->sa.agf_bp);
+ error = xfs_trans_roll_inode(&sc->tp, sc->ip);
+ if (error)
+ return error;
+ xfs_trans_bjoin(sc->tp, sc->sa.agf_bp);
+ return 0;
+ }
+
return xrep_roll_ag_trans(sc);
}
@@ -1074,8 +1088,24 @@ xrep_reap_extent(
ASSERT(len <= MAXEXTLEN);
- /* We don't support reaping file extents yet. */
- if (sc->ip != NULL || sc->sa.pag->pag_agno != agno) {
+ if (sc->ip != NULL) {
+ /*
+ * We're reaping blocks after repairing file metadata, which
+ * means that the blocks can be in any AG, so we have to init
+ * the xchk_ag structure before we can reap each extent and
+ * release it afterwards.
+ */
+ ASSERT(!sc->sa.pag);
+
+ sc->sa.pag = xfs_perag_get(sc->mp, agno);
+ if (!sc->sa.pag)
+ return -EFSCORRUPTED;
+
+ error = xfs_alloc_read_agf(sc->mp, sc->tp, agno, 0,
+ &sc->sa.agf_bp);
+ if (error)
+ goto out_pag;
+ } else if (sc->sa.pag == NULL || sc->sa.pag->pag_agno != agno) {
ASSERT(0);
return -EFSCORRUPTED;
}
@@ -1112,6 +1142,15 @@ xrep_reap_extent(
out_cur:
if (cur)
xfs_btree_del_cursor(cur, error);
+ if (sc->ip != NULL) {
+ xfs_trans_brelse(sc->tp, sc->sa.agf_bp);
+ sc->sa.agf_bp = NULL;
+ }
+out_pag:
+ if (sc->ip != NULL) {
+ xfs_perag_put(sc->sa.pag);
+ sc->sa.pag = NULL;
+ }
return error;
}