From 69debeac4ee82fb79d8184c62f5fdd607e034376 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 3 Jul 2024 14:22:20 -0700 Subject: [PATCH] xfs: hook live realtime rmap operations during a repair operation Hook the regular realtime rmap code when an rtrmapbt repair operation is running so that we can unlock the AGF buffer to scan the filesystem and keep the in-memory btree up to date during the scan. Signed-off-by: Darrick J. Wong --- libxfs/xfs_rmap.c | 56 +++++++++++++++++++++++++++++++++++++++++--- libxfs/xfs_rmap.h | 6 +++++ libxfs/xfs_rtgroup.c | 1 + libxfs/xfs_rtgroup.h | 3 +++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c index f07561ff8..9eff45fcd 100644 --- a/libxfs/xfs_rmap.c +++ b/libxfs/xfs_rmap.c @@ -917,8 +917,7 @@ xfs_rmap_update_hook( .oinfo = *oinfo, /* struct copy */ }; - if (pag) - xfs_hooks_call(&pag->pag_rmap_update_hooks, op, &p); + xfs_hooks_call(&pag->pag_rmap_update_hooks, op, &p); } } @@ -952,6 +951,50 @@ xfs_rmap_hook_setup( # define xfs_rmap_update_hook(t, p, o, s, b, u, oi) do { } while (0) #endif /* CONFIG_XFS_LIVE_HOOKS */ +# if defined(CONFIG_XFS_LIVE_HOOKS) && defined(CONFIG_XFS_RT) +static inline void +xfs_rtrmap_update_hook( + struct xfs_trans *tp, + struct xfs_rtgroup *rtg, + enum xfs_rmap_intent_type op, + xfs_rgblock_t startblock, + xfs_extlen_t blockcount, + bool unwritten, + const struct xfs_owner_info *oinfo) +{ + if (xfs_hooks_switched_on(&xfs_rmap_hooks_switch)) { + struct xfs_rmap_update_params p = { + .startblock = startblock, + .blockcount = blockcount, + .unwritten = unwritten, + .oinfo = *oinfo, /* struct copy */ + }; + + xfs_hooks_call(&rtg->rtg_rmap_update_hooks, op, &p); + } +} + +/* Call the specified function during a rt reverse mapping update. */ +int +xfs_rtrmap_hook_add( + struct xfs_rtgroup *rtg, + struct xfs_rmap_hook *hook) +{ + return xfs_hooks_add(&rtg->rtg_rmap_update_hooks, &hook->rmap_hook); +} + +/* Stop calling the specified function during a rt reverse mapping update. */ +void +xfs_rtrmap_hook_del( + struct xfs_rtgroup *rtg, + struct xfs_rmap_hook *hook) +{ + xfs_hooks_del(&rtg->rtg_rmap_update_hooks, &hook->rmap_hook); +} +#else +# define xfs_rtrmap_update_hook(t, r, o, s, b, u, oi) do { } while (0) +#endif /* CONFIG_XFS_LIVE_HOOKS && CONFIG_XFS_RT */ + /* * Remove a reference to an extent in the rmap btree. */ @@ -2708,6 +2751,7 @@ xfs_rtrmap_finish_one( xfs_rgnumber_t rgno; xfs_rgblock_t bno; bool unwritten; + int error; trace_xfs_rmap_deferred(mp, ri); @@ -2733,8 +2777,14 @@ xfs_rtrmap_finish_one( unwritten = ri->ri_bmap.br_state == XFS_EXT_UNWRITTEN; bno = xfs_rtb_to_rgbno(mp, ri->ri_bmap.br_startblock, &rgno); - return __xfs_rmap_finish_intent(rcur, ri->ri_type, bno, + error = __xfs_rmap_finish_intent(rcur, ri->ri_type, bno, ri->ri_bmap.br_blockcount, &oinfo, unwritten); + if (error) + return error; + + xfs_rtrmap_update_hook(tp, ri->ri_rtg, ri->ri_type, bno, + ri->ri_bmap.br_blockcount, unwritten, &oinfo); + return 0; } /* diff --git a/libxfs/xfs_rmap.h b/libxfs/xfs_rmap.h index 82f7505ca..430816354 100644 --- a/libxfs/xfs_rmap.h +++ b/libxfs/xfs_rmap.h @@ -276,6 +276,12 @@ void xfs_rmap_hook_enable(void); int xfs_rmap_hook_add(struct xfs_perag *pag, struct xfs_rmap_hook *hook); void xfs_rmap_hook_del(struct xfs_perag *pag, struct xfs_rmap_hook *hook); void xfs_rmap_hook_setup(struct xfs_rmap_hook *hook, notifier_fn_t mod_fn); + +# ifdef CONFIG_XFS_RT +int xfs_rtrmap_hook_add(struct xfs_rtgroup *rtg, struct xfs_rmap_hook *hook); +void xfs_rtrmap_hook_del(struct xfs_rtgroup *rtg, struct xfs_rmap_hook *hook); +# endif /* CONFIG_XFS_RT */ + #endif #endif /* __XFS_RMAP_H__ */ diff --git a/libxfs/xfs_rtgroup.c b/libxfs/xfs_rtgroup.c index a7a227c2a..fe4608fca 100644 --- a/libxfs/xfs_rtgroup.c +++ b/libxfs/xfs_rtgroup.c @@ -164,6 +164,7 @@ xfs_initialize_rtgroups( memset(&rtg->lock_class, 0, sizeof(rtg->lock_class)); lockdep_register_key(&rtg->lock_class); xfs_defer_drain_init(&rtg->rtg_intents_drain); + xfs_hooks_init(&rtg->rtg_rmap_update_hooks); #endif /* __KERNEL__ */ /* Active ref owned by mount indicates rtgroup is online. */ diff --git a/libxfs/xfs_rtgroup.h b/libxfs/xfs_rtgroup.h index 4f8c7fff7..f9c5f5d54 100644 --- a/libxfs/xfs_rtgroup.h +++ b/libxfs/xfs_rtgroup.h @@ -50,6 +50,9 @@ struct xfs_rtgroup { * inconsistencies. */ struct xfs_defer_drain rtg_intents_drain; + + /* Hook to feed rt rmapbt updates to an active online repair. */ + struct xfs_hooks rtg_rmap_update_hooks; #endif /* __KERNEL__ */ }; -- 2.50.1