Skip to content

Commit 9b2e5a2

Browse files
author
Darrick J. Wong
committed
xfs: create traced helper to get extra perag references
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>
1 parent 00e7b3b commit 9b2e5a2

9 files changed

Lines changed: 22 additions & 20 deletions

File tree

fs/xfs/libxfs/xfs_ag.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ xfs_perag_get_tag(
8181
return pag;
8282
}
8383

84+
/* Get a passive reference to the given perag. */
85+
struct xfs_perag *
86+
xfs_perag_hold(
87+
struct xfs_perag *pag)
88+
{
89+
ASSERT(atomic_read(&pag->pag_ref) > 0 ||
90+
atomic_read(&pag->pag_active_ref) > 0);
91+
92+
trace_xfs_perag_hold(pag, _RET_IP_);
93+
atomic_inc(&pag->pag_ref);
94+
return pag;
95+
}
96+
8497
void
8598
xfs_perag_put(
8699
struct xfs_perag *pag)

fs/xfs/libxfs/xfs_ag.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ void xfs_free_perag(struct xfs_mount *mp);
134134
struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno);
135135
struct xfs_perag *xfs_perag_get_tag(struct xfs_mount *mp, xfs_agnumber_t agno,
136136
unsigned int tag);
137+
struct xfs_perag *xfs_perag_hold(struct xfs_perag *pag);
137138
void xfs_perag_put(struct xfs_perag *pag);
138139

139140
/* Active AG references */

fs/xfs/libxfs/xfs_alloc_btree.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,9 +492,7 @@ xfs_allocbt_init_common(
492492
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2);
493493
}
494494

495-
/* take a reference for the cursor */
496-
atomic_inc(&pag->pag_ref);
497-
cur->bc_ag.pag = pag;
495+
cur->bc_ag.pag = xfs_perag_hold(pag);
498496

499497
if (xfs_has_crc(mp))
500498
cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;

fs/xfs/libxfs/xfs_ialloc_btree.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,9 +450,7 @@ xfs_inobt_init_common(
450450
if (xfs_has_crc(mp))
451451
cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
452452

453-
/* take a reference for the cursor */
454-
atomic_inc(&pag->pag_ref);
455-
cur->bc_ag.pag = pag;
453+
cur->bc_ag.pag = xfs_perag_hold(pag);
456454
return cur;
457455
}
458456

fs/xfs/libxfs/xfs_refcount_btree.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,10 +340,7 @@ xfs_refcountbt_init_common(
340340

341341
cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
342342

343-
/* take a reference for the cursor */
344-
atomic_inc(&pag->pag_ref);
345-
cur->bc_ag.pag = pag;
346-
343+
cur->bc_ag.pag = xfs_perag_hold(pag);
347344
cur->bc_ag.refc.nr_ops = 0;
348345
cur->bc_ag.refc.shape_changes = 0;
349346
cur->bc_ops = &xfs_refcountbt_ops;

fs/xfs/libxfs/xfs_rmap_btree.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -460,10 +460,7 @@ xfs_rmapbt_init_common(
460460
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2);
461461
cur->bc_ops = &xfs_rmapbt_ops;
462462

463-
/* take a reference for the cursor */
464-
atomic_inc(&pag->pag_ref);
465-
cur->bc_ag.pag = pag;
466-
463+
cur->bc_ag.pag = xfs_perag_hold(pag);
467464
return cur;
468465
}
469466

fs/xfs/xfs_iunlink_item.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,7 @@ xfs_iunlink_log_inode(
168168
iup->ip = ip;
169169
iup->next_agino = next_agino;
170170
iup->old_agino = ip->i_next_unlinked;
171-
172-
atomic_inc(&pag->pag_ref);
173-
iup->pag = pag;
171+
iup->pag = xfs_perag_hold(pag);
174172

175173
xfs_trans_add_item(tp, &iup->item);
176174
tp->t_flags |= XFS_TRANS_DIRTY;

fs/xfs/xfs_iwalk.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,11 +667,10 @@ xfs_iwalk_threaded(
667667
iwag->mp = mp;
668668

669669
/*
670-
* perag is being handed off to async work, so take another
670+
* perag is being handed off to async work, so take a passive
671671
* reference for the async work to release.
672672
*/
673-
atomic_inc(&pag->pag_ref);
674-
iwag->pag = pag;
673+
iwag->pag = xfs_perag_hold(pag);
675674
iwag->iwalk_fn = iwalk_fn;
676675
iwag->data = data;
677676
iwag->startino = startino;

fs/xfs/xfs_trace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ DEFINE_EVENT(xfs_perag_class, name, \
190190
TP_ARGS(pag, caller_ip))
191191
DEFINE_PERAG_REF_EVENT(xfs_perag_get);
192192
DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag);
193+
DEFINE_PERAG_REF_EVENT(xfs_perag_hold);
193194
DEFINE_PERAG_REF_EVENT(xfs_perag_put);
194195
DEFINE_PERAG_REF_EVENT(xfs_perag_grab);
195196
DEFINE_PERAG_REF_EVENT(xfs_perag_grab_tag);

0 commit comments

Comments
 (0)