Commit 4cdbfe45 authored by Chandan Babu R's avatar Chandan Babu R
Browse files

Merge tag 'refcount-intent-cleanups-6.11_2024-07-02' of...

Merge tag 'refcount-intent-cleanups-6.11_2024-07-02' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux

 into xfs-6.11-mergeB

xfs: refcount log intent cleanups

This series cleans up the refcount intent code before we start adding
support for realtime devices.  Similar to previous intent cleanup
patchsets, we start transforming the tracepoints so that the data
extraction are done inside the tracepoint code, and then we start
passing the intent itself to the _finish_one function.  This reduces the
boxing and unboxing of parameters.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandanbabu@kernel.org>

* tag 'refcount-intent-cleanups-6.11_2024-07-02' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
  xfs: move xfs_refcount_update_defer_add to xfs_refcount_item.c
  xfs: simplify usage of the rcur local variable in xfs_refcount_finish_one
  xfs: don't bother calling xfs_refcount_finish_one_cleanup in xfs_refcount_finish_one
  xfs: reuse xfs_refcount_update_cancel_item
  xfs: add a ci_entry helper
  xfs: remove xfs_trans_set_refcount_flags
  xfs: clean up refcount log intent item tracepoint callsites
  xfs: pass btree cursors to refcount btree tracepoints
  xfs: create specialized classes for refcount tracepoints
  xfs: give refcount btree cursor error tracepoints their own class
parents 584aa150 783e8a7c
Loading
Loading
Loading
Loading
+46 −104
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "xfs_rmap.h"
#include "xfs_ag.h"
#include "xfs_health.h"
#include "xfs_refcount_item.h"

struct kmem_cache	*xfs_refcount_intent_cache;

