From 34249fa83a020467a48b81b8972abdccabeec21e Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 3 Jul 2024 14:22:34 -0700 Subject: [PATCH] xfs_repair: compute refcount data for the realtime groups At the end of phase 4, compute reference count information for realtime groups from the realtime rmap information collected, just like we do for AGs in the data section. Signed-off-by: Darrick J. Wong --- repair/phase4.c | 19 ++++++++++++++++++- repair/rmap.c | 17 ++++++++++++----- repair/rmap.h | 2 +- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/repair/phase4.c b/repair/phase4.c index b0cb805f3..e90533689 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -173,13 +173,28 @@ compute_ag_refcounts( { int error; - error = compute_refcounts(wq->wq_ctx, agno); + error = compute_refcounts(wq->wq_ctx, false, agno); if (error) do_error( _("%s while computing reference count records.\n"), strerror(error)); } +static void +compute_rt_refcounts( + struct workqueue*wq, + xfs_agnumber_t rgno, + void *arg) +{ + int error; + + error = compute_refcounts(wq->wq_ctx, true, rgno); + if (error) + do_error( +_("%s while computing realtime reference count records.\n"), + strerror(error)); +} + static void process_inode_reflink_flags( struct workqueue *wq, @@ -227,6 +242,8 @@ process_rmap_data( create_work_queue(&wq, mp, platform_nproc()); for (i = 0; i < mp->m_sb.sb_agcount; i++) queue_work(&wq, compute_ag_refcounts, i, NULL); + for (i = 0; i < mp->m_sb.sb_rgcount; i++) + queue_work(&wq, compute_rt_refcounts, i, NULL); destroy_work_queue(&wq); create_work_queue(&wq, mp, platform_nproc()); diff --git a/repair/rmap.c b/repair/rmap.c index ac4ed4bcf..519e02e71 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -142,6 +142,11 @@ rmaps_init_rt( if (error) goto nomem; + error = init_slab(&ag_rmap->ar_refcount_items, + sizeof(struct xfs_refcount_irec)); + if (error) + goto nomem; + ag_rmap->rg_rmap_ino = NULLFSINO; ag_rmap->rg_refcount_ino = NULLFSINO; return; @@ -1088,6 +1093,7 @@ mark_reflink_inodes( static void refcount_emit( struct xfs_mount *mp, + bool isrt, xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, @@ -1097,7 +1103,7 @@ refcount_emit( int error; struct xfs_slab *rlslab; - rlslab = rmaps_for_group(false, agno)->ar_refcount_items; + rlslab = rmaps_for_group(isrt, agno)->ar_refcount_items; ASSERT(nr_rmaps > 0); dbg_printf("REFL: agno=%u pblk=%u, len=%u -> refcount=%zu\n", @@ -1215,6 +1221,7 @@ refcount_push_rmaps_at( int compute_refcounts( struct xfs_mount *mp, + bool isrt, xfs_agnumber_t agno) { struct xfs_btree_cur *rmcur; @@ -1230,12 +1237,12 @@ compute_refcounts( if (!xfs_has_reflink(mp)) return 0; - if (!rmaps_has_observations(rmaps_for_group(false, agno))) + if (!rmaps_has_observations(rmaps_for_group(isrt, agno))) return 0; - nr_rmaps = rmap_record_count(mp, false, agno); + nr_rmaps = rmap_record_count(mp, isrt, agno); - error = rmap_init_mem_cursor(mp, NULL, false, agno, &rmcur); + error = rmap_init_mem_cursor(mp, NULL, isrt, agno, &rmcur); if (error) return error; @@ -1292,7 +1299,7 @@ compute_refcounts( ASSERT(nbno > cbno); if (rcbag_count(rcstack) != old_stack_height) { if (old_stack_height > 1) { - refcount_emit(mp, agno, cbno, + refcount_emit(mp, isrt, agno, cbno, nbno - cbno, old_stack_height); } diff --git a/repair/rmap.h b/repair/rmap.h index 75974fccb..836d0da82 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -38,7 +38,7 @@ extern int64_t rmap_diffkeys(struct xfs_rmap_irec *kp1, extern void rmap_high_key_from_rec(struct xfs_rmap_irec *rec, struct xfs_rmap_irec *key); -extern int compute_refcounts(struct xfs_mount *, xfs_agnumber_t); +int compute_refcounts(struct xfs_mount *mp, bool isrt, xfs_agnumber_t agno); uint64_t refcount_record_count(struct xfs_mount *mp, xfs_agnumber_t agno); extern int init_refcount_cursor(xfs_agnumber_t, struct xfs_slab_cursor **); extern void refcount_avoid_check(struct xfs_mount *mp); -- 2.50.1