From 6b44054b2dd868cb1b46de8e7cd2dfceaa046e90 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 15 Aug 2024 11:57:36 -0700 Subject: [PATCH] xfs: hook live realtime rmap operations during a repair operation Source kernel commit: 95ca3a8b151f34e4084aeade83ef25893a41f37e 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 Signed-off-by: Christoph Hellwig --- 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 ed9fc39b5..751a7a91c 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. */ @@ -2707,6 +2750,7 @@ xfs_rtrmap_finish_one( struct xfs_btree_cur *rcur = *pcur; 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); - 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 5b24e0614..1eb1fb514 100644 --- a/libxfs/xfs_rtgroup.c +++ b/libxfs/xfs_rtgroup.c @@ -143,6 +143,7 @@ xfs_rtgroup_alloc( 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 aad16b0ec..172d9be22 100644 --- a/libxfs/xfs_rtgroup.h +++ b/libxfs/xfs_rtgroup.h @@ -65,6 +65,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