@@ -51,7 +52,7 @@ xfs_refcount_lookup_le(
	xfs_agblock_t		bno,
	int			*stat)
{
	trace_xfs_refcount_lookup(cur->bc_mp, cur->bc_ag.pag->pag_agno,
	trace_xfs_refcount_lookup(cur,
			xfs_refcount_encode_startblock(bno, domain),
			XFS_LOOKUP_LE);
	cur->bc_rec.rc.rc_startblock = bno;
@@ -71,7 +72,7 @@ xfs_refcount_lookup_ge(
	xfs_agblock_t		bno,
	int			*stat)
{
	trace_xfs_refcount_lookup(cur->bc_mp, cur->bc_ag.pag->pag_agno,
	trace_xfs_refcount_lookup(cur,
			xfs_refcount_encode_startblock(bno, domain),
			XFS_LOOKUP_GE);
	cur->bc_rec.rc.rc_startblock = bno;
@@ -91,7 +92,7 @@ xfs_refcount_lookup_eq(
	xfs_agblock_t		bno,
	int			*stat)
{
	trace_xfs_refcount_lookup(cur->bc_mp, cur->bc_ag.pag->pag_agno,
	trace_xfs_refcount_lookup(cur,
			xfs_refcount_encode_startblock(bno, domain),
			XFS_LOOKUP_LE);
	cur->bc_rec.rc.rc_startblock = bno;
@@ -183,7 +184,7 @@ xfs_refcount_get_rec(
	if (fa)
		return xfs_refcount_complain_bad_rec(cur, fa, irec);

	trace_xfs_refcount_get(cur->bc_mp, cur->bc_ag.pag->pag_agno, irec);
	trace_xfs_refcount_get(cur, irec);
	return 0;
}

@@ -201,7 +202,7 @@ xfs_refcount_update(
	uint32_t		start;
	int			error;

	trace_xfs_refcount_update(cur->bc_mp, cur->bc_ag.pag->pag_agno, irec);
	trace_xfs_refcount_update(cur, irec);

	start = xfs_refcount_encode_startblock(irec->rc_startblock,
			irec->rc_domain);
@@ -211,8 +212,7 @@ xfs_refcount_update(

	error = xfs_btree_update(cur, &rec);
	if (error)
		trace_xfs_refcount_update_error(cur->bc_mp,
				cur->bc_ag.pag->pag_agno, error, _RET_IP_);
		trace_xfs_refcount_update_error(cur, error, _RET_IP_);
	return error;
}

@@ -229,7 +229,7 @@ xfs_refcount_insert(
{
	int				error;

	trace_xfs_refcount_insert(cur->bc_mp, cur->bc_ag.pag->pag_agno, irec);
	trace_xfs_refcount_insert(cur, irec);

	cur->bc_rec.rc.rc_startblock = irec->rc_startblock;
	cur->bc_rec.rc.rc_blockcount = irec->rc_blockcount;
@@ -247,8 +247,7 @@ xfs_refcount_insert(

out_error:
	if (error)
		trace_xfs_refcount_insert_error(cur->bc_mp,
				cur->bc_ag.pag->pag_agno, error, _RET_IP_);
		trace_xfs_refcount_insert_error(cur, error, _RET_IP_);
	return error;
}

@@ -275,7 +274,7 @@ xfs_refcount_delete(
		error = -EFSCORRUPTED;
		goto out_error;
	}
	trace_xfs_refcount_delete(cur->bc_mp, cur->bc_ag.pag->pag_agno, &irec);
	trace_xfs_refcount_delete(cur, &irec);
	error = xfs_btree_delete(cur, i);
	if (XFS_IS_CORRUPT(cur->bc_mp, *i != 1)) {
		xfs_btree_mark_sick(cur);
@@ -288,8 +287,7 @@ xfs_refcount_delete(
			&found_rec);
out_error:
	if (error)
		trace_xfs_refcount_delete_error(cur->bc_mp,
				cur->bc_ag.pag->pag_agno, error, _RET_IP_);
		trace_xfs_refcount_delete_error(cur, error, _RET_IP_);
	return error;
}

@@ -413,8 +411,7 @@ xfs_refcount_split_extent(
		return 0;

	*shape_changed = true;
	trace_xfs_refcount_split_extent(cur->bc_mp, cur->bc_ag.pag->pag_agno,
			&rcext, agbno);
	trace_xfs_refcount_split_extent(cur, &rcext, agbno);

	/* Establish the right extent. */
	tmp = rcext;
@@ -438,8 +435,7 @@ xfs_refcount_split_extent(
	return error;

out_error:
	trace_xfs_refcount_split_extent_error(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, error, _RET_IP_);
	trace_xfs_refcount_split_extent_error(cur, error, _RET_IP_);
	return error;
}

@@ -458,8 +454,7 @@ xfs_refcount_merge_center_extents(
	int				error;
	int				found_rec;

	trace_xfs_refcount_merge_center_extents(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, left, center, right);
	trace_xfs_refcount_merge_center_extents(cur, left, center, right);

	ASSERT(left->rc_domain == center->rc_domain);
	ASSERT(right->rc_domain == center->rc_domain);
@@ -522,8 +517,7 @@ xfs_refcount_merge_center_extents(
	return error;

out_error:
	trace_xfs_refcount_merge_center_extents_error(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, error, _RET_IP_);
	trace_xfs_refcount_merge_center_extents_error(cur, error, _RET_IP_);
	return error;
}

@@ -541,8 +535,7 @@ xfs_refcount_merge_left_extent(
	int				error;
	int				found_rec;

	trace_xfs_refcount_merge_left_extent(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, left, cleft);
	trace_xfs_refcount_merge_left_extent(cur, left, cleft);

	ASSERT(left->rc_domain == cleft->rc_domain);

@@ -589,8 +582,7 @@ xfs_refcount_merge_left_extent(
	return error;

out_error:
	trace_xfs_refcount_merge_left_extent_error(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, error, _RET_IP_);
	trace_xfs_refcount_merge_left_extent_error(cur, error, _RET_IP_);
	return error;
}

@@ -607,8 +599,7 @@ xfs_refcount_merge_right_extent(
	int				error;
	int				found_rec;

	trace_xfs_refcount_merge_right_extent(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, cright, right);
	trace_xfs_refcount_merge_right_extent(cur, cright, right);

	ASSERT(right->rc_domain == cright->rc_domain);

@@ -658,8 +649,7 @@ xfs_refcount_merge_right_extent(
	return error;

out_error:
	trace_xfs_refcount_merge_right_extent_error(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, error, _RET_IP_);
	trace_xfs_refcount_merge_right_extent_error(cur, error, _RET_IP_);
	return error;
}

@@ -748,13 +738,11 @@ xfs_refcount_find_left_extents(
		cleft->rc_refcount = 1;
		cleft->rc_domain = domain;
	}
	trace_xfs_refcount_find_left_extent(cur->bc_mp, cur->bc_ag.pag->pag_agno,
			left, cleft, agbno);
	trace_xfs_refcount_find_left_extent(cur, left, cleft, agbno);
	return error;

out_error:
	trace_xfs_refcount_find_left_extent_error(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, error, _RET_IP_);
	trace_xfs_refcount_find_left_extent_error(cur, error, _RET_IP_);
	return error;
}

@@ -843,13 +831,12 @@ xfs_refcount_find_right_extents(
		cright->rc_refcount = 1;
		cright->rc_domain = domain;
	}
	trace_xfs_refcount_find_right_extent(cur->bc_mp, cur->bc_ag.pag->pag_agno,
			cright, right, agbno + aglen);
	trace_xfs_refcount_find_right_extent(cur, cright, right,
			agbno + aglen);
	return error;

out_error:
	trace_xfs_refcount_find_right_extent_error(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, error, _RET_IP_);
	trace_xfs_refcount_find_right_extent_error(cur, error, _RET_IP_);
	return error;
}

@@ -1148,8 +1135,7 @@ xfs_refcount_adjust_extents(
			tmp.rc_refcount = 1 + adj;
			tmp.rc_domain = XFS_REFC_DOMAIN_SHARED;

			trace_xfs_refcount_modify_extent(cur->bc_mp,
					cur->bc_ag.pag->pag_agno, &tmp);
			trace_xfs_refcount_modify_extent(cur, &tmp);

			/*
			 * Either cover the hole (increment) or
@@ -1214,8 +1200,7 @@ xfs_refcount_adjust_extents(
		if (ext.rc_refcount == MAXREFCOUNT)
			goto skip;
		ext.rc_refcount += adj;
		trace_xfs_refcount_modify_extent(cur->bc_mp,
				cur->bc_ag.pag->pag_agno, &ext);
		trace_xfs_refcount_modify_extent(cur, &ext);
		cur->bc_refc.nr_ops++;
		if (ext.rc_refcount > 1) {
			error = xfs_refcount_update(cur, &ext);
@@ -1254,8 +1239,7 @@ xfs_refcount_adjust_extents(

	return error;
out_error:
	trace_xfs_refcount_modify_extent_error(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, error, _RET_IP_);
	trace_xfs_refcount_modify_extent_error(cur, error, _RET_IP_);
	return error;
}

@@ -1272,11 +1256,9 @@ xfs_refcount_adjust(
	int			error;

	if (adj == XFS_REFCOUNT_ADJUST_INCREASE)
		trace_xfs_refcount_increase(cur->bc_mp,
				cur->bc_ag.pag->pag_agno, *agbno, *aglen);
		trace_xfs_refcount_increase(cur, *agbno, *aglen);
	else
		trace_xfs_refcount_decrease(cur->bc_mp,
				cur->bc_ag.pag->pag_agno, *agbno, *aglen);
		trace_xfs_refcount_decrease(cur, *agbno, *aglen);

	/*
	 * Ensure that no rcextents cross the boundary of the adjustment range.
@@ -1315,28 +1297,10 @@ xfs_refcount_adjust(
	return 0;

out_error:
	trace_xfs_refcount_adjust_error(cur->bc_mp, cur->bc_ag.pag->pag_agno,
			error, _RET_IP_);
	trace_xfs_refcount_adjust_error(cur, error, _RET_IP_);
	return error;
}

/* Clean up after calling xfs_refcount_finish_one. */
void
xfs_refcount_finish_one_cleanup(
	struct xfs_trans	*tp,
	struct xfs_btree_cur	*rcur,
	int			error)
{
	struct xfs_buf		*agbp;

	if (rcur == NULL)
		return;
	agbp = rcur->bc_ag.agbp;
	xfs_btree_del_cursor(rcur, error);
	if (error)
		xfs_trans_brelse(tp, agbp);
}

/*
 * Set up a continuation a deferred refcount operation by updating the intent.
 * Checks to make sure we're not going to run off the end of the AG.
@@ -1378,7 +1342,7 @@ xfs_refcount_finish_one(
	struct xfs_btree_cur		**pcur)
{
	struct xfs_mount		*mp = tp->t_mountp;
	struct xfs_btree_cur		*rcur;
	struct xfs_btree_cur		*rcur = *pcur;
	struct xfs_buf			*agbp = NULL;
	int				error = 0;
	xfs_agblock_t			bno;
@@ -1387,9 +1351,7 @@ xfs_refcount_finish_one(

	bno = XFS_FSB_TO_AGBNO(mp, ri->ri_startblock);

	trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, ri->ri_startblock),
			ri->ri_type, XFS_FSB_TO_AGBNO(mp, ri->ri_startblock),
			ri->ri_blockcount);
	trace_xfs_refcount_deferred(mp, ri);

	if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE))
		return -EIO;
@@ -1398,11 +1360,10 @@ xfs_refcount_finish_one(
	 * If we haven't gotten a cursor or the cursor AG doesn't match
	 * the startblock, get one now.
	 */
	rcur = *pcur;
	if (rcur != NULL && rcur->bc_ag.pag != ri->ri_pag) {
		nr_ops = rcur->bc_refc.nr_ops;
		shape_changes = rcur->bc_refc.shape_changes;
		xfs_refcount_finish_one_cleanup(tp, rcur, 0);
		xfs_btree_del_cursor(rcur, 0);
		rcur = NULL;
		*pcur = NULL;
	}
@@ -1412,11 +1373,11 @@ xfs_refcount_finish_one(
		if (error)
			return error;

		rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, ri->ri_pag);
		*pcur = rcur = xfs_refcountbt_init_cursor(mp, tp, agbp,
							  ri->ri_pag);
		rcur->bc_refc.nr_ops = nr_ops;
		rcur->bc_refc.shape_changes = shape_changes;
	}
	*pcur = rcur;

	switch (ri->ri_type) {
	case XFS_REFCOUNT_INCREASE:
@@ -1452,8 +1413,7 @@ xfs_refcount_finish_one(
		return -EFSCORRUPTED;
	}
	if (!error && ri->ri_blockcount > 0)
		trace_xfs_refcount_finish_one_leftover(mp, ri->ri_pag->pag_agno,
				ri->ri_type, bno, ri->ri_blockcount);
		trace_xfs_refcount_finish_one_leftover(mp, ri);
	return error;
}

@@ -1469,11 +1429,6 @@ __xfs_refcount_add(
{
	struct xfs_refcount_intent	*ri;

	trace_xfs_refcount_defer(tp->t_mountp,
			XFS_FSB_TO_AGNO(tp->t_mountp, startblock),
			type, XFS_FSB_TO_AGBNO(tp->t_mountp, startblock),
			blockcount);

	ri = kmem_cache_alloc(xfs_refcount_intent_cache,
			GFP_KERNEL | __GFP_NOFAIL);
	INIT_LIST_HEAD(&ri->ri_list);
@@ -1481,8 +1436,7 @@ __xfs_refcount_add(
	ri->ri_startblock = startblock;
	ri->ri_blockcount = blockcount;

	xfs_refcount_update_get_group(tp->t_mountp, ri);
	xfs_defer_add(tp, &ri->ri_list, &xfs_refcount_update_defer_type);
	xfs_refcount_defer_add(tp, ri);
}

/*
@@ -1537,8 +1491,7 @@ xfs_refcount_find_shared(
	int				have;
	int				error;

	trace_xfs_refcount_find_shared(cur->bc_mp, cur->bc_ag.pag->pag_agno,
			agbno, aglen);
	trace_xfs_refcount_find_shared(cur, agbno, aglen);

	/* By default, skip the whole range */
	*fbno = NULLAGBLOCK;
@@ -1625,13 +1578,11 @@ xfs_refcount_find_shared(
	}

done:
	trace_xfs_refcount_find_shared_result(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, *fbno, *flen);
	trace_xfs_refcount_find_shared_result(cur, *fbno, *flen);

out_error:
	if (error)
		trace_xfs_refcount_find_shared_error(cur->bc_mp,
				cur->bc_ag.pag->pag_agno, error, _RET_IP_);
		trace_xfs_refcount_find_shared_error(cur, error, _RET_IP_);
	return error;
}

@@ -1737,8 +1688,7 @@ xfs_refcount_adjust_cow_extents(
		tmp.rc_refcount = 1;
		tmp.rc_domain = XFS_REFC_DOMAIN_COW;

		trace_xfs_refcount_modify_extent(cur->bc_mp,
				cur->bc_ag.pag->pag_agno, &tmp);
		trace_xfs_refcount_modify_extent(cur, &tmp);

		error = xfs_refcount_insert(cur, &tmp,
				&found_tmp);
@@ -1769,8 +1719,7 @@ xfs_refcount_adjust_cow_extents(
		}

		ext.rc_refcount = 0;
		trace_xfs_refcount_modify_extent(cur->bc_mp,
				cur->bc_ag.pag->pag_agno, &ext);
		trace_xfs_refcount_modify_extent(cur, &ext);
		error = xfs_refcount_delete(cur, &found_rec);
		if (error)
			goto out_error;
@@ -1786,8 +1735,7 @@ xfs_refcount_adjust_cow_extents(

	return error;
out_error:
	trace_xfs_refcount_modify_extent_error(cur->bc_mp,
			cur->bc_ag.pag->pag_agno, error, _RET_IP_);
	trace_xfs_refcount_modify_extent_error(cur, error, _RET_IP_);
	return error;
}

@@ -1833,8 +1781,7 @@ xfs_refcount_adjust_cow(
	return 0;

out_error:
	trace_xfs_refcount_adjust_cow_error(cur->bc_mp, cur->bc_ag.pag->pag_agno,
			error, _RET_IP_);
	trace_xfs_refcount_adjust_cow_error(cur, error, _RET_IP_);
	return error;
}

@@ -1847,8 +1794,7 @@ __xfs_refcount_cow_alloc(
	xfs_agblock_t		agbno,
	xfs_extlen_t		aglen)
{
	trace_xfs_refcount_cow_increase(rcur->bc_mp, rcur->bc_ag.pag->pag_agno,
			agbno, aglen);
	trace_xfs_refcount_cow_increase(rcur, agbno, aglen);

	/* Add refcount btree reservation */
	return xfs_refcount_adjust_cow(rcur, agbno, aglen,
@@ -1864,8 +1810,7 @@ __xfs_refcount_cow_free(
	xfs_agblock_t		agbno,
	xfs_extlen_t		aglen)
{
	trace_xfs_refcount_cow_decrease(rcur->bc_mp, rcur->bc_ag.pag->pag_agno,
			agbno, aglen);
	trace_xfs_refcount_cow_decrease(rcur, agbno, aglen);

	/* Remove refcount btree reservation */
	return xfs_refcount_adjust_cow(rcur, agbno, aglen,
@@ -2010,9 +1955,6 @@ xfs_refcount_recover_cow_leftovers(
		if (error)
			goto out_free;

		trace_xfs_refcount_recover_extent(mp, pag->pag_agno,
				&rr->rr_rrec);

		/* Free the orphan record */
		fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno,
				rr->rr_rrec.rc_startblock);
+6 −5
Original line number Diff line number Diff line
@@ -48,6 +48,12 @@ enum xfs_refcount_intent_type {
	XFS_REFCOUNT_FREE_COW,
};

#define XFS_REFCOUNT_INTENT_STRINGS \
	{ XFS_REFCOUNT_INCREASE,	"incr" }, \
	{ XFS_REFCOUNT_DECREASE,	"decr" }, \
	{ XFS_REFCOUNT_ALLOC_COW,	"alloc_cow" }, \
	{ XFS_REFCOUNT_FREE_COW,	"free_cow" }

struct xfs_refcount_intent {
	struct list_head			ri_list;
	struct xfs_perag			*ri_pag;
@@ -68,16 +74,11 @@ xfs_refcount_check_domain(
	return true;
}

void xfs_refcount_update_get_group(struct xfs_mount *mp,
		struct xfs_refcount_intent *ri);

void xfs_refcount_increase_extent(struct xfs_trans *tp,
		struct xfs_bmbt_irec *irec);
void xfs_refcount_decrease_extent(struct xfs_trans *tp,
		struct xfs_bmbt_irec *irec);

extern void xfs_refcount_finish_one_cleanup(struct xfs_trans *tp,
		struct xfs_btree_cur *rcur, int error);
extern int xfs_refcount_finish_one(struct xfs_trans *tp,
		struct xfs_refcount_intent *ri, struct xfs_btree_cur **pcur);

+56 −51
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@
#include "xfs_log_priv.h"
#include "xfs_log_recover.h"
#include "xfs_ag.h"
#include "xfs_btree.h"
#include "xfs_trace.h"

struct kmem_cache	*xfs_cui_cache;
struct kmem_cache	*xfs_cud_cache;
@@ -227,6 +229,11 @@ static const struct xfs_item_ops xfs_cud_item_ops = {
	.iop_intent	= xfs_cud_item_intent,
};

static inline struct xfs_refcount_intent *ci_entry(const struct list_head *e)
{
	return list_entry(e, struct xfs_refcount_intent, ri_list);
}

/* Sort refcount intents by AG. */
static int
xfs_refcount_update_diff_items(
@@ -234,34 +241,12 @@ xfs_refcount_update_diff_items(
	const struct list_head		*a,
	const struct list_head		*b)
{
	struct xfs_refcount_intent	*ra;
	struct xfs_refcount_intent	*rb;

	ra = container_of(a, struct xfs_refcount_intent, ri_list);
	rb = container_of(b, struct xfs_refcount_intent, ri_list);
	struct xfs_refcount_intent	*ra = ci_entry(a);
	struct xfs_refcount_intent	*rb = ci_entry(b);

	return ra->ri_pag->pag_agno - rb->ri_pag->pag_agno;
}

/* Set the phys extent flags for this reverse mapping. */
static void
xfs_trans_set_refcount_flags(
	struct xfs_phys_extent		*pmap,
	enum xfs_refcount_intent_type	type)
{
	pmap->pe_flags = 0;
	switch (type) {
	case XFS_REFCOUNT_INCREASE:
	case XFS_REFCOUNT_DECREASE:
	case XFS_REFCOUNT_ALLOC_COW:
	case XFS_REFCOUNT_FREE_COW:
		pmap->pe_flags |= type;
		break;
	default:
		ASSERT(0);
	}
}

/* Log refcount updates in the intent item. */
STATIC void
xfs_refcount_update_log_item(
@@ -282,7 +267,18 @@ xfs_refcount_update_log_item(
	pmap = &cuip->cui_format.cui_extents[next_extent];
	pmap->pe_startblock = ri->ri_startblock;
	pmap->pe_len = ri->ri_blockcount;
	xfs_trans_set_refcount_flags(pmap, ri->ri_type);

	pmap->pe_flags = 0;
	switch (ri->ri_type) {
	case XFS_REFCOUNT_INCREASE:
	case XFS_REFCOUNT_DECREASE:
	case XFS_REFCOUNT_ALLOC_COW:
	case XFS_REFCOUNT_FREE_COW:
		pmap->pe_flags |= ri->ri_type;
		break;
	default:
		ASSERT(0);
	}
}

static struct xfs_log_item *
@@ -324,21 +320,29 @@ xfs_refcount_update_create_done(
	return &cudp->cud_item;
}

/* Take a passive ref to the AG containing the space we're refcounting. */
/* Add this deferred CUI to the transaction. */
void
xfs_refcount_update_get_group(
	struct xfs_mount		*mp,
xfs_refcount_defer_add(
	struct xfs_trans		*tp,
	struct xfs_refcount_intent	*ri)
{
	struct xfs_mount		*mp = tp->t_mountp;

	trace_xfs_refcount_defer(mp, ri);

	ri->ri_pag = xfs_perag_intent_get(mp, ri->ri_startblock);
	xfs_defer_add(tp, &ri->ri_list, &xfs_refcount_update_defer_type);
}

/* Release a passive AG ref after finishing refcounting work. */
static inline void
xfs_refcount_update_put_group(
	struct xfs_refcount_intent	*ri)
/* Cancel a deferred refcount update. */
STATIC void
xfs_refcount_update_cancel_item(
	struct list_head		*item)
{
	struct xfs_refcount_intent	*ri = ci_entry(item);

	xfs_perag_intent_put(ri->ri_pag);
	kmem_cache_free(xfs_refcount_intent_cache, ri);
}

/* Process a deferred refcount update. */
@@ -349,11 +353,9 @@ xfs_refcount_update_finish_item(
	struct list_head		*item,
	struct xfs_btree_cur		**state)
{
	struct xfs_refcount_intent	*ri;
	struct xfs_refcount_intent	*ri = ci_entry(item);
	int				error;

	ri = container_of(item, struct xfs_refcount_intent, ri_list);

	/* Did we run out of reservation?  Requeue what we didn't finish. */
	error = xfs_refcount_finish_one(tp, ri, state);
	if (!error && ri->ri_blockcount > 0) {
@@ -362,30 +364,33 @@ xfs_refcount_update_finish_item(
		return -EAGAIN;
	}

	xfs_refcount_update_put_group(ri);
	kmem_cache_free(xfs_refcount_intent_cache, ri);
	xfs_refcount_update_cancel_item(item);
	return error;
}

/* Abort all pending CUIs. */
/* Clean up after calling xfs_refcount_finish_one. */
STATIC void
xfs_refcount_update_abort_intent(
	struct xfs_log_item		*intent)
xfs_refcount_finish_one_cleanup(
	struct xfs_trans	*tp,
	struct xfs_btree_cur	*rcur,
	int			error)
{
	xfs_cui_release(CUI_ITEM(intent));
	struct xfs_buf		*agbp;

	if (rcur == NULL)
		return;
	agbp = rcur->bc_ag.agbp;
	xfs_btree_del_cursor(rcur, error);
	if (error)
		xfs_trans_brelse(tp, agbp);
}

/* Cancel a deferred refcount update. */
/* Abort all pending CUIs. */
STATIC void
xfs_refcount_update_cancel_item(
	struct list_head		*item)
xfs_refcount_update_abort_intent(
	struct xfs_log_item		*intent)
{
	struct xfs_refcount_intent	*ri;

	ri = container_of(item, struct xfs_refcount_intent, ri_list);

	xfs_refcount_update_put_group(ri);
	kmem_cache_free(xfs_refcount_intent_cache, ri);
	xfs_cui_release(CUI_ITEM(intent));
}

/* Is this recovered CUI ok? */
@@ -426,7 +431,7 @@ xfs_cui_recover_work(
	ri->ri_type = pmap->pe_flags & XFS_REFCOUNT_EXTENT_TYPE_MASK;
	ri->ri_startblock = pmap->pe_startblock;
	ri->ri_blockcount = pmap->pe_len;
	xfs_refcount_update_get_group(mp, ri);
	ri->ri_pag = xfs_perag_intent_get(mp, pmap->pe_startblock);

	xfs_defer_add_item(dfp, &ri->ri_list);
}
+5 −0
Original line number Diff line number Diff line
@@ -71,4 +71,9 @@ struct xfs_cud_log_item {
extern struct kmem_cache	*xfs_cui_cache;
extern struct kmem_cache	*xfs_cud_cache;

struct xfs_refcount_intent;

void xfs_refcount_defer_add(struct xfs_trans *tp,
		struct xfs_refcount_intent *ri);

#endif	/* __XFS_REFCOUNT_ITEM_H__ */
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#include "xfs_exchrange.h"
#include "xfs_parent.h"
#include "xfs_rmap.h"
#include "xfs_refcount.h"

/*
 * We include this last to have the helpers above available for the trace
Loading