diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-09-01 10:45:54 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-10-22 16:40:36 -0700 |
commit | 48bec246f88d06c80d2918284cb9d78fa767c140 (patch) | |
tree | 0a3c0feabdef35a1f9e31c28c214ed2cba5c4e65 /fs/xfs/scrub | |
parent | 86fd53a2c51b3253bb407bd1003c1e86c017c53c (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>
Diffstat (limited to 'fs/xfs/scrub')
-rw-r--r-- | fs/xfs/scrub/repair.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/fs/xfs/scrub/repair.c b/fs/xfs/scrub/repair.c index 832926c1fa9d..20667b8b2754 100644 --- a/fs/xfs/scrub/repair.c +++ b/fs/xfs/scrub/repair.c @@ -1027,6 +1027,20 @@ xrep_reap_ag_extent( roll_out: 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); } @@ -1086,8 +1100,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; } @@ -1124,6 +1154,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; } |