From 9effc51e5867fdf1949fa432aeaddd536b754d25 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 5a8a029b1..97e8808fc 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); @@ -2734,8 +2778,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 f58b27102..ec724e5dc 100644 --- a/libxfs/xfs_rtgroup.c +++ b/libxfs/xfs_rtgroup.c @@ -165,6 +165,7 @@ xfs_initialize_rtgroups( spin_lock_init(&rtg->rtg_state_lock); init_waitqueue_head(&rtg->rtg_active_wq); 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 f0abe53ef..addcad627 100644 --- a/libxfs/xfs_rtgroup.h +++ b/libxfs/xfs_rtgroup.h @@ -57,6 +57,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