xref: /kernel/linux/linux-6.6/fs/xfs/xfs_trans.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
462306a36Sopenharmony_ci * Copyright (C) 2010 Red Hat, Inc.
562306a36Sopenharmony_ci * All Rights Reserved.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#include "xfs.h"
862306a36Sopenharmony_ci#include "xfs_fs.h"
962306a36Sopenharmony_ci#include "xfs_shared.h"
1062306a36Sopenharmony_ci#include "xfs_format.h"
1162306a36Sopenharmony_ci#include "xfs_log_format.h"
1262306a36Sopenharmony_ci#include "xfs_trans_resv.h"
1362306a36Sopenharmony_ci#include "xfs_mount.h"
1462306a36Sopenharmony_ci#include "xfs_extent_busy.h"
1562306a36Sopenharmony_ci#include "xfs_quota.h"
1662306a36Sopenharmony_ci#include "xfs_trans.h"
1762306a36Sopenharmony_ci#include "xfs_trans_priv.h"
1862306a36Sopenharmony_ci#include "xfs_log.h"
1962306a36Sopenharmony_ci#include "xfs_log_priv.h"
2062306a36Sopenharmony_ci#include "xfs_trace.h"
2162306a36Sopenharmony_ci#include "xfs_error.h"
2262306a36Sopenharmony_ci#include "xfs_defer.h"
2362306a36Sopenharmony_ci#include "xfs_inode.h"
2462306a36Sopenharmony_ci#include "xfs_dquot_item.h"
2562306a36Sopenharmony_ci#include "xfs_dquot.h"
2662306a36Sopenharmony_ci#include "xfs_icache.h"
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistruct kmem_cache	*xfs_trans_cache;
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#if defined(CONFIG_TRACEPOINTS)
3162306a36Sopenharmony_cistatic void
3262306a36Sopenharmony_cixfs_trans_trace_reservations(
3362306a36Sopenharmony_ci	struct xfs_mount	*mp)
3462306a36Sopenharmony_ci{
3562306a36Sopenharmony_ci	struct xfs_trans_res	*res;
3662306a36Sopenharmony_ci	struct xfs_trans_res	*end_res;
3762306a36Sopenharmony_ci	int			i;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	res = (struct xfs_trans_res *)M_RES(mp);
4062306a36Sopenharmony_ci	end_res = (struct xfs_trans_res *)(M_RES(mp) + 1);
4162306a36Sopenharmony_ci	for (i = 0; res < end_res; i++, res++)
4262306a36Sopenharmony_ci		trace_xfs_trans_resv_calc(mp, i, res);
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci#else
4562306a36Sopenharmony_ci# define xfs_trans_trace_reservations(mp)
4662306a36Sopenharmony_ci#endif
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci/*
4962306a36Sopenharmony_ci * Initialize the precomputed transaction reservation values
5062306a36Sopenharmony_ci * in the mount structure.
5162306a36Sopenharmony_ci */
5262306a36Sopenharmony_civoid
5362306a36Sopenharmony_cixfs_trans_init(
5462306a36Sopenharmony_ci	struct xfs_mount	*mp)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	xfs_trans_resv_calc(mp, M_RES(mp));
5762306a36Sopenharmony_ci	xfs_trans_trace_reservations(mp);
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci/*
6162306a36Sopenharmony_ci * Free the transaction structure.  If there is more clean up
6262306a36Sopenharmony_ci * to do when the structure is freed, add it here.
6362306a36Sopenharmony_ci */
6462306a36Sopenharmony_ciSTATIC void
6562306a36Sopenharmony_cixfs_trans_free(
6662306a36Sopenharmony_ci	struct xfs_trans	*tp)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	xfs_extent_busy_sort(&tp->t_busy);
6962306a36Sopenharmony_ci	xfs_extent_busy_clear(tp->t_mountp, &tp->t_busy, false);
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	trace_xfs_trans_free(tp, _RET_IP_);
7262306a36Sopenharmony_ci	xfs_trans_clear_context(tp);
7362306a36Sopenharmony_ci	if (!(tp->t_flags & XFS_TRANS_NO_WRITECOUNT))
7462306a36Sopenharmony_ci		sb_end_intwrite(tp->t_mountp->m_super);
7562306a36Sopenharmony_ci	xfs_trans_free_dqinfo(tp);
7662306a36Sopenharmony_ci	kmem_cache_free(xfs_trans_cache, tp);
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/*
8062306a36Sopenharmony_ci * This is called to create a new transaction which will share the
8162306a36Sopenharmony_ci * permanent log reservation of the given transaction.  The remaining
8262306a36Sopenharmony_ci * unused block and rt extent reservations are also inherited.  This
8362306a36Sopenharmony_ci * implies that the original transaction is no longer allowed to allocate
8462306a36Sopenharmony_ci * blocks.  Locks and log items, however, are no inherited.  They must
8562306a36Sopenharmony_ci * be added to the new transaction explicitly.
8662306a36Sopenharmony_ci */
8762306a36Sopenharmony_ciSTATIC struct xfs_trans *
8862306a36Sopenharmony_cixfs_trans_dup(
8962306a36Sopenharmony_ci	struct xfs_trans	*tp)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	struct xfs_trans	*ntp;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	trace_xfs_trans_dup(tp, _RET_IP_);
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	ntp = kmem_cache_zalloc(xfs_trans_cache, GFP_KERNEL | __GFP_NOFAIL);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	/*
9862306a36Sopenharmony_ci	 * Initialize the new transaction structure.
9962306a36Sopenharmony_ci	 */
10062306a36Sopenharmony_ci	ntp->t_magic = XFS_TRANS_HEADER_MAGIC;
10162306a36Sopenharmony_ci	ntp->t_mountp = tp->t_mountp;
10262306a36Sopenharmony_ci	INIT_LIST_HEAD(&ntp->t_items);
10362306a36Sopenharmony_ci	INIT_LIST_HEAD(&ntp->t_busy);
10462306a36Sopenharmony_ci	INIT_LIST_HEAD(&ntp->t_dfops);
10562306a36Sopenharmony_ci	ntp->t_highest_agno = NULLAGNUMBER;
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
10862306a36Sopenharmony_ci	ASSERT(tp->t_ticket != NULL);
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	ntp->t_flags = XFS_TRANS_PERM_LOG_RES |
11162306a36Sopenharmony_ci		       (tp->t_flags & XFS_TRANS_RESERVE) |
11262306a36Sopenharmony_ci		       (tp->t_flags & XFS_TRANS_NO_WRITECOUNT) |
11362306a36Sopenharmony_ci		       (tp->t_flags & XFS_TRANS_RES_FDBLKS);
11462306a36Sopenharmony_ci	/* We gave our writer reference to the new transaction */
11562306a36Sopenharmony_ci	tp->t_flags |= XFS_TRANS_NO_WRITECOUNT;
11662306a36Sopenharmony_ci	ntp->t_ticket = xfs_log_ticket_get(tp->t_ticket);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	ASSERT(tp->t_blk_res >= tp->t_blk_res_used);
11962306a36Sopenharmony_ci	ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used;
12062306a36Sopenharmony_ci	tp->t_blk_res = tp->t_blk_res_used;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
12362306a36Sopenharmony_ci	tp->t_rtx_res = tp->t_rtx_res_used;
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	xfs_trans_switch_context(tp, ntp);
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci	/* move deferred ops over to the new tp */
12862306a36Sopenharmony_ci	xfs_defer_move(ntp, tp);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	xfs_trans_dup_dqinfo(tp, ntp);
13162306a36Sopenharmony_ci	return ntp;
13262306a36Sopenharmony_ci}
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci/*
13562306a36Sopenharmony_ci * This is called to reserve free disk blocks and log space for the
13662306a36Sopenharmony_ci * given transaction.  This must be done before allocating any resources
13762306a36Sopenharmony_ci * within the transaction.
13862306a36Sopenharmony_ci *
13962306a36Sopenharmony_ci * This will return ENOSPC if there are not enough blocks available.
14062306a36Sopenharmony_ci * It will sleep waiting for available log space.
14162306a36Sopenharmony_ci * The only valid value for the flags parameter is XFS_RES_LOG_PERM, which
14262306a36Sopenharmony_ci * is used by long running transactions.  If any one of the reservations
14362306a36Sopenharmony_ci * fails then they will all be backed out.
14462306a36Sopenharmony_ci *
14562306a36Sopenharmony_ci * This does not do quota reservations. That typically is done by the
14662306a36Sopenharmony_ci * caller afterwards.
14762306a36Sopenharmony_ci */
14862306a36Sopenharmony_cistatic int
14962306a36Sopenharmony_cixfs_trans_reserve(
15062306a36Sopenharmony_ci	struct xfs_trans	*tp,
15162306a36Sopenharmony_ci	struct xfs_trans_res	*resp,
15262306a36Sopenharmony_ci	uint			blocks,
15362306a36Sopenharmony_ci	uint			rtextents)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci	struct xfs_mount	*mp = tp->t_mountp;
15662306a36Sopenharmony_ci	int			error = 0;
15762306a36Sopenharmony_ci	bool			rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	/*
16062306a36Sopenharmony_ci	 * Attempt to reserve the needed disk blocks by decrementing
16162306a36Sopenharmony_ci	 * the number needed from the number available.  This will
16262306a36Sopenharmony_ci	 * fail if the count would go below zero.
16362306a36Sopenharmony_ci	 */
16462306a36Sopenharmony_ci	if (blocks > 0) {
16562306a36Sopenharmony_ci		error = xfs_mod_fdblocks(mp, -((int64_t)blocks), rsvd);
16662306a36Sopenharmony_ci		if (error != 0)
16762306a36Sopenharmony_ci			return -ENOSPC;
16862306a36Sopenharmony_ci		tp->t_blk_res += blocks;
16962306a36Sopenharmony_ci	}
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	/*
17262306a36Sopenharmony_ci	 * Reserve the log space needed for this transaction.
17362306a36Sopenharmony_ci	 */
17462306a36Sopenharmony_ci	if (resp->tr_logres > 0) {
17562306a36Sopenharmony_ci		bool	permanent = false;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci		ASSERT(tp->t_log_res == 0 ||
17862306a36Sopenharmony_ci		       tp->t_log_res == resp->tr_logres);
17962306a36Sopenharmony_ci		ASSERT(tp->t_log_count == 0 ||
18062306a36Sopenharmony_ci		       tp->t_log_count == resp->tr_logcount);
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci		if (resp->tr_logflags & XFS_TRANS_PERM_LOG_RES) {
18362306a36Sopenharmony_ci			tp->t_flags |= XFS_TRANS_PERM_LOG_RES;
18462306a36Sopenharmony_ci			permanent = true;
18562306a36Sopenharmony_ci		} else {
18662306a36Sopenharmony_ci			ASSERT(tp->t_ticket == NULL);
18762306a36Sopenharmony_ci			ASSERT(!(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
18862306a36Sopenharmony_ci		}
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci		if (tp->t_ticket != NULL) {
19162306a36Sopenharmony_ci			ASSERT(resp->tr_logflags & XFS_TRANS_PERM_LOG_RES);
19262306a36Sopenharmony_ci			error = xfs_log_regrant(mp, tp->t_ticket);
19362306a36Sopenharmony_ci		} else {
19462306a36Sopenharmony_ci			error = xfs_log_reserve(mp, resp->tr_logres,
19562306a36Sopenharmony_ci						resp->tr_logcount,
19662306a36Sopenharmony_ci						&tp->t_ticket, permanent);
19762306a36Sopenharmony_ci		}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci		if (error)
20062306a36Sopenharmony_ci			goto undo_blocks;
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci		tp->t_log_res = resp->tr_logres;
20362306a36Sopenharmony_ci		tp->t_log_count = resp->tr_logcount;
20462306a36Sopenharmony_ci	}
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci	/*
20762306a36Sopenharmony_ci	 * Attempt to reserve the needed realtime extents by decrementing
20862306a36Sopenharmony_ci	 * the number needed from the number available.  This will
20962306a36Sopenharmony_ci	 * fail if the count would go below zero.
21062306a36Sopenharmony_ci	 */
21162306a36Sopenharmony_ci	if (rtextents > 0) {
21262306a36Sopenharmony_ci		error = xfs_mod_frextents(mp, -((int64_t)rtextents));
21362306a36Sopenharmony_ci		if (error) {
21462306a36Sopenharmony_ci			error = -ENOSPC;
21562306a36Sopenharmony_ci			goto undo_log;
21662306a36Sopenharmony_ci		}
21762306a36Sopenharmony_ci		tp->t_rtx_res += rtextents;
21862306a36Sopenharmony_ci	}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	return 0;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	/*
22362306a36Sopenharmony_ci	 * Error cases jump to one of these labels to undo any
22462306a36Sopenharmony_ci	 * reservations which have already been performed.
22562306a36Sopenharmony_ci	 */
22662306a36Sopenharmony_ciundo_log:
22762306a36Sopenharmony_ci	if (resp->tr_logres > 0) {
22862306a36Sopenharmony_ci		xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket);
22962306a36Sopenharmony_ci		tp->t_ticket = NULL;
23062306a36Sopenharmony_ci		tp->t_log_res = 0;
23162306a36Sopenharmony_ci		tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES;
23262306a36Sopenharmony_ci	}
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ciundo_blocks:
23562306a36Sopenharmony_ci	if (blocks > 0) {
23662306a36Sopenharmony_ci		xfs_mod_fdblocks(mp, (int64_t)blocks, rsvd);
23762306a36Sopenharmony_ci		tp->t_blk_res = 0;
23862306a36Sopenharmony_ci	}
23962306a36Sopenharmony_ci	return error;
24062306a36Sopenharmony_ci}
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ciint
24362306a36Sopenharmony_cixfs_trans_alloc(
24462306a36Sopenharmony_ci	struct xfs_mount	*mp,
24562306a36Sopenharmony_ci	struct xfs_trans_res	*resp,
24662306a36Sopenharmony_ci	uint			blocks,
24762306a36Sopenharmony_ci	uint			rtextents,
24862306a36Sopenharmony_ci	uint			flags,
24962306a36Sopenharmony_ci	struct xfs_trans	**tpp)
25062306a36Sopenharmony_ci{
25162306a36Sopenharmony_ci	struct xfs_trans	*tp;
25262306a36Sopenharmony_ci	bool			want_retry = true;
25362306a36Sopenharmony_ci	int			error;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	/*
25662306a36Sopenharmony_ci	 * Allocate the handle before we do our freeze accounting and setting up
25762306a36Sopenharmony_ci	 * GFP_NOFS allocation context so that we avoid lockdep false positives
25862306a36Sopenharmony_ci	 * by doing GFP_KERNEL allocations inside sb_start_intwrite().
25962306a36Sopenharmony_ci	 */
26062306a36Sopenharmony_ciretry:
26162306a36Sopenharmony_ci	tp = kmem_cache_zalloc(xfs_trans_cache, GFP_KERNEL | __GFP_NOFAIL);
26262306a36Sopenharmony_ci	if (!(flags & XFS_TRANS_NO_WRITECOUNT))
26362306a36Sopenharmony_ci		sb_start_intwrite(mp->m_super);
26462306a36Sopenharmony_ci	xfs_trans_set_context(tp);
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	/*
26762306a36Sopenharmony_ci	 * Zero-reservation ("empty") transactions can't modify anything, so
26862306a36Sopenharmony_ci	 * they're allowed to run while we're frozen.
26962306a36Sopenharmony_ci	 */
27062306a36Sopenharmony_ci	WARN_ON(resp->tr_logres > 0 &&
27162306a36Sopenharmony_ci		mp->m_super->s_writers.frozen == SB_FREEZE_COMPLETE);
27262306a36Sopenharmony_ci	ASSERT(!(flags & XFS_TRANS_RES_FDBLKS) ||
27362306a36Sopenharmony_ci	       xfs_has_lazysbcount(mp));
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	tp->t_magic = XFS_TRANS_HEADER_MAGIC;
27662306a36Sopenharmony_ci	tp->t_flags = flags;
27762306a36Sopenharmony_ci	tp->t_mountp = mp;
27862306a36Sopenharmony_ci	INIT_LIST_HEAD(&tp->t_items);
27962306a36Sopenharmony_ci	INIT_LIST_HEAD(&tp->t_busy);
28062306a36Sopenharmony_ci	INIT_LIST_HEAD(&tp->t_dfops);
28162306a36Sopenharmony_ci	tp->t_highest_agno = NULLAGNUMBER;
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	error = xfs_trans_reserve(tp, resp, blocks, rtextents);
28462306a36Sopenharmony_ci	if (error == -ENOSPC && want_retry) {
28562306a36Sopenharmony_ci		xfs_trans_cancel(tp);
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci		/*
28862306a36Sopenharmony_ci		 * We weren't able to reserve enough space for the transaction.
28962306a36Sopenharmony_ci		 * Flush the other speculative space allocations to free space.
29062306a36Sopenharmony_ci		 * Do not perform a synchronous scan because callers can hold
29162306a36Sopenharmony_ci		 * other locks.
29262306a36Sopenharmony_ci		 */
29362306a36Sopenharmony_ci		error = xfs_blockgc_flush_all(mp);
29462306a36Sopenharmony_ci		if (error)
29562306a36Sopenharmony_ci			return error;
29662306a36Sopenharmony_ci		want_retry = false;
29762306a36Sopenharmony_ci		goto retry;
29862306a36Sopenharmony_ci	}
29962306a36Sopenharmony_ci	if (error) {
30062306a36Sopenharmony_ci		xfs_trans_cancel(tp);
30162306a36Sopenharmony_ci		return error;
30262306a36Sopenharmony_ci	}
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci	trace_xfs_trans_alloc(tp, _RET_IP_);
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	*tpp = tp;
30762306a36Sopenharmony_ci	return 0;
30862306a36Sopenharmony_ci}
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci/*
31162306a36Sopenharmony_ci * Create an empty transaction with no reservation.  This is a defensive
31262306a36Sopenharmony_ci * mechanism for routines that query metadata without actually modifying them --
31362306a36Sopenharmony_ci * if the metadata being queried is somehow cross-linked (think a btree block
31462306a36Sopenharmony_ci * pointer that points higher in the tree), we risk deadlock.  However, blocks
31562306a36Sopenharmony_ci * grabbed as part of a transaction can be re-grabbed.  The verifiers will
31662306a36Sopenharmony_ci * notice the corrupt block and the operation will fail back to userspace
31762306a36Sopenharmony_ci * without deadlocking.
31862306a36Sopenharmony_ci *
31962306a36Sopenharmony_ci * Note the zero-length reservation; this transaction MUST be cancelled without
32062306a36Sopenharmony_ci * any dirty data.
32162306a36Sopenharmony_ci *
32262306a36Sopenharmony_ci * Callers should obtain freeze protection to avoid a conflict with fs freezing
32362306a36Sopenharmony_ci * where we can be grabbing buffers at the same time that freeze is trying to
32462306a36Sopenharmony_ci * drain the buffer LRU list.
32562306a36Sopenharmony_ci */
32662306a36Sopenharmony_ciint
32762306a36Sopenharmony_cixfs_trans_alloc_empty(
32862306a36Sopenharmony_ci	struct xfs_mount		*mp,
32962306a36Sopenharmony_ci	struct xfs_trans		**tpp)
33062306a36Sopenharmony_ci{
33162306a36Sopenharmony_ci	struct xfs_trans_res		resv = {0};
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	return xfs_trans_alloc(mp, &resv, 0, 0, XFS_TRANS_NO_WRITECOUNT, tpp);
33462306a36Sopenharmony_ci}
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci/*
33762306a36Sopenharmony_ci * Record the indicated change to the given field for application
33862306a36Sopenharmony_ci * to the file system's superblock when the transaction commits.
33962306a36Sopenharmony_ci * For now, just store the change in the transaction structure.
34062306a36Sopenharmony_ci *
34162306a36Sopenharmony_ci * Mark the transaction structure to indicate that the superblock
34262306a36Sopenharmony_ci * needs to be updated before committing.
34362306a36Sopenharmony_ci *
34462306a36Sopenharmony_ci * Because we may not be keeping track of allocated/free inodes and
34562306a36Sopenharmony_ci * used filesystem blocks in the superblock, we do not mark the
34662306a36Sopenharmony_ci * superblock dirty in this transaction if we modify these fields.
34762306a36Sopenharmony_ci * We still need to update the transaction deltas so that they get
34862306a36Sopenharmony_ci * applied to the incore superblock, but we don't want them to
34962306a36Sopenharmony_ci * cause the superblock to get locked and logged if these are the
35062306a36Sopenharmony_ci * only fields in the superblock that the transaction modifies.
35162306a36Sopenharmony_ci */
35262306a36Sopenharmony_civoid
35362306a36Sopenharmony_cixfs_trans_mod_sb(
35462306a36Sopenharmony_ci	xfs_trans_t	*tp,
35562306a36Sopenharmony_ci	uint		field,
35662306a36Sopenharmony_ci	int64_t		delta)
35762306a36Sopenharmony_ci{
35862306a36Sopenharmony_ci	uint32_t	flags = (XFS_TRANS_DIRTY|XFS_TRANS_SB_DIRTY);
35962306a36Sopenharmony_ci	xfs_mount_t	*mp = tp->t_mountp;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	switch (field) {
36262306a36Sopenharmony_ci	case XFS_TRANS_SB_ICOUNT:
36362306a36Sopenharmony_ci		tp->t_icount_delta += delta;
36462306a36Sopenharmony_ci		if (xfs_has_lazysbcount(mp))
36562306a36Sopenharmony_ci			flags &= ~XFS_TRANS_SB_DIRTY;
36662306a36Sopenharmony_ci		break;
36762306a36Sopenharmony_ci	case XFS_TRANS_SB_IFREE:
36862306a36Sopenharmony_ci		tp->t_ifree_delta += delta;
36962306a36Sopenharmony_ci		if (xfs_has_lazysbcount(mp))
37062306a36Sopenharmony_ci			flags &= ~XFS_TRANS_SB_DIRTY;
37162306a36Sopenharmony_ci		break;
37262306a36Sopenharmony_ci	case XFS_TRANS_SB_FDBLOCKS:
37362306a36Sopenharmony_ci		/*
37462306a36Sopenharmony_ci		 * Track the number of blocks allocated in the transaction.
37562306a36Sopenharmony_ci		 * Make sure it does not exceed the number reserved. If so,
37662306a36Sopenharmony_ci		 * shutdown as this can lead to accounting inconsistency.
37762306a36Sopenharmony_ci		 */
37862306a36Sopenharmony_ci		if (delta < 0) {
37962306a36Sopenharmony_ci			tp->t_blk_res_used += (uint)-delta;
38062306a36Sopenharmony_ci			if (tp->t_blk_res_used > tp->t_blk_res)
38162306a36Sopenharmony_ci				xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
38262306a36Sopenharmony_ci		} else if (delta > 0 && (tp->t_flags & XFS_TRANS_RES_FDBLKS)) {
38362306a36Sopenharmony_ci			int64_t	blkres_delta;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci			/*
38662306a36Sopenharmony_ci			 * Return freed blocks directly to the reservation
38762306a36Sopenharmony_ci			 * instead of the global pool, being careful not to
38862306a36Sopenharmony_ci			 * overflow the trans counter. This is used to preserve
38962306a36Sopenharmony_ci			 * reservation across chains of transaction rolls that
39062306a36Sopenharmony_ci			 * repeatedly free and allocate blocks.
39162306a36Sopenharmony_ci			 */
39262306a36Sopenharmony_ci			blkres_delta = min_t(int64_t, delta,
39362306a36Sopenharmony_ci					     UINT_MAX - tp->t_blk_res);
39462306a36Sopenharmony_ci			tp->t_blk_res += blkres_delta;
39562306a36Sopenharmony_ci			delta -= blkres_delta;
39662306a36Sopenharmony_ci		}
39762306a36Sopenharmony_ci		tp->t_fdblocks_delta += delta;
39862306a36Sopenharmony_ci		if (xfs_has_lazysbcount(mp))
39962306a36Sopenharmony_ci			flags &= ~XFS_TRANS_SB_DIRTY;
40062306a36Sopenharmony_ci		break;
40162306a36Sopenharmony_ci	case XFS_TRANS_SB_RES_FDBLOCKS:
40262306a36Sopenharmony_ci		/*
40362306a36Sopenharmony_ci		 * The allocation has already been applied to the
40462306a36Sopenharmony_ci		 * in-core superblock's counter.  This should only
40562306a36Sopenharmony_ci		 * be applied to the on-disk superblock.
40662306a36Sopenharmony_ci		 */
40762306a36Sopenharmony_ci		tp->t_res_fdblocks_delta += delta;
40862306a36Sopenharmony_ci		if (xfs_has_lazysbcount(mp))
40962306a36Sopenharmony_ci			flags &= ~XFS_TRANS_SB_DIRTY;
41062306a36Sopenharmony_ci		break;
41162306a36Sopenharmony_ci	case XFS_TRANS_SB_FREXTENTS:
41262306a36Sopenharmony_ci		/*
41362306a36Sopenharmony_ci		 * Track the number of blocks allocated in the
41462306a36Sopenharmony_ci		 * transaction.  Make sure it does not exceed the
41562306a36Sopenharmony_ci		 * number reserved.
41662306a36Sopenharmony_ci		 */
41762306a36Sopenharmony_ci		if (delta < 0) {
41862306a36Sopenharmony_ci			tp->t_rtx_res_used += (uint)-delta;
41962306a36Sopenharmony_ci			ASSERT(tp->t_rtx_res_used <= tp->t_rtx_res);
42062306a36Sopenharmony_ci		}
42162306a36Sopenharmony_ci		tp->t_frextents_delta += delta;
42262306a36Sopenharmony_ci		break;
42362306a36Sopenharmony_ci	case XFS_TRANS_SB_RES_FREXTENTS:
42462306a36Sopenharmony_ci		/*
42562306a36Sopenharmony_ci		 * The allocation has already been applied to the
42662306a36Sopenharmony_ci		 * in-core superblock's counter.  This should only
42762306a36Sopenharmony_ci		 * be applied to the on-disk superblock.
42862306a36Sopenharmony_ci		 */
42962306a36Sopenharmony_ci		ASSERT(delta < 0);
43062306a36Sopenharmony_ci		tp->t_res_frextents_delta += delta;
43162306a36Sopenharmony_ci		break;
43262306a36Sopenharmony_ci	case XFS_TRANS_SB_DBLOCKS:
43362306a36Sopenharmony_ci		tp->t_dblocks_delta += delta;
43462306a36Sopenharmony_ci		break;
43562306a36Sopenharmony_ci	case XFS_TRANS_SB_AGCOUNT:
43662306a36Sopenharmony_ci		ASSERT(delta > 0);
43762306a36Sopenharmony_ci		tp->t_agcount_delta += delta;
43862306a36Sopenharmony_ci		break;
43962306a36Sopenharmony_ci	case XFS_TRANS_SB_IMAXPCT:
44062306a36Sopenharmony_ci		tp->t_imaxpct_delta += delta;
44162306a36Sopenharmony_ci		break;
44262306a36Sopenharmony_ci	case XFS_TRANS_SB_REXTSIZE:
44362306a36Sopenharmony_ci		tp->t_rextsize_delta += delta;
44462306a36Sopenharmony_ci		break;
44562306a36Sopenharmony_ci	case XFS_TRANS_SB_RBMBLOCKS:
44662306a36Sopenharmony_ci		tp->t_rbmblocks_delta += delta;
44762306a36Sopenharmony_ci		break;
44862306a36Sopenharmony_ci	case XFS_TRANS_SB_RBLOCKS:
44962306a36Sopenharmony_ci		tp->t_rblocks_delta += delta;
45062306a36Sopenharmony_ci		break;
45162306a36Sopenharmony_ci	case XFS_TRANS_SB_REXTENTS:
45262306a36Sopenharmony_ci		tp->t_rextents_delta += delta;
45362306a36Sopenharmony_ci		break;
45462306a36Sopenharmony_ci	case XFS_TRANS_SB_REXTSLOG:
45562306a36Sopenharmony_ci		tp->t_rextslog_delta += delta;
45662306a36Sopenharmony_ci		break;
45762306a36Sopenharmony_ci	default:
45862306a36Sopenharmony_ci		ASSERT(0);
45962306a36Sopenharmony_ci		return;
46062306a36Sopenharmony_ci	}
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci	tp->t_flags |= flags;
46362306a36Sopenharmony_ci}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci/*
46662306a36Sopenharmony_ci * xfs_trans_apply_sb_deltas() is called from the commit code
46762306a36Sopenharmony_ci * to bring the superblock buffer into the current transaction
46862306a36Sopenharmony_ci * and modify it as requested by earlier calls to xfs_trans_mod_sb().
46962306a36Sopenharmony_ci *
47062306a36Sopenharmony_ci * For now we just look at each field allowed to change and change
47162306a36Sopenharmony_ci * it if necessary.
47262306a36Sopenharmony_ci */
47362306a36Sopenharmony_ciSTATIC void
47462306a36Sopenharmony_cixfs_trans_apply_sb_deltas(
47562306a36Sopenharmony_ci	xfs_trans_t	*tp)
47662306a36Sopenharmony_ci{
47762306a36Sopenharmony_ci	struct xfs_dsb	*sbp;
47862306a36Sopenharmony_ci	struct xfs_buf	*bp;
47962306a36Sopenharmony_ci	int		whole = 0;
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci	bp = xfs_trans_getsb(tp);
48262306a36Sopenharmony_ci	sbp = bp->b_addr;
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	/*
48562306a36Sopenharmony_ci	 * Only update the superblock counters if we are logging them
48662306a36Sopenharmony_ci	 */
48762306a36Sopenharmony_ci	if (!xfs_has_lazysbcount((tp->t_mountp))) {
48862306a36Sopenharmony_ci		if (tp->t_icount_delta)
48962306a36Sopenharmony_ci			be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta);
49062306a36Sopenharmony_ci		if (tp->t_ifree_delta)
49162306a36Sopenharmony_ci			be64_add_cpu(&sbp->sb_ifree, tp->t_ifree_delta);
49262306a36Sopenharmony_ci		if (tp->t_fdblocks_delta)
49362306a36Sopenharmony_ci			be64_add_cpu(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
49462306a36Sopenharmony_ci		if (tp->t_res_fdblocks_delta)
49562306a36Sopenharmony_ci			be64_add_cpu(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
49662306a36Sopenharmony_ci	}
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	/*
49962306a36Sopenharmony_ci	 * Updating frextents requires careful handling because it does not
50062306a36Sopenharmony_ci	 * behave like the lazysb counters because we cannot rely on log
50162306a36Sopenharmony_ci	 * recovery in older kenels to recompute the value from the rtbitmap.
50262306a36Sopenharmony_ci	 * This means that the ondisk frextents must be consistent with the
50362306a36Sopenharmony_ci	 * rtbitmap.
50462306a36Sopenharmony_ci	 *
50562306a36Sopenharmony_ci	 * Therefore, log the frextents change to the ondisk superblock and
50662306a36Sopenharmony_ci	 * update the incore superblock so that future calls to xfs_log_sb
50762306a36Sopenharmony_ci	 * write the correct value ondisk.
50862306a36Sopenharmony_ci	 *
50962306a36Sopenharmony_ci	 * Don't touch m_frextents because it includes incore reservations,
51062306a36Sopenharmony_ci	 * and those are handled by the unreserve function.
51162306a36Sopenharmony_ci	 */
51262306a36Sopenharmony_ci	if (tp->t_frextents_delta || tp->t_res_frextents_delta) {
51362306a36Sopenharmony_ci		struct xfs_mount	*mp = tp->t_mountp;
51462306a36Sopenharmony_ci		int64_t			rtxdelta;
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci		rtxdelta = tp->t_frextents_delta + tp->t_res_frextents_delta;
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci		spin_lock(&mp->m_sb_lock);
51962306a36Sopenharmony_ci		be64_add_cpu(&sbp->sb_frextents, rtxdelta);
52062306a36Sopenharmony_ci		mp->m_sb.sb_frextents += rtxdelta;
52162306a36Sopenharmony_ci		spin_unlock(&mp->m_sb_lock);
52262306a36Sopenharmony_ci	}
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	if (tp->t_dblocks_delta) {
52562306a36Sopenharmony_ci		be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta);
52662306a36Sopenharmony_ci		whole = 1;
52762306a36Sopenharmony_ci	}
52862306a36Sopenharmony_ci	if (tp->t_agcount_delta) {
52962306a36Sopenharmony_ci		be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta);
53062306a36Sopenharmony_ci		whole = 1;
53162306a36Sopenharmony_ci	}
53262306a36Sopenharmony_ci	if (tp->t_imaxpct_delta) {
53362306a36Sopenharmony_ci		sbp->sb_imax_pct += tp->t_imaxpct_delta;
53462306a36Sopenharmony_ci		whole = 1;
53562306a36Sopenharmony_ci	}
53662306a36Sopenharmony_ci	if (tp->t_rextsize_delta) {
53762306a36Sopenharmony_ci		be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta);
53862306a36Sopenharmony_ci		whole = 1;
53962306a36Sopenharmony_ci	}
54062306a36Sopenharmony_ci	if (tp->t_rbmblocks_delta) {
54162306a36Sopenharmony_ci		be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
54262306a36Sopenharmony_ci		whole = 1;
54362306a36Sopenharmony_ci	}
54462306a36Sopenharmony_ci	if (tp->t_rblocks_delta) {
54562306a36Sopenharmony_ci		be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta);
54662306a36Sopenharmony_ci		whole = 1;
54762306a36Sopenharmony_ci	}
54862306a36Sopenharmony_ci	if (tp->t_rextents_delta) {
54962306a36Sopenharmony_ci		be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta);
55062306a36Sopenharmony_ci		whole = 1;
55162306a36Sopenharmony_ci	}
55262306a36Sopenharmony_ci	if (tp->t_rextslog_delta) {
55362306a36Sopenharmony_ci		sbp->sb_rextslog += tp->t_rextslog_delta;
55462306a36Sopenharmony_ci		whole = 1;
55562306a36Sopenharmony_ci	}
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
55862306a36Sopenharmony_ci	if (whole)
55962306a36Sopenharmony_ci		/*
56062306a36Sopenharmony_ci		 * Log the whole thing, the fields are noncontiguous.
56162306a36Sopenharmony_ci		 */
56262306a36Sopenharmony_ci		xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb) - 1);
56362306a36Sopenharmony_ci	else
56462306a36Sopenharmony_ci		/*
56562306a36Sopenharmony_ci		 * Since all the modifiable fields are contiguous, we
56662306a36Sopenharmony_ci		 * can get away with this.
56762306a36Sopenharmony_ci		 */
56862306a36Sopenharmony_ci		xfs_trans_log_buf(tp, bp, offsetof(struct xfs_dsb, sb_icount),
56962306a36Sopenharmony_ci				  offsetof(struct xfs_dsb, sb_frextents) +
57062306a36Sopenharmony_ci				  sizeof(sbp->sb_frextents) - 1);
57162306a36Sopenharmony_ci}
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci/*
57462306a36Sopenharmony_ci * xfs_trans_unreserve_and_mod_sb() is called to release unused reservations and
57562306a36Sopenharmony_ci * apply superblock counter changes to the in-core superblock.  The
57662306a36Sopenharmony_ci * t_res_fdblocks_delta and t_res_frextents_delta fields are explicitly NOT
57762306a36Sopenharmony_ci * applied to the in-core superblock.  The idea is that that has already been
57862306a36Sopenharmony_ci * done.
57962306a36Sopenharmony_ci *
58062306a36Sopenharmony_ci * If we are not logging superblock counters, then the inode allocated/free and
58162306a36Sopenharmony_ci * used block counts are not updated in the on disk superblock. In this case,
58262306a36Sopenharmony_ci * XFS_TRANS_SB_DIRTY will not be set when the transaction is updated but we
58362306a36Sopenharmony_ci * still need to update the incore superblock with the changes.
58462306a36Sopenharmony_ci *
58562306a36Sopenharmony_ci * Deltas for the inode count are +/-64, hence we use a large batch size of 128
58662306a36Sopenharmony_ci * so we don't need to take the counter lock on every update.
58762306a36Sopenharmony_ci */
58862306a36Sopenharmony_ci#define XFS_ICOUNT_BATCH	128
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_civoid
59162306a36Sopenharmony_cixfs_trans_unreserve_and_mod_sb(
59262306a36Sopenharmony_ci	struct xfs_trans	*tp)
59362306a36Sopenharmony_ci{
59462306a36Sopenharmony_ci	struct xfs_mount	*mp = tp->t_mountp;
59562306a36Sopenharmony_ci	bool			rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
59662306a36Sopenharmony_ci	int64_t			blkdelta = 0;
59762306a36Sopenharmony_ci	int64_t			rtxdelta = 0;
59862306a36Sopenharmony_ci	int64_t			idelta = 0;
59962306a36Sopenharmony_ci	int64_t			ifreedelta = 0;
60062306a36Sopenharmony_ci	int			error;
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci	/* calculate deltas */
60362306a36Sopenharmony_ci	if (tp->t_blk_res > 0)
60462306a36Sopenharmony_ci		blkdelta = tp->t_blk_res;
60562306a36Sopenharmony_ci	if ((tp->t_fdblocks_delta != 0) &&
60662306a36Sopenharmony_ci	    (xfs_has_lazysbcount(mp) ||
60762306a36Sopenharmony_ci	     (tp->t_flags & XFS_TRANS_SB_DIRTY)))
60862306a36Sopenharmony_ci	        blkdelta += tp->t_fdblocks_delta;
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	if (tp->t_rtx_res > 0)
61162306a36Sopenharmony_ci		rtxdelta = tp->t_rtx_res;
61262306a36Sopenharmony_ci	if ((tp->t_frextents_delta != 0) &&
61362306a36Sopenharmony_ci	    (tp->t_flags & XFS_TRANS_SB_DIRTY))
61462306a36Sopenharmony_ci		rtxdelta += tp->t_frextents_delta;
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_ci	if (xfs_has_lazysbcount(mp) ||
61762306a36Sopenharmony_ci	     (tp->t_flags & XFS_TRANS_SB_DIRTY)) {
61862306a36Sopenharmony_ci		idelta = tp->t_icount_delta;
61962306a36Sopenharmony_ci		ifreedelta = tp->t_ifree_delta;
62062306a36Sopenharmony_ci	}
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	/* apply the per-cpu counters */
62362306a36Sopenharmony_ci	if (blkdelta) {
62462306a36Sopenharmony_ci		error = xfs_mod_fdblocks(mp, blkdelta, rsvd);
62562306a36Sopenharmony_ci		ASSERT(!error);
62662306a36Sopenharmony_ci	}
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci	if (idelta)
62962306a36Sopenharmony_ci		percpu_counter_add_batch(&mp->m_icount, idelta,
63062306a36Sopenharmony_ci					 XFS_ICOUNT_BATCH);
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	if (ifreedelta)
63362306a36Sopenharmony_ci		percpu_counter_add(&mp->m_ifree, ifreedelta);
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	if (rtxdelta) {
63662306a36Sopenharmony_ci		error = xfs_mod_frextents(mp, rtxdelta);
63762306a36Sopenharmony_ci		ASSERT(!error);
63862306a36Sopenharmony_ci	}
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	if (!(tp->t_flags & XFS_TRANS_SB_DIRTY))
64162306a36Sopenharmony_ci		return;
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	/* apply remaining deltas */
64462306a36Sopenharmony_ci	spin_lock(&mp->m_sb_lock);
64562306a36Sopenharmony_ci	mp->m_sb.sb_fdblocks += tp->t_fdblocks_delta + tp->t_res_fdblocks_delta;
64662306a36Sopenharmony_ci	mp->m_sb.sb_icount += idelta;
64762306a36Sopenharmony_ci	mp->m_sb.sb_ifree += ifreedelta;
64862306a36Sopenharmony_ci	/*
64962306a36Sopenharmony_ci	 * Do not touch sb_frextents here because we are dealing with incore
65062306a36Sopenharmony_ci	 * reservation.  sb_frextents is not part of the lazy sb counters so it
65162306a36Sopenharmony_ci	 * must be consistent with the ondisk rtbitmap and must never include
65262306a36Sopenharmony_ci	 * incore reservations.
65362306a36Sopenharmony_ci	 */
65462306a36Sopenharmony_ci	mp->m_sb.sb_dblocks += tp->t_dblocks_delta;
65562306a36Sopenharmony_ci	mp->m_sb.sb_agcount += tp->t_agcount_delta;
65662306a36Sopenharmony_ci	mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta;
65762306a36Sopenharmony_ci	mp->m_sb.sb_rextsize += tp->t_rextsize_delta;
65862306a36Sopenharmony_ci	mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta;
65962306a36Sopenharmony_ci	mp->m_sb.sb_rblocks += tp->t_rblocks_delta;
66062306a36Sopenharmony_ci	mp->m_sb.sb_rextents += tp->t_rextents_delta;
66162306a36Sopenharmony_ci	mp->m_sb.sb_rextslog += tp->t_rextslog_delta;
66262306a36Sopenharmony_ci	spin_unlock(&mp->m_sb_lock);
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	/*
66562306a36Sopenharmony_ci	 * Debug checks outside of the spinlock so they don't lock up the
66662306a36Sopenharmony_ci	 * machine if they fail.
66762306a36Sopenharmony_ci	 */
66862306a36Sopenharmony_ci	ASSERT(mp->m_sb.sb_imax_pct >= 0);
66962306a36Sopenharmony_ci	ASSERT(mp->m_sb.sb_rextslog >= 0);
67062306a36Sopenharmony_ci	return;
67162306a36Sopenharmony_ci}
67262306a36Sopenharmony_ci
67362306a36Sopenharmony_ci/* Add the given log item to the transaction's list of log items. */
67462306a36Sopenharmony_civoid
67562306a36Sopenharmony_cixfs_trans_add_item(
67662306a36Sopenharmony_ci	struct xfs_trans	*tp,
67762306a36Sopenharmony_ci	struct xfs_log_item	*lip)
67862306a36Sopenharmony_ci{
67962306a36Sopenharmony_ci	ASSERT(lip->li_log == tp->t_mountp->m_log);
68062306a36Sopenharmony_ci	ASSERT(lip->li_ailp == tp->t_mountp->m_ail);
68162306a36Sopenharmony_ci	ASSERT(list_empty(&lip->li_trans));
68262306a36Sopenharmony_ci	ASSERT(!test_bit(XFS_LI_DIRTY, &lip->li_flags));
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	list_add_tail(&lip->li_trans, &tp->t_items);
68562306a36Sopenharmony_ci	trace_xfs_trans_add_item(tp, _RET_IP_);
68662306a36Sopenharmony_ci}
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci/*
68962306a36Sopenharmony_ci * Unlink the log item from the transaction. the log item is no longer
69062306a36Sopenharmony_ci * considered dirty in this transaction, as the linked transaction has
69162306a36Sopenharmony_ci * finished, either by abort or commit completion.
69262306a36Sopenharmony_ci */
69362306a36Sopenharmony_civoid
69462306a36Sopenharmony_cixfs_trans_del_item(
69562306a36Sopenharmony_ci	struct xfs_log_item	*lip)
69662306a36Sopenharmony_ci{
69762306a36Sopenharmony_ci	clear_bit(XFS_LI_DIRTY, &lip->li_flags);
69862306a36Sopenharmony_ci	list_del_init(&lip->li_trans);
69962306a36Sopenharmony_ci}
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci/* Detach and unlock all of the items in a transaction */
70262306a36Sopenharmony_cistatic void
70362306a36Sopenharmony_cixfs_trans_free_items(
70462306a36Sopenharmony_ci	struct xfs_trans	*tp,
70562306a36Sopenharmony_ci	bool			abort)
70662306a36Sopenharmony_ci{
70762306a36Sopenharmony_ci	struct xfs_log_item	*lip, *next;
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	trace_xfs_trans_free_items(tp, _RET_IP_);
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci	list_for_each_entry_safe(lip, next, &tp->t_items, li_trans) {
71262306a36Sopenharmony_ci		xfs_trans_del_item(lip);
71362306a36Sopenharmony_ci		if (abort)
71462306a36Sopenharmony_ci			set_bit(XFS_LI_ABORTED, &lip->li_flags);
71562306a36Sopenharmony_ci		if (lip->li_ops->iop_release)
71662306a36Sopenharmony_ci			lip->li_ops->iop_release(lip);
71762306a36Sopenharmony_ci	}
71862306a36Sopenharmony_ci}
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_cistatic inline void
72162306a36Sopenharmony_cixfs_log_item_batch_insert(
72262306a36Sopenharmony_ci	struct xfs_ail		*ailp,
72362306a36Sopenharmony_ci	struct xfs_ail_cursor	*cur,
72462306a36Sopenharmony_ci	struct xfs_log_item	**log_items,
72562306a36Sopenharmony_ci	int			nr_items,
72662306a36Sopenharmony_ci	xfs_lsn_t		commit_lsn)
72762306a36Sopenharmony_ci{
72862306a36Sopenharmony_ci	int	i;
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	spin_lock(&ailp->ail_lock);
73162306a36Sopenharmony_ci	/* xfs_trans_ail_update_bulk drops ailp->ail_lock */
73262306a36Sopenharmony_ci	xfs_trans_ail_update_bulk(ailp, cur, log_items, nr_items, commit_lsn);
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci	for (i = 0; i < nr_items; i++) {
73562306a36Sopenharmony_ci		struct xfs_log_item *lip = log_items[i];
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci		if (lip->li_ops->iop_unpin)
73862306a36Sopenharmony_ci			lip->li_ops->iop_unpin(lip, 0);
73962306a36Sopenharmony_ci	}
74062306a36Sopenharmony_ci}
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci/*
74362306a36Sopenharmony_ci * Bulk operation version of xfs_trans_committed that takes a log vector of
74462306a36Sopenharmony_ci * items to insert into the AIL. This uses bulk AIL insertion techniques to
74562306a36Sopenharmony_ci * minimise lock traffic.
74662306a36Sopenharmony_ci *
74762306a36Sopenharmony_ci * If we are called with the aborted flag set, it is because a log write during
74862306a36Sopenharmony_ci * a CIL checkpoint commit has failed. In this case, all the items in the
74962306a36Sopenharmony_ci * checkpoint have already gone through iop_committed and iop_committing, which
75062306a36Sopenharmony_ci * means that checkpoint commit abort handling is treated exactly the same
75162306a36Sopenharmony_ci * as an iclog write error even though we haven't started any IO yet. Hence in
75262306a36Sopenharmony_ci * this case all we need to do is iop_committed processing, followed by an
75362306a36Sopenharmony_ci * iop_unpin(aborted) call.
75462306a36Sopenharmony_ci *
75562306a36Sopenharmony_ci * The AIL cursor is used to optimise the insert process. If commit_lsn is not
75662306a36Sopenharmony_ci * at the end of the AIL, the insert cursor avoids the need to walk
75762306a36Sopenharmony_ci * the AIL to find the insertion point on every xfs_log_item_batch_insert()
75862306a36Sopenharmony_ci * call. This saves a lot of needless list walking and is a net win, even
75962306a36Sopenharmony_ci * though it slightly increases that amount of AIL lock traffic to set it up
76062306a36Sopenharmony_ci * and tear it down.
76162306a36Sopenharmony_ci */
76262306a36Sopenharmony_civoid
76362306a36Sopenharmony_cixfs_trans_committed_bulk(
76462306a36Sopenharmony_ci	struct xfs_ail		*ailp,
76562306a36Sopenharmony_ci	struct list_head	*lv_chain,
76662306a36Sopenharmony_ci	xfs_lsn_t		commit_lsn,
76762306a36Sopenharmony_ci	bool			aborted)
76862306a36Sopenharmony_ci{
76962306a36Sopenharmony_ci#define LOG_ITEM_BATCH_SIZE	32
77062306a36Sopenharmony_ci	struct xfs_log_item	*log_items[LOG_ITEM_BATCH_SIZE];
77162306a36Sopenharmony_ci	struct xfs_log_vec	*lv;
77262306a36Sopenharmony_ci	struct xfs_ail_cursor	cur;
77362306a36Sopenharmony_ci	int			i = 0;
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci	spin_lock(&ailp->ail_lock);
77662306a36Sopenharmony_ci	xfs_trans_ail_cursor_last(ailp, &cur, commit_lsn);
77762306a36Sopenharmony_ci	spin_unlock(&ailp->ail_lock);
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_ci	/* unpin all the log items */
78062306a36Sopenharmony_ci	list_for_each_entry(lv, lv_chain, lv_list) {
78162306a36Sopenharmony_ci		struct xfs_log_item	*lip = lv->lv_item;
78262306a36Sopenharmony_ci		xfs_lsn_t		item_lsn;
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_ci		if (aborted)
78562306a36Sopenharmony_ci			set_bit(XFS_LI_ABORTED, &lip->li_flags);
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci		if (lip->li_ops->flags & XFS_ITEM_RELEASE_WHEN_COMMITTED) {
78862306a36Sopenharmony_ci			lip->li_ops->iop_release(lip);
78962306a36Sopenharmony_ci			continue;
79062306a36Sopenharmony_ci		}
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci		if (lip->li_ops->iop_committed)
79362306a36Sopenharmony_ci			item_lsn = lip->li_ops->iop_committed(lip, commit_lsn);
79462306a36Sopenharmony_ci		else
79562306a36Sopenharmony_ci			item_lsn = commit_lsn;
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ci		/* item_lsn of -1 means the item needs no further processing */
79862306a36Sopenharmony_ci		if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
79962306a36Sopenharmony_ci			continue;
80062306a36Sopenharmony_ci
80162306a36Sopenharmony_ci		/*
80262306a36Sopenharmony_ci		 * if we are aborting the operation, no point in inserting the
80362306a36Sopenharmony_ci		 * object into the AIL as we are in a shutdown situation.
80462306a36Sopenharmony_ci		 */
80562306a36Sopenharmony_ci		if (aborted) {
80662306a36Sopenharmony_ci			ASSERT(xlog_is_shutdown(ailp->ail_log));
80762306a36Sopenharmony_ci			if (lip->li_ops->iop_unpin)
80862306a36Sopenharmony_ci				lip->li_ops->iop_unpin(lip, 1);
80962306a36Sopenharmony_ci			continue;
81062306a36Sopenharmony_ci		}
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci		if (item_lsn != commit_lsn) {
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci			/*
81562306a36Sopenharmony_ci			 * Not a bulk update option due to unusual item_lsn.
81662306a36Sopenharmony_ci			 * Push into AIL immediately, rechecking the lsn once
81762306a36Sopenharmony_ci			 * we have the ail lock. Then unpin the item. This does
81862306a36Sopenharmony_ci			 * not affect the AIL cursor the bulk insert path is
81962306a36Sopenharmony_ci			 * using.
82062306a36Sopenharmony_ci			 */
82162306a36Sopenharmony_ci			spin_lock(&ailp->ail_lock);
82262306a36Sopenharmony_ci			if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0)
82362306a36Sopenharmony_ci				xfs_trans_ail_update(ailp, lip, item_lsn);
82462306a36Sopenharmony_ci			else
82562306a36Sopenharmony_ci				spin_unlock(&ailp->ail_lock);
82662306a36Sopenharmony_ci			if (lip->li_ops->iop_unpin)
82762306a36Sopenharmony_ci				lip->li_ops->iop_unpin(lip, 0);
82862306a36Sopenharmony_ci			continue;
82962306a36Sopenharmony_ci		}
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ci		/* Item is a candidate for bulk AIL insert.  */
83262306a36Sopenharmony_ci		log_items[i++] = lv->lv_item;
83362306a36Sopenharmony_ci		if (i >= LOG_ITEM_BATCH_SIZE) {
83462306a36Sopenharmony_ci			xfs_log_item_batch_insert(ailp, &cur, log_items,
83562306a36Sopenharmony_ci					LOG_ITEM_BATCH_SIZE, commit_lsn);
83662306a36Sopenharmony_ci			i = 0;
83762306a36Sopenharmony_ci		}
83862306a36Sopenharmony_ci	}
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci	/* make sure we insert the remainder! */
84162306a36Sopenharmony_ci	if (i)
84262306a36Sopenharmony_ci		xfs_log_item_batch_insert(ailp, &cur, log_items, i, commit_lsn);
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci	spin_lock(&ailp->ail_lock);
84562306a36Sopenharmony_ci	xfs_trans_ail_cursor_done(&cur);
84662306a36Sopenharmony_ci	spin_unlock(&ailp->ail_lock);
84762306a36Sopenharmony_ci}
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci/*
85062306a36Sopenharmony_ci * Sort transaction items prior to running precommit operations. This will
85162306a36Sopenharmony_ci * attempt to order the items such that they will always be locked in the same
85262306a36Sopenharmony_ci * order. Items that have no sort function are moved to the end of the list
85362306a36Sopenharmony_ci * and so are locked last.
85462306a36Sopenharmony_ci *
85562306a36Sopenharmony_ci * This may need refinement as different types of objects add sort functions.
85662306a36Sopenharmony_ci *
85762306a36Sopenharmony_ci * Function is more complex than it needs to be because we are comparing 64 bit
85862306a36Sopenharmony_ci * values and the function only returns 32 bit values.
85962306a36Sopenharmony_ci */
86062306a36Sopenharmony_cistatic int
86162306a36Sopenharmony_cixfs_trans_precommit_sort(
86262306a36Sopenharmony_ci	void			*unused_arg,
86362306a36Sopenharmony_ci	const struct list_head	*a,
86462306a36Sopenharmony_ci	const struct list_head	*b)
86562306a36Sopenharmony_ci{
86662306a36Sopenharmony_ci	struct xfs_log_item	*lia = container_of(a,
86762306a36Sopenharmony_ci					struct xfs_log_item, li_trans);
86862306a36Sopenharmony_ci	struct xfs_log_item	*lib = container_of(b,
86962306a36Sopenharmony_ci					struct xfs_log_item, li_trans);
87062306a36Sopenharmony_ci	int64_t			diff;
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ci	/*
87362306a36Sopenharmony_ci	 * If both items are non-sortable, leave them alone. If only one is
87462306a36Sopenharmony_ci	 * sortable, move the non-sortable item towards the end of the list.
87562306a36Sopenharmony_ci	 */
87662306a36Sopenharmony_ci	if (!lia->li_ops->iop_sort && !lib->li_ops->iop_sort)
87762306a36Sopenharmony_ci		return 0;
87862306a36Sopenharmony_ci	if (!lia->li_ops->iop_sort)
87962306a36Sopenharmony_ci		return 1;
88062306a36Sopenharmony_ci	if (!lib->li_ops->iop_sort)
88162306a36Sopenharmony_ci		return -1;
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci	diff = lia->li_ops->iop_sort(lia) - lib->li_ops->iop_sort(lib);
88462306a36Sopenharmony_ci	if (diff < 0)
88562306a36Sopenharmony_ci		return -1;
88662306a36Sopenharmony_ci	if (diff > 0)
88762306a36Sopenharmony_ci		return 1;
88862306a36Sopenharmony_ci	return 0;
88962306a36Sopenharmony_ci}
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci/*
89262306a36Sopenharmony_ci * Run transaction precommit functions.
89362306a36Sopenharmony_ci *
89462306a36Sopenharmony_ci * If there is an error in any of the callouts, then stop immediately and
89562306a36Sopenharmony_ci * trigger a shutdown to abort the transaction. There is no recovery possible
89662306a36Sopenharmony_ci * from errors at this point as the transaction is dirty....
89762306a36Sopenharmony_ci */
89862306a36Sopenharmony_cistatic int
89962306a36Sopenharmony_cixfs_trans_run_precommits(
90062306a36Sopenharmony_ci	struct xfs_trans	*tp)
90162306a36Sopenharmony_ci{
90262306a36Sopenharmony_ci	struct xfs_mount	*mp = tp->t_mountp;
90362306a36Sopenharmony_ci	struct xfs_log_item	*lip, *n;
90462306a36Sopenharmony_ci	int			error = 0;
90562306a36Sopenharmony_ci
90662306a36Sopenharmony_ci	/*
90762306a36Sopenharmony_ci	 * Sort the item list to avoid ABBA deadlocks with other transactions
90862306a36Sopenharmony_ci	 * running precommit operations that lock multiple shared items such as
90962306a36Sopenharmony_ci	 * inode cluster buffers.
91062306a36Sopenharmony_ci	 */
91162306a36Sopenharmony_ci	list_sort(NULL, &tp->t_items, xfs_trans_precommit_sort);
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci	/*
91462306a36Sopenharmony_ci	 * Precommit operations can remove the log item from the transaction
91562306a36Sopenharmony_ci	 * if the log item exists purely to delay modifications until they
91662306a36Sopenharmony_ci	 * can be ordered against other operations. Hence we have to use
91762306a36Sopenharmony_ci	 * list_for_each_entry_safe() here.
91862306a36Sopenharmony_ci	 */
91962306a36Sopenharmony_ci	list_for_each_entry_safe(lip, n, &tp->t_items, li_trans) {
92062306a36Sopenharmony_ci		if (!test_bit(XFS_LI_DIRTY, &lip->li_flags))
92162306a36Sopenharmony_ci			continue;
92262306a36Sopenharmony_ci		if (lip->li_ops->iop_precommit) {
92362306a36Sopenharmony_ci			error = lip->li_ops->iop_precommit(tp, lip);
92462306a36Sopenharmony_ci			if (error)
92562306a36Sopenharmony_ci				break;
92662306a36Sopenharmony_ci		}
92762306a36Sopenharmony_ci	}
92862306a36Sopenharmony_ci	if (error)
92962306a36Sopenharmony_ci		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
93062306a36Sopenharmony_ci	return error;
93162306a36Sopenharmony_ci}
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ci/*
93462306a36Sopenharmony_ci * Commit the given transaction to the log.
93562306a36Sopenharmony_ci *
93662306a36Sopenharmony_ci * XFS disk error handling mechanism is not based on a typical
93762306a36Sopenharmony_ci * transaction abort mechanism. Logically after the filesystem
93862306a36Sopenharmony_ci * gets marked 'SHUTDOWN', we can't let any new transactions
93962306a36Sopenharmony_ci * be durable - ie. committed to disk - because some metadata might
94062306a36Sopenharmony_ci * be inconsistent. In such cases, this returns an error, and the
94162306a36Sopenharmony_ci * caller may assume that all locked objects joined to the transaction
94262306a36Sopenharmony_ci * have already been unlocked as if the commit had succeeded.
94362306a36Sopenharmony_ci * Do not reference the transaction structure after this call.
94462306a36Sopenharmony_ci */
94562306a36Sopenharmony_cistatic int
94662306a36Sopenharmony_ci__xfs_trans_commit(
94762306a36Sopenharmony_ci	struct xfs_trans	*tp,
94862306a36Sopenharmony_ci	bool			regrant)
94962306a36Sopenharmony_ci{
95062306a36Sopenharmony_ci	struct xfs_mount	*mp = tp->t_mountp;
95162306a36Sopenharmony_ci	struct xlog		*log = mp->m_log;
95262306a36Sopenharmony_ci	xfs_csn_t		commit_seq = 0;
95362306a36Sopenharmony_ci	int			error = 0;
95462306a36Sopenharmony_ci	int			sync = tp->t_flags & XFS_TRANS_SYNC;
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	trace_xfs_trans_commit(tp, _RET_IP_);
95762306a36Sopenharmony_ci
95862306a36Sopenharmony_ci	error = xfs_trans_run_precommits(tp);
95962306a36Sopenharmony_ci	if (error) {
96062306a36Sopenharmony_ci		if (tp->t_flags & XFS_TRANS_PERM_LOG_RES)
96162306a36Sopenharmony_ci			xfs_defer_cancel(tp);
96262306a36Sopenharmony_ci		goto out_unreserve;
96362306a36Sopenharmony_ci	}
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci	/*
96662306a36Sopenharmony_ci	 * Finish deferred items on final commit. Only permanent transactions
96762306a36Sopenharmony_ci	 * should ever have deferred ops.
96862306a36Sopenharmony_ci	 */
96962306a36Sopenharmony_ci	WARN_ON_ONCE(!list_empty(&tp->t_dfops) &&
97062306a36Sopenharmony_ci		     !(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
97162306a36Sopenharmony_ci	if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) {
97262306a36Sopenharmony_ci		error = xfs_defer_finish_noroll(&tp);
97362306a36Sopenharmony_ci		if (error)
97462306a36Sopenharmony_ci			goto out_unreserve;
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci		/* Run precommits from final tx in defer chain. */
97762306a36Sopenharmony_ci		error = xfs_trans_run_precommits(tp);
97862306a36Sopenharmony_ci		if (error)
97962306a36Sopenharmony_ci			goto out_unreserve;
98062306a36Sopenharmony_ci	}
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	/*
98362306a36Sopenharmony_ci	 * If there is nothing to be logged by the transaction,
98462306a36Sopenharmony_ci	 * then unlock all of the items associated with the
98562306a36Sopenharmony_ci	 * transaction and free the transaction structure.
98662306a36Sopenharmony_ci	 * Also make sure to return any reserved blocks to
98762306a36Sopenharmony_ci	 * the free pool.
98862306a36Sopenharmony_ci	 */
98962306a36Sopenharmony_ci	if (!(tp->t_flags & XFS_TRANS_DIRTY))
99062306a36Sopenharmony_ci		goto out_unreserve;
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci	/*
99362306a36Sopenharmony_ci	 * We must check against log shutdown here because we cannot abort log
99462306a36Sopenharmony_ci	 * items and leave them dirty, inconsistent and unpinned in memory while
99562306a36Sopenharmony_ci	 * the log is active. This leaves them open to being written back to
99662306a36Sopenharmony_ci	 * disk, and that will lead to on-disk corruption.
99762306a36Sopenharmony_ci	 */
99862306a36Sopenharmony_ci	if (xlog_is_shutdown(log)) {
99962306a36Sopenharmony_ci		error = -EIO;
100062306a36Sopenharmony_ci		goto out_unreserve;
100162306a36Sopenharmony_ci	}
100262306a36Sopenharmony_ci
100362306a36Sopenharmony_ci	ASSERT(tp->t_ticket != NULL);
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_ci	/*
100662306a36Sopenharmony_ci	 * If we need to update the superblock, then do it now.
100762306a36Sopenharmony_ci	 */
100862306a36Sopenharmony_ci	if (tp->t_flags & XFS_TRANS_SB_DIRTY)
100962306a36Sopenharmony_ci		xfs_trans_apply_sb_deltas(tp);
101062306a36Sopenharmony_ci	xfs_trans_apply_dquot_deltas(tp);
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	xlog_cil_commit(log, tp, &commit_seq, regrant);
101362306a36Sopenharmony_ci
101462306a36Sopenharmony_ci	xfs_trans_free(tp);
101562306a36Sopenharmony_ci
101662306a36Sopenharmony_ci	/*
101762306a36Sopenharmony_ci	 * If the transaction needs to be synchronous, then force the
101862306a36Sopenharmony_ci	 * log out now and wait for it.
101962306a36Sopenharmony_ci	 */
102062306a36Sopenharmony_ci	if (sync) {
102162306a36Sopenharmony_ci		error = xfs_log_force_seq(mp, commit_seq, XFS_LOG_SYNC, NULL);
102262306a36Sopenharmony_ci		XFS_STATS_INC(mp, xs_trans_sync);
102362306a36Sopenharmony_ci	} else {
102462306a36Sopenharmony_ci		XFS_STATS_INC(mp, xs_trans_async);
102562306a36Sopenharmony_ci	}
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_ci	return error;
102862306a36Sopenharmony_ci
102962306a36Sopenharmony_ciout_unreserve:
103062306a36Sopenharmony_ci	xfs_trans_unreserve_and_mod_sb(tp);
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci	/*
103362306a36Sopenharmony_ci	 * It is indeed possible for the transaction to be not dirty but
103462306a36Sopenharmony_ci	 * the dqinfo portion to be.  All that means is that we have some
103562306a36Sopenharmony_ci	 * (non-persistent) quota reservations that need to be unreserved.
103662306a36Sopenharmony_ci	 */
103762306a36Sopenharmony_ci	xfs_trans_unreserve_and_mod_dquots(tp);
103862306a36Sopenharmony_ci	if (tp->t_ticket) {
103962306a36Sopenharmony_ci		if (regrant && !xlog_is_shutdown(log))
104062306a36Sopenharmony_ci			xfs_log_ticket_regrant(log, tp->t_ticket);
104162306a36Sopenharmony_ci		else
104262306a36Sopenharmony_ci			xfs_log_ticket_ungrant(log, tp->t_ticket);
104362306a36Sopenharmony_ci		tp->t_ticket = NULL;
104462306a36Sopenharmony_ci	}
104562306a36Sopenharmony_ci	xfs_trans_free_items(tp, !!error);
104662306a36Sopenharmony_ci	xfs_trans_free(tp);
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_ci	XFS_STATS_INC(mp, xs_trans_empty);
104962306a36Sopenharmony_ci	return error;
105062306a36Sopenharmony_ci}
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ciint
105362306a36Sopenharmony_cixfs_trans_commit(
105462306a36Sopenharmony_ci	struct xfs_trans	*tp)
105562306a36Sopenharmony_ci{
105662306a36Sopenharmony_ci	return __xfs_trans_commit(tp, false);
105762306a36Sopenharmony_ci}
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_ci/*
106062306a36Sopenharmony_ci * Unlock all of the transaction's items and free the transaction.  If the
106162306a36Sopenharmony_ci * transaction is dirty, we must shut down the filesystem because there is no
106262306a36Sopenharmony_ci * way to restore them to their previous state.
106362306a36Sopenharmony_ci *
106462306a36Sopenharmony_ci * If the transaction has made a log reservation, make sure to release it as
106562306a36Sopenharmony_ci * well.
106662306a36Sopenharmony_ci *
106762306a36Sopenharmony_ci * This is a high level function (equivalent to xfs_trans_commit()) and so can
106862306a36Sopenharmony_ci * be called after the transaction has effectively been aborted due to the mount
106962306a36Sopenharmony_ci * being shut down. However, if the mount has not been shut down and the
107062306a36Sopenharmony_ci * transaction is dirty we will shut the mount down and, in doing so, that
107162306a36Sopenharmony_ci * guarantees that the log is shut down, too. Hence we don't need to be as
107262306a36Sopenharmony_ci * careful with shutdown state and dirty items here as we need to be in
107362306a36Sopenharmony_ci * xfs_trans_commit().
107462306a36Sopenharmony_ci */
107562306a36Sopenharmony_civoid
107662306a36Sopenharmony_cixfs_trans_cancel(
107762306a36Sopenharmony_ci	struct xfs_trans	*tp)
107862306a36Sopenharmony_ci{
107962306a36Sopenharmony_ci	struct xfs_mount	*mp = tp->t_mountp;
108062306a36Sopenharmony_ci	struct xlog		*log = mp->m_log;
108162306a36Sopenharmony_ci	bool			dirty = (tp->t_flags & XFS_TRANS_DIRTY);
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_ci	trace_xfs_trans_cancel(tp, _RET_IP_);
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ci	/*
108662306a36Sopenharmony_ci	 * It's never valid to cancel a transaction with deferred ops attached,
108762306a36Sopenharmony_ci	 * because the transaction is effectively dirty.  Complain about this
108862306a36Sopenharmony_ci	 * loudly before freeing the in-memory defer items and shutting down the
108962306a36Sopenharmony_ci	 * filesystem.
109062306a36Sopenharmony_ci	 */
109162306a36Sopenharmony_ci	if (!list_empty(&tp->t_dfops)) {
109262306a36Sopenharmony_ci		ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
109362306a36Sopenharmony_ci		dirty = true;
109462306a36Sopenharmony_ci		xfs_defer_cancel(tp);
109562306a36Sopenharmony_ci	}
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_ci	/*
109862306a36Sopenharmony_ci	 * See if the caller is relying on us to shut down the filesystem. We
109962306a36Sopenharmony_ci	 * only want an error report if there isn't already a shutdown in
110062306a36Sopenharmony_ci	 * progress, so we only need to check against the mount shutdown state
110162306a36Sopenharmony_ci	 * here.
110262306a36Sopenharmony_ci	 */
110362306a36Sopenharmony_ci	if (dirty && !xfs_is_shutdown(mp)) {
110462306a36Sopenharmony_ci		XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
110562306a36Sopenharmony_ci		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
110662306a36Sopenharmony_ci	}
110762306a36Sopenharmony_ci#ifdef DEBUG
110862306a36Sopenharmony_ci	/* Log items need to be consistent until the log is shut down. */
110962306a36Sopenharmony_ci	if (!dirty && !xlog_is_shutdown(log)) {
111062306a36Sopenharmony_ci		struct xfs_log_item *lip;
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_ci		list_for_each_entry(lip, &tp->t_items, li_trans)
111362306a36Sopenharmony_ci			ASSERT(!xlog_item_is_intent_done(lip));
111462306a36Sopenharmony_ci	}
111562306a36Sopenharmony_ci#endif
111662306a36Sopenharmony_ci	xfs_trans_unreserve_and_mod_sb(tp);
111762306a36Sopenharmony_ci	xfs_trans_unreserve_and_mod_dquots(tp);
111862306a36Sopenharmony_ci
111962306a36Sopenharmony_ci	if (tp->t_ticket) {
112062306a36Sopenharmony_ci		xfs_log_ticket_ungrant(log, tp->t_ticket);
112162306a36Sopenharmony_ci		tp->t_ticket = NULL;
112262306a36Sopenharmony_ci	}
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ci	xfs_trans_free_items(tp, dirty);
112562306a36Sopenharmony_ci	xfs_trans_free(tp);
112662306a36Sopenharmony_ci}
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci/*
112962306a36Sopenharmony_ci * Roll from one trans in the sequence of PERMANENT transactions to
113062306a36Sopenharmony_ci * the next: permanent transactions are only flushed out when
113162306a36Sopenharmony_ci * committed with xfs_trans_commit(), but we still want as soon
113262306a36Sopenharmony_ci * as possible to let chunks of it go to the log. So we commit the
113362306a36Sopenharmony_ci * chunk we've been working on and get a new transaction to continue.
113462306a36Sopenharmony_ci */
113562306a36Sopenharmony_ciint
113662306a36Sopenharmony_cixfs_trans_roll(
113762306a36Sopenharmony_ci	struct xfs_trans	**tpp)
113862306a36Sopenharmony_ci{
113962306a36Sopenharmony_ci	struct xfs_trans	*trans = *tpp;
114062306a36Sopenharmony_ci	struct xfs_trans_res	tres;
114162306a36Sopenharmony_ci	int			error;
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci	trace_xfs_trans_roll(trans, _RET_IP_);
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_ci	/*
114662306a36Sopenharmony_ci	 * Copy the critical parameters from one trans to the next.
114762306a36Sopenharmony_ci	 */
114862306a36Sopenharmony_ci	tres.tr_logres = trans->t_log_res;
114962306a36Sopenharmony_ci	tres.tr_logcount = trans->t_log_count;
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci	*tpp = xfs_trans_dup(trans);
115262306a36Sopenharmony_ci
115362306a36Sopenharmony_ci	/*
115462306a36Sopenharmony_ci	 * Commit the current transaction.
115562306a36Sopenharmony_ci	 * If this commit failed, then it'd just unlock those items that
115662306a36Sopenharmony_ci	 * are not marked ihold. That also means that a filesystem shutdown
115762306a36Sopenharmony_ci	 * is in progress. The caller takes the responsibility to cancel
115862306a36Sopenharmony_ci	 * the duplicate transaction that gets returned.
115962306a36Sopenharmony_ci	 */
116062306a36Sopenharmony_ci	error = __xfs_trans_commit(trans, true);
116162306a36Sopenharmony_ci	if (error)
116262306a36Sopenharmony_ci		return error;
116362306a36Sopenharmony_ci
116462306a36Sopenharmony_ci	/*
116562306a36Sopenharmony_ci	 * Reserve space in the log for the next transaction.
116662306a36Sopenharmony_ci	 * This also pushes items in the "AIL", the list of logged items,
116762306a36Sopenharmony_ci	 * out to disk if they are taking up space at the tail of the log
116862306a36Sopenharmony_ci	 * that we want to use.  This requires that either nothing be locked
116962306a36Sopenharmony_ci	 * across this call, or that anything that is locked be logged in
117062306a36Sopenharmony_ci	 * the prior and the next transactions.
117162306a36Sopenharmony_ci	 */
117262306a36Sopenharmony_ci	tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
117362306a36Sopenharmony_ci	return xfs_trans_reserve(*tpp, &tres, 0, 0);
117462306a36Sopenharmony_ci}
117562306a36Sopenharmony_ci
117662306a36Sopenharmony_ci/*
117762306a36Sopenharmony_ci * Allocate an transaction, lock and join the inode to it, and reserve quota.
117862306a36Sopenharmony_ci *
117962306a36Sopenharmony_ci * The caller must ensure that the on-disk dquots attached to this inode have
118062306a36Sopenharmony_ci * already been allocated and initialized.  The caller is responsible for
118162306a36Sopenharmony_ci * releasing ILOCK_EXCL if a new transaction is returned.
118262306a36Sopenharmony_ci */
118362306a36Sopenharmony_ciint
118462306a36Sopenharmony_cixfs_trans_alloc_inode(
118562306a36Sopenharmony_ci	struct xfs_inode	*ip,
118662306a36Sopenharmony_ci	struct xfs_trans_res	*resv,
118762306a36Sopenharmony_ci	unsigned int		dblocks,
118862306a36Sopenharmony_ci	unsigned int		rblocks,
118962306a36Sopenharmony_ci	bool			force,
119062306a36Sopenharmony_ci	struct xfs_trans	**tpp)
119162306a36Sopenharmony_ci{
119262306a36Sopenharmony_ci	struct xfs_trans	*tp;
119362306a36Sopenharmony_ci	struct xfs_mount	*mp = ip->i_mount;
119462306a36Sopenharmony_ci	bool			retried = false;
119562306a36Sopenharmony_ci	int			error;
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ciretry:
119862306a36Sopenharmony_ci	error = xfs_trans_alloc(mp, resv, dblocks,
119962306a36Sopenharmony_ci			rblocks / mp->m_sb.sb_rextsize,
120062306a36Sopenharmony_ci			force ? XFS_TRANS_RESERVE : 0, &tp);
120162306a36Sopenharmony_ci	if (error)
120262306a36Sopenharmony_ci		return error;
120362306a36Sopenharmony_ci
120462306a36Sopenharmony_ci	xfs_ilock(ip, XFS_ILOCK_EXCL);
120562306a36Sopenharmony_ci	xfs_trans_ijoin(tp, ip, 0);
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci	error = xfs_qm_dqattach_locked(ip, false);
120862306a36Sopenharmony_ci	if (error) {
120962306a36Sopenharmony_ci		/* Caller should have allocated the dquots! */
121062306a36Sopenharmony_ci		ASSERT(error != -ENOENT);
121162306a36Sopenharmony_ci		goto out_cancel;
121262306a36Sopenharmony_ci	}
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_ci	error = xfs_trans_reserve_quota_nblks(tp, ip, dblocks, rblocks, force);
121562306a36Sopenharmony_ci	if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
121662306a36Sopenharmony_ci		xfs_trans_cancel(tp);
121762306a36Sopenharmony_ci		xfs_iunlock(ip, XFS_ILOCK_EXCL);
121862306a36Sopenharmony_ci		xfs_blockgc_free_quota(ip, 0);
121962306a36Sopenharmony_ci		retried = true;
122062306a36Sopenharmony_ci		goto retry;
122162306a36Sopenharmony_ci	}
122262306a36Sopenharmony_ci	if (error)
122362306a36Sopenharmony_ci		goto out_cancel;
122462306a36Sopenharmony_ci
122562306a36Sopenharmony_ci	*tpp = tp;
122662306a36Sopenharmony_ci	return 0;
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_ciout_cancel:
122962306a36Sopenharmony_ci	xfs_trans_cancel(tp);
123062306a36Sopenharmony_ci	xfs_iunlock(ip, XFS_ILOCK_EXCL);
123162306a36Sopenharmony_ci	return error;
123262306a36Sopenharmony_ci}
123362306a36Sopenharmony_ci
123462306a36Sopenharmony_ci/*
123562306a36Sopenharmony_ci * Allocate an transaction in preparation for inode creation by reserving quota
123662306a36Sopenharmony_ci * against the given dquots.  Callers are not required to hold any inode locks.
123762306a36Sopenharmony_ci */
123862306a36Sopenharmony_ciint
123962306a36Sopenharmony_cixfs_trans_alloc_icreate(
124062306a36Sopenharmony_ci	struct xfs_mount	*mp,
124162306a36Sopenharmony_ci	struct xfs_trans_res	*resv,
124262306a36Sopenharmony_ci	struct xfs_dquot	*udqp,
124362306a36Sopenharmony_ci	struct xfs_dquot	*gdqp,
124462306a36Sopenharmony_ci	struct xfs_dquot	*pdqp,
124562306a36Sopenharmony_ci	unsigned int		dblocks,
124662306a36Sopenharmony_ci	struct xfs_trans	**tpp)
124762306a36Sopenharmony_ci{
124862306a36Sopenharmony_ci	struct xfs_trans	*tp;
124962306a36Sopenharmony_ci	bool			retried = false;
125062306a36Sopenharmony_ci	int			error;
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ciretry:
125362306a36Sopenharmony_ci	error = xfs_trans_alloc(mp, resv, dblocks, 0, 0, &tp);
125462306a36Sopenharmony_ci	if (error)
125562306a36Sopenharmony_ci		return error;
125662306a36Sopenharmony_ci
125762306a36Sopenharmony_ci	error = xfs_trans_reserve_quota_icreate(tp, udqp, gdqp, pdqp, dblocks);
125862306a36Sopenharmony_ci	if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
125962306a36Sopenharmony_ci		xfs_trans_cancel(tp);
126062306a36Sopenharmony_ci		xfs_blockgc_free_dquots(mp, udqp, gdqp, pdqp, 0);
126162306a36Sopenharmony_ci		retried = true;
126262306a36Sopenharmony_ci		goto retry;
126362306a36Sopenharmony_ci	}
126462306a36Sopenharmony_ci	if (error) {
126562306a36Sopenharmony_ci		xfs_trans_cancel(tp);
126662306a36Sopenharmony_ci		return error;
126762306a36Sopenharmony_ci	}
126862306a36Sopenharmony_ci
126962306a36Sopenharmony_ci	*tpp = tp;
127062306a36Sopenharmony_ci	return 0;
127162306a36Sopenharmony_ci}
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci/*
127462306a36Sopenharmony_ci * Allocate an transaction, lock and join the inode to it, and reserve quota
127562306a36Sopenharmony_ci * in preparation for inode attribute changes that include uid, gid, or prid
127662306a36Sopenharmony_ci * changes.
127762306a36Sopenharmony_ci *
127862306a36Sopenharmony_ci * The caller must ensure that the on-disk dquots attached to this inode have
127962306a36Sopenharmony_ci * already been allocated and initialized.  The ILOCK will be dropped when the
128062306a36Sopenharmony_ci * transaction is committed or cancelled.
128162306a36Sopenharmony_ci */
128262306a36Sopenharmony_ciint
128362306a36Sopenharmony_cixfs_trans_alloc_ichange(
128462306a36Sopenharmony_ci	struct xfs_inode	*ip,
128562306a36Sopenharmony_ci	struct xfs_dquot	*new_udqp,
128662306a36Sopenharmony_ci	struct xfs_dquot	*new_gdqp,
128762306a36Sopenharmony_ci	struct xfs_dquot	*new_pdqp,
128862306a36Sopenharmony_ci	bool			force,
128962306a36Sopenharmony_ci	struct xfs_trans	**tpp)
129062306a36Sopenharmony_ci{
129162306a36Sopenharmony_ci	struct xfs_trans	*tp;
129262306a36Sopenharmony_ci	struct xfs_mount	*mp = ip->i_mount;
129362306a36Sopenharmony_ci	struct xfs_dquot	*udqp;
129462306a36Sopenharmony_ci	struct xfs_dquot	*gdqp;
129562306a36Sopenharmony_ci	struct xfs_dquot	*pdqp;
129662306a36Sopenharmony_ci	bool			retried = false;
129762306a36Sopenharmony_ci	int			error;
129862306a36Sopenharmony_ci
129962306a36Sopenharmony_ciretry:
130062306a36Sopenharmony_ci	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
130162306a36Sopenharmony_ci	if (error)
130262306a36Sopenharmony_ci		return error;
130362306a36Sopenharmony_ci
130462306a36Sopenharmony_ci	xfs_ilock(ip, XFS_ILOCK_EXCL);
130562306a36Sopenharmony_ci	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
130662306a36Sopenharmony_ci
130762306a36Sopenharmony_ci	error = xfs_qm_dqattach_locked(ip, false);
130862306a36Sopenharmony_ci	if (error) {
130962306a36Sopenharmony_ci		/* Caller should have allocated the dquots! */
131062306a36Sopenharmony_ci		ASSERT(error != -ENOENT);
131162306a36Sopenharmony_ci		goto out_cancel;
131262306a36Sopenharmony_ci	}
131362306a36Sopenharmony_ci
131462306a36Sopenharmony_ci	/*
131562306a36Sopenharmony_ci	 * For each quota type, skip quota reservations if the inode's dquots
131662306a36Sopenharmony_ci	 * now match the ones that came from the caller, or the caller didn't
131762306a36Sopenharmony_ci	 * pass one in.  The inode's dquots can change if we drop the ILOCK to
131862306a36Sopenharmony_ci	 * perform a blockgc scan, so we must preserve the caller's arguments.
131962306a36Sopenharmony_ci	 */
132062306a36Sopenharmony_ci	udqp = (new_udqp != ip->i_udquot) ? new_udqp : NULL;
132162306a36Sopenharmony_ci	gdqp = (new_gdqp != ip->i_gdquot) ? new_gdqp : NULL;
132262306a36Sopenharmony_ci	pdqp = (new_pdqp != ip->i_pdquot) ? new_pdqp : NULL;
132362306a36Sopenharmony_ci	if (udqp || gdqp || pdqp) {
132462306a36Sopenharmony_ci		unsigned int	qflags = XFS_QMOPT_RES_REGBLKS;
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_ci		if (force)
132762306a36Sopenharmony_ci			qflags |= XFS_QMOPT_FORCE_RES;
132862306a36Sopenharmony_ci
132962306a36Sopenharmony_ci		/*
133062306a36Sopenharmony_ci		 * Reserve enough quota to handle blocks on disk and reserved
133162306a36Sopenharmony_ci		 * for a delayed allocation.  We'll actually transfer the
133262306a36Sopenharmony_ci		 * delalloc reservation between dquots at chown time, even
133362306a36Sopenharmony_ci		 * though that part is only semi-transactional.
133462306a36Sopenharmony_ci		 */
133562306a36Sopenharmony_ci		error = xfs_trans_reserve_quota_bydquots(tp, mp, udqp, gdqp,
133662306a36Sopenharmony_ci				pdqp, ip->i_nblocks + ip->i_delayed_blks,
133762306a36Sopenharmony_ci				1, qflags);
133862306a36Sopenharmony_ci		if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
133962306a36Sopenharmony_ci			xfs_trans_cancel(tp);
134062306a36Sopenharmony_ci			xfs_blockgc_free_dquots(mp, udqp, gdqp, pdqp, 0);
134162306a36Sopenharmony_ci			retried = true;
134262306a36Sopenharmony_ci			goto retry;
134362306a36Sopenharmony_ci		}
134462306a36Sopenharmony_ci		if (error)
134562306a36Sopenharmony_ci			goto out_cancel;
134662306a36Sopenharmony_ci	}
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_ci	*tpp = tp;
134962306a36Sopenharmony_ci	return 0;
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ciout_cancel:
135262306a36Sopenharmony_ci	xfs_trans_cancel(tp);
135362306a36Sopenharmony_ci	return error;
135462306a36Sopenharmony_ci}
135562306a36Sopenharmony_ci
135662306a36Sopenharmony_ci/*
135762306a36Sopenharmony_ci * Allocate an transaction, lock and join the directory and child inodes to it,
135862306a36Sopenharmony_ci * and reserve quota for a directory update.  If there isn't sufficient space,
135962306a36Sopenharmony_ci * @dblocks will be set to zero for a reservationless directory update and
136062306a36Sopenharmony_ci * @nospace_error will be set to a negative errno describing the space
136162306a36Sopenharmony_ci * constraint we hit.
136262306a36Sopenharmony_ci *
136362306a36Sopenharmony_ci * The caller must ensure that the on-disk dquots attached to this inode have
136462306a36Sopenharmony_ci * already been allocated and initialized.  The ILOCKs will be dropped when the
136562306a36Sopenharmony_ci * transaction is committed or cancelled.
136662306a36Sopenharmony_ci */
136762306a36Sopenharmony_ciint
136862306a36Sopenharmony_cixfs_trans_alloc_dir(
136962306a36Sopenharmony_ci	struct xfs_inode	*dp,
137062306a36Sopenharmony_ci	struct xfs_trans_res	*resv,
137162306a36Sopenharmony_ci	struct xfs_inode	*ip,
137262306a36Sopenharmony_ci	unsigned int		*dblocks,
137362306a36Sopenharmony_ci	struct xfs_trans	**tpp,
137462306a36Sopenharmony_ci	int			*nospace_error)
137562306a36Sopenharmony_ci{
137662306a36Sopenharmony_ci	struct xfs_trans	*tp;
137762306a36Sopenharmony_ci	struct xfs_mount	*mp = ip->i_mount;
137862306a36Sopenharmony_ci	unsigned int		resblks;
137962306a36Sopenharmony_ci	bool			retried = false;
138062306a36Sopenharmony_ci	int			error;
138162306a36Sopenharmony_ci
138262306a36Sopenharmony_ciretry:
138362306a36Sopenharmony_ci	*nospace_error = 0;
138462306a36Sopenharmony_ci	resblks = *dblocks;
138562306a36Sopenharmony_ci	error = xfs_trans_alloc(mp, resv, resblks, 0, 0, &tp);
138662306a36Sopenharmony_ci	if (error == -ENOSPC) {
138762306a36Sopenharmony_ci		*nospace_error = error;
138862306a36Sopenharmony_ci		resblks = 0;
138962306a36Sopenharmony_ci		error = xfs_trans_alloc(mp, resv, resblks, 0, 0, &tp);
139062306a36Sopenharmony_ci	}
139162306a36Sopenharmony_ci	if (error)
139262306a36Sopenharmony_ci		return error;
139362306a36Sopenharmony_ci
139462306a36Sopenharmony_ci	xfs_lock_two_inodes(dp, XFS_ILOCK_EXCL, ip, XFS_ILOCK_EXCL);
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci	xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
139762306a36Sopenharmony_ci	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_ci	error = xfs_qm_dqattach_locked(dp, false);
140062306a36Sopenharmony_ci	if (error) {
140162306a36Sopenharmony_ci		/* Caller should have allocated the dquots! */
140262306a36Sopenharmony_ci		ASSERT(error != -ENOENT);
140362306a36Sopenharmony_ci		goto out_cancel;
140462306a36Sopenharmony_ci	}
140562306a36Sopenharmony_ci
140662306a36Sopenharmony_ci	error = xfs_qm_dqattach_locked(ip, false);
140762306a36Sopenharmony_ci	if (error) {
140862306a36Sopenharmony_ci		/* Caller should have allocated the dquots! */
140962306a36Sopenharmony_ci		ASSERT(error != -ENOENT);
141062306a36Sopenharmony_ci		goto out_cancel;
141162306a36Sopenharmony_ci	}
141262306a36Sopenharmony_ci
141362306a36Sopenharmony_ci	if (resblks == 0)
141462306a36Sopenharmony_ci		goto done;
141562306a36Sopenharmony_ci
141662306a36Sopenharmony_ci	error = xfs_trans_reserve_quota_nblks(tp, dp, resblks, 0, false);
141762306a36Sopenharmony_ci	if (error == -EDQUOT || error == -ENOSPC) {
141862306a36Sopenharmony_ci		if (!retried) {
141962306a36Sopenharmony_ci			xfs_trans_cancel(tp);
142062306a36Sopenharmony_ci			xfs_blockgc_free_quota(dp, 0);
142162306a36Sopenharmony_ci			retried = true;
142262306a36Sopenharmony_ci			goto retry;
142362306a36Sopenharmony_ci		}
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_ci		*nospace_error = error;
142662306a36Sopenharmony_ci		resblks = 0;
142762306a36Sopenharmony_ci		error = 0;
142862306a36Sopenharmony_ci	}
142962306a36Sopenharmony_ci	if (error)
143062306a36Sopenharmony_ci		goto out_cancel;
143162306a36Sopenharmony_ci
143262306a36Sopenharmony_cidone:
143362306a36Sopenharmony_ci	*tpp = tp;
143462306a36Sopenharmony_ci	*dblocks = resblks;
143562306a36Sopenharmony_ci	return 0;
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ciout_cancel:
143862306a36Sopenharmony_ci	xfs_trans_cancel(tp);
143962306a36Sopenharmony_ci	return error;
144062306a36Sopenharmony_ci}
1441