From: Darrick J. Wong Date: Tue, 30 May 2023 08:48:02 +0000 (+0200) Subject: xfs: create traced helper to get extra perag references X-Git-Tag: v6.4.0~56 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=11e716f40c71da49b073eb287c14a908c1fbeb01;p=thirdparty%2Fxfsprogs-dev.git xfs: create traced helper to get extra perag references Source kernel commit: 9b2e5a234c89f097ec36f922763dfa1465dc06f8 There are a few places in the XFS codebase where a caller has either an active or a passive reference to a perag structure and wants to give a passive reference to some other piece of code. Btree cursor creation and inode walks are good examples of this. Replace the open-coded logic with a helper to do this. The new function adds a few safeguards -- it checks that there's at least one reference to the perag structure passed in, and it records the refcount bump in the ftrace information. This makes it much easier to debug perag refcounting problems. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner Signed-off-by: Carlos Maiolino --- diff --git a/include/xfs_trace.h b/include/xfs_trace.h index 4facca264..b3e5ff1f5 100644 --- a/include/xfs_trace.h +++ b/include/xfs_trace.h @@ -189,6 +189,7 @@ #define trace_xfs_write_extent(a,b,c,d) ((c) = (c)) #define trace_xfs_perag_get(c,d) ((c) = (c)) #define trace_xfs_perag_get_tag(c,d) ((c) = (c)) +#define trace_xfs_perag_hold(...) ((void) 0) #define trace_xfs_perag_grab(...) ((void) 0) #define trace_xfs_perag_grab_tag(...) ((void) 0) #define trace_xfs_perag_put(c,d) ((c) = (c)) diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c index e7801a67e..b181c3e25 100644 --- a/libxfs/xfs_ag.c +++ b/libxfs/xfs_ag.c @@ -79,6 +79,19 @@ xfs_perag_get_tag( return pag; } +/* Get a passive reference to the given perag. */ +struct xfs_perag * +xfs_perag_hold( + struct xfs_perag *pag) +{ + ASSERT(atomic_read(&pag->pag_ref) > 0 || + atomic_read(&pag->pag_active_ref) > 0); + + trace_xfs_perag_hold(pag, _RET_IP_); + atomic_inc(&pag->pag_ref); + return pag; +} + void xfs_perag_put( struct xfs_perag *pag) diff --git a/libxfs/xfs_ag.h b/libxfs/xfs_ag.h index 5e18536df..8092eaba9 100644 --- a/libxfs/xfs_ag.h +++ b/libxfs/xfs_ag.h @@ -134,6 +134,7 @@ void xfs_free_perag(struct xfs_mount *mp); struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno); struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno, unsigned int tag); +struct xfs_perag *xfs_perag_hold(struct xfs_perag *pag); void xfs_perag_put(struct xfs_perag *pag); /* Active AG references */ diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c index f4ee585e9..99844b78a 100644 --- a/libxfs/xfs_alloc_btree.c +++ b/libxfs/xfs_alloc_btree.c @@ -490,9 +490,7 @@ xfs_allocbt_init_common( cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2); } - /* take a reference for the cursor */ - atomic_inc(&pag->pag_ref); - cur->bc_ag.pag = pag; + cur->bc_ag.pag = xfs_perag_hold(pag); if (xfs_has_crc(mp)) cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c index 3865a7462..934ae98be 100644 --- a/libxfs/xfs_ialloc_btree.c +++ b/libxfs/xfs_ialloc_btree.c @@ -449,9 +449,7 @@ xfs_inobt_init_common( if (xfs_has_crc(mp)) cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; - /* take a reference for the cursor */ - atomic_inc(&pag->pag_ref); - cur->bc_ag.pag = pag; + cur->bc_ag.pag = xfs_perag_hold(pag); return cur; } diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c index eb56e07db..bb9e3b2fe 100644 --- a/libxfs/xfs_refcount_btree.c +++ b/libxfs/xfs_refcount_btree.c @@ -339,10 +339,7 @@ xfs_refcountbt_init_common( cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; - /* take a reference for the cursor */ - atomic_inc(&pag->pag_ref); - cur->bc_ag.pag = pag; - + cur->bc_ag.pag = xfs_perag_hold(pag); cur->bc_ag.refc.nr_ops = 0; cur->bc_ag.refc.shape_changes = 0; cur->bc_ops = &xfs_refcountbt_ops; diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c index a7e6e652f..8a0c1fbc0 100644 --- a/libxfs/xfs_rmap_btree.c +++ b/libxfs/xfs_rmap_btree.c @@ -458,10 +458,7 @@ xfs_rmapbt_init_common( cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2); cur->bc_ops = &xfs_rmapbt_ops; - /* take a reference for the cursor */ - atomic_inc(&pag->pag_ref); - cur->bc_ag.pag = pag; - + cur->bc_ag.pag = xfs_perag_hold(pag); return cur; }