From: Darrick J. Wong <djwong@xxxxxxxxxx> Rearrange the logic inside xrep_reap_block to make it more obvious that crosslinked metadata blocks are handled differently. Add a couple of tracepoints so that we can tell what's going on at the end of a btree rebuild operation. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- fs/xfs/scrub/agheader_repair.c | 6 +++--- fs/xfs/scrub/reap.c | 19 ++++++++++++++----- fs/xfs/scrub/trace.h | 17 ++++++++--------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index c902a5dee57f..b8d28cfec286 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -646,13 +646,13 @@ xrep_agfl_fill( xfs_fsblock_t fsbno = start; int error; + trace_xrep_agfl_insert(sc->sa.pag, XFS_FSB_TO_AGBNO(sc->mp, start), + len); + while (fsbno < start + len && af->fl_off < af->flcount) af->agfl_bno[af->fl_off++] = cpu_to_be32(XFS_FSB_TO_AGBNO(sc->mp, fsbno++)); - trace_xrep_agfl_insert(sc->mp, sc->sa.pag->pag_agno, - XFS_FSB_TO_AGBNO(sc->mp, start), len); - error = xbitmap_set(&af->used_extents, start, fsbno - 1); if (error) return error; diff --git a/fs/xfs/scrub/reap.c b/fs/xfs/scrub/reap.c index e9839f3905e7..30e61315feb0 100644 --- a/fs/xfs/scrub/reap.c +++ b/fs/xfs/scrub/reap.c @@ -175,8 +175,6 @@ xrep_reap_block( agno = XFS_FSB_TO_AGNO(sc->mp, fsbno); agbno = XFS_FSB_TO_AGBNO(sc->mp, fsbno); - trace_xrep_dispose_btree_extent(sc->mp, agno, agbno, 1); - /* We don't support reaping file extents yet. */ if (sc->ip != NULL || sc->sa.pag->pag_agno != agno) { ASSERT(0); @@ -206,10 +204,21 @@ xrep_reap_block( * to run xfs_repair. */ if (has_other_rmap) { + trace_xrep_dispose_unmap_extent(sc->sa.pag, agbno, 1); + error = xfs_rmap_free(sc->tp, sc->sa.agf_bp, sc->sa.pag, agbno, 1, rs->oinfo); - } else if (rs->resv == XFS_AG_RESV_AGFL) { - xrep_block_reap_binval(sc, fsbno); + if (error) + return error; + + goto roll_out; + } + + trace_xrep_dispose_free_extent(sc->sa.pag, agbno, 1); + + xrep_block_reap_binval(sc, fsbno); + + if (rs->resv == XFS_AG_RESV_AGFL) { error = xrep_put_freelist(sc, agbno); } else { /* @@ -219,7 +228,6 @@ xrep_reap_block( * every 100 or so EFIs so that we don't exceed the log * reservation. */ - xrep_block_reap_binval(sc, fsbno); __xfs_free_extent_later(sc->tp, fsbno, 1, rs->oinfo, true); rs->deferred++; need_roll = rs->deferred > 100; @@ -227,6 +235,7 @@ xrep_reap_block( if (error || !need_roll) return error; +roll_out: rs->deferred = 0; return xrep_roll_ag_trans(sc); } diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h index 9c8c7dd0f262..71bfab3d2d29 100644 --- a/fs/xfs/scrub/trace.h +++ b/fs/xfs/scrub/trace.h @@ -729,9 +729,8 @@ TRACE_EVENT(xchk_refcount_incorrect, #if IS_ENABLED(CONFIG_XFS_ONLINE_REPAIR) DECLARE_EVENT_CLASS(xrep_extent_class, - TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, - xfs_agblock_t agbno, xfs_extlen_t len), - TP_ARGS(mp, agno, agbno, len), + TP_PROTO(struct xfs_perag *pag, xfs_agblock_t agbno, xfs_extlen_t len), + TP_ARGS(pag, agbno, len), TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_agnumber_t, agno) @@ -739,8 +738,8 @@ DECLARE_EVENT_CLASS(xrep_extent_class, __field(xfs_extlen_t, len) ), TP_fast_assign( - __entry->dev = mp->m_super->s_dev; - __entry->agno = agno; + __entry->dev = pag->pag_mount->m_super->s_dev; + __entry->agno = pag->pag_agno; __entry->agbno = agbno; __entry->len = len; ), @@ -752,10 +751,10 @@ DECLARE_EVENT_CLASS(xrep_extent_class, ); #define DEFINE_REPAIR_EXTENT_EVENT(name) \ DEFINE_EVENT(xrep_extent_class, name, \ - TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ - xfs_agblock_t agbno, xfs_extlen_t len), \ - TP_ARGS(mp, agno, agbno, len)) -DEFINE_REPAIR_EXTENT_EVENT(xrep_dispose_btree_extent); + TP_PROTO(struct xfs_perag *pag, xfs_agblock_t agbno, xfs_extlen_t len), \ + TP_ARGS(pag, agbno, len)) +DEFINE_REPAIR_EXTENT_EVENT(xrep_dispose_unmap_extent); +DEFINE_REPAIR_EXTENT_EVENT(xrep_dispose_free_extent); DEFINE_REPAIR_EXTENT_EVENT(xrep_agfl_insert); DECLARE_EVENT_CLASS(xrep_rmap_class,