]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: create traced helper to get extra perag references
authorDarrick J. Wong <djwong@kernel.org>
Tue, 30 May 2023 08:48:02 +0000 (10:48 +0200)
committerCarlos Maiolino <cem@kernel.org>
Fri, 9 Jun 2023 08:27:50 +0000 (10:27 +0200)
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 <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
include/xfs_trace.h
libxfs/xfs_ag.c
libxfs/xfs_ag.h
libxfs/xfs_alloc_btree.c
libxfs/xfs_ialloc_btree.c
libxfs/xfs_refcount_btree.c
libxfs/xfs_rmap_btree.c

index 4facca264c1b05d93c7ab78f7fc0a4f44a82b5c1..b3e5ff1f53272bdf0e3841663e11d49577dd599b 100644 (file)
 #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))
index e7801a67e4c9fc4f3560fce42ba995315d1d4268..b181c3e25f40806ba3bf527f7feb93148d491c4c 100644 (file)
@@ -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)
index 5e18536dfdcecce70572565cac837b20e59b4131..8092eaba977d4c004d1abbe04f80df9781d69c4b 100644 (file)
@@ -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 */
index f4ee585e908a7f3331e6b927bb250834c06a6532..99844b78afe143ce53c04ea67f2ae22f33ccbef7 100644 (file)
@@ -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;
index 3865a74621caa0d6995ac211d175f1aa869184b7..934ae98bebe656cbe4e7d464affaa3dc84099cbd 100644 (file)
@@ -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;
 }
 
index eb56e07db7f2a155ae00c5974ab03d1d9d86a3a8..bb9e3b2fe4359af930803ab11e2148ba9115db58 100644 (file)
@@ -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;
index a7e6e652f5c39069d3874ddef02bec2a8d49b290..8a0c1fbc02c3eba30ec4f76fb28d8fc21a7adde4 100644 (file)
@@ -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;
 }