From: Darrick J. Wong <djwong@xxxxxxxxxx> 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" <djwong@xxxxxxxxxx> --- repair/phase4.c | 21 ++++++++++++++++++++- repair/rmap.c | 17 ++++++++++++----- repair/rmap.h | 2 +- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/repair/phase4.c b/repair/phase4.c index 29efa58af33178..4cfad1a6911764 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -177,13 +177,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, @@ -233,6 +248,10 @@ 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); + if (xfs_has_rtreflink(mp)) { + 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 e39c74cc7b44f7..64a9f06d0ee915 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -125,6 +125,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; + return; nomem: do_error( @@ -878,6 +883,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, @@ -887,7 +893,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", @@ -1005,6 +1011,7 @@ refcount_push_rmaps_at( int compute_refcounts( struct xfs_mount *mp, + bool isrt, xfs_agnumber_t agno) { struct xfs_btree_cur *rmcur; @@ -1020,12 +1027,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; @@ -1082,7 +1089,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 c0984d97322861..98f2891692a6f8 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);