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>
This commit is contained in:
Родитель
00e7b3bac1
Коммит
9b2e5a234c
|
@ -81,6 +81,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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -492,9 +492,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;
|
||||
|
|
|
@ -450,9 +450,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -340,10 +340,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;
|
||||
|
|
|
@ -460,10 +460,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -168,9 +168,7 @@ xfs_iunlink_log_inode(
|
|||
iup->ip = ip;
|
||||
iup->next_agino = next_agino;
|
||||
iup->old_agino = ip->i_next_unlinked;
|
||||
|
||||
atomic_inc(&pag->pag_ref);
|
||||
iup->pag = pag;
|
||||
iup->pag = xfs_perag_hold(pag);
|
||||
|
||||
xfs_trans_add_item(tp, &iup->item);
|
||||
tp->t_flags |= XFS_TRANS_DIRTY;
|
||||
|
|
|
@ -667,11 +667,10 @@ xfs_iwalk_threaded(
|
|||
iwag->mp = mp;
|
||||
|
||||
/*
|
||||
* perag is being handed off to async work, so take another
|
||||
* perag is being handed off to async work, so take a passive
|
||||
* reference for the async work to release.
|
||||
*/
|
||||
atomic_inc(&pag->pag_ref);
|
||||
iwag->pag = pag;
|
||||
iwag->pag = xfs_perag_hold(pag);
|
||||
iwag->iwalk_fn = iwalk_fn;
|
||||
iwag->data = data;
|
||||
iwag->startino = startino;
|
||||
|
|
|
@ -190,6 +190,7 @@ DEFINE_EVENT(xfs_perag_class, name, \
|
|||
TP_ARGS(pag, caller_ip))
|
||||
DEFINE_PERAG_REF_EVENT(xfs_perag_get);
|
||||
DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag);
|
||||
DEFINE_PERAG_REF_EVENT(xfs_perag_hold);
|
||||
DEFINE_PERAG_REF_EVENT(xfs_perag_put);
|
||||
DEFINE_PERAG_REF_EVENT(xfs_perag_grab);
|
||||
DEFINE_PERAG_REF_EVENT(xfs_perag_grab_tag);
|
||||
|
|
Загрузка…
Ссылка в новой задаче