Commit a90cde3f authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Zizhi Wo
Browse files

xfs: split xfs_mod_freecounter

mainline inclusion
from mainline-v6.10-rc1
commit f30f656e25eb72c4309e76b16fa45062e183a2ee
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IB7V02

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f30f656e25eb72c4309e76b16fa45062e183a2ee



--------------------------------

xfs_mod_freecounter has two entirely separate code paths for adding or
subtracting from the free counters.  Only the subtract case looks at the
rsvd flag and can return an error.

Split xfs_mod_freecounter into separate helpers for subtracting or
adding the freecounter, and remove all the impossible to reach error
handling for the addition case.

Fixes: 0d485ada ("xfs: use generic percpu counters for free block counter")
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatar"Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandanbabu@kernel.org>

Conflicts:
	fs/xfs/libxfs/xfs_bmap.c
	fs/xfs/scrub/repair.c
	fs/xfs/xfs_fsops.h
	fs/xfs/xfs_trans.c
[One part is due to the function not existing, and the other part is due
to a context conflict.]
Signed-off-by: default avatarZizhi Wo <wozizhi@huawei.com>
parent df4c334b
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -967,9 +967,7 @@ xfs_ag_shrink_space(
	 * Disable perag reservations so it doesn't cause the allocation request
	 * to fail. We'll reestablish reservation before we return.
	 */
	error = xfs_ag_resv_free(pag);
	if (error)
		return error;
	xfs_ag_resv_free(pag);

	/* internal log shouldn't also show up in the free space btrees */
	error = xfs_alloc_vextent_exact_bno(&args,
+6 −18
Original line number Diff line number Diff line
@@ -126,14 +126,13 @@ xfs_ag_resv_needed(
}

/* Clean out a reservation */
static int
static void
__xfs_ag_resv_free(
	struct xfs_perag		*pag,
	enum xfs_ag_resv_type		type)
{
	struct xfs_ag_resv		*resv;
	xfs_extlen_t			oldresv;
	int				error;

	trace_xfs_ag_resv_free(pag, type, 0);

@@ -149,30 +148,19 @@ __xfs_ag_resv_free(
		oldresv = resv->ar_orig_reserved;
	else
		oldresv = resv->ar_reserved;
	error = xfs_mod_fdblocks(pag->pag_mount, oldresv, true);
	xfs_add_fdblocks(pag->pag_mount, oldresv);
	resv->ar_reserved = 0;
	resv->ar_asked = 0;
	resv->ar_orig_reserved = 0;

	if (error)
		trace_xfs_ag_resv_free_error(pag->pag_mount, pag->pag_agno,
				error, _RET_IP_);
	return error;
}

/* Free a per-AG reservation. */
int
void
xfs_ag_resv_free(
	struct xfs_perag		*pag)
{
	int				error;
	int				err2;

	error = __xfs_ag_resv_free(pag, XFS_AG_RESV_RMAPBT);
	err2 = __xfs_ag_resv_free(pag, XFS_AG_RESV_METADATA);
	if (err2 && !error)
		error = err2;
	return error;
	__xfs_ag_resv_free(pag, XFS_AG_RESV_RMAPBT);
	__xfs_ag_resv_free(pag, XFS_AG_RESV_METADATA);
}

static int
@@ -216,7 +204,7 @@ __xfs_ag_resv_init(
	if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_AG_RESV_FAIL))
		error = -ENOSPC;
	else
		error = xfs_mod_fdblocks(mp, -(int64_t)hidden_space, true);
		error = xfs_dec_fdblocks(mp, hidden_space, true);
	if (error) {
		trace_xfs_ag_resv_init_error(pag->pag_mount, pag->pag_agno,
				error, _RET_IP_);
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
#ifndef __XFS_AG_RESV_H__
#define	__XFS_AG_RESV_H__

int xfs_ag_resv_free(struct xfs_perag *pag);
void xfs_ag_resv_free(struct xfs_perag *pag);
int xfs_ag_resv_init(struct xfs_perag *pag, struct xfs_trans *tp);

bool xfs_ag_resv_critical(struct xfs_perag *pag, enum xfs_ag_resv_type type);
+2 −2
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ xfs_prealloc_blocks(
}

/*
 * The number of blocks per AG that we withhold from xfs_mod_fdblocks to
 * The number of blocks per AG that we withhold from xfs_dec_fdblocks to
 * guarantee that we can refill the AGFL prior to allocating space in a nearly
 * full AG.  Although the space described by the free space btrees, the
 * blocks used by the freesp btrees themselves, and the blocks owned by the
@@ -89,7 +89,7 @@ xfs_prealloc_blocks(
 * until the fs goes down, we subtract this many AG blocks from the incore
 * fdblocks to ensure user allocation does not overcommit the space the
 * filesystem needs for the AGFLs.  The rmap btree uses a per-AG reservation to
 * withhold space from xfs_mod_fdblocks, so we do not account for that here.
 * withhold space from xfs_dec_fdblocks, so we do not account for that here.
 */
#define XFS_ALLOCBT_AGFL_RESERVE	4

+11 −10
Original line number Diff line number Diff line
@@ -1941,9 +1941,10 @@ xfs_bmap_add_extent_delay_real(
	}

	/* adjust for changes in reserved delayed indirect blocks */
	if (da_new != da_old)
		error = xfs_mod_fdblocks(mp, (int64_t)(da_old - da_new),
				true);
	if (da_new < da_old)
		xfs_add_fdblocks(mp, da_old - da_new);
	else if (da_new > da_old)
		error = xfs_dec_fdblocks(mp, da_new - da_old, true);

	xfs_bmap_check_leaf_extents(bma->cur, bma->ip, whichfork);
done:
@@ -2621,8 +2622,8 @@ xfs_bmap_add_extent_hole_delay(
	}
	if (oldlen != newlen) {
		ASSERT(oldlen > newlen);
		xfs_mod_fdblocks(ip->i_mount, (int64_t)(oldlen - newlen),
				 false);
		xfs_add_fdblocks(ip->i_mount, oldlen - newlen);

		/*
		 * Nothing to do for disk quota accounting here.
		 */
@@ -4028,11 +4029,11 @@ xfs_bmapi_reserve_delalloc(
	indlen = (xfs_extlen_t)xfs_bmap_worst_indlen(ip, alen);
	ASSERT(indlen > 0);

	error = xfs_mod_fdblocks(mp, -((int64_t)alen), false);
	error = xfs_dec_fdblocks(mp, alen, false);
	if (error)
		goto out_unreserve_quota;

	error = xfs_mod_fdblocks(mp, -((int64_t)indlen), false);
	error = xfs_dec_fdblocks(mp, indlen, false);
	if (error)
		goto out_unreserve_blocks;

@@ -4060,7 +4061,7 @@ xfs_bmapi_reserve_delalloc(
	return 0;

out_unreserve_blocks:
	xfs_mod_fdblocks(mp, alen, false);
	xfs_add_fdblocks(mp, alen);
out_unreserve_quota:
	if (XFS_IS_QUOTA_ON(mp))
		xfs_quota_unreserve_blkres(ip, alen);
@@ -4919,7 +4920,7 @@ xfs_bmap_del_extent_delay(
		uint64_t	rtexts = del->br_blockcount;

		do_div(rtexts, mp->m_sb.sb_rextsize);
		xfs_mod_frextents(mp, rtexts);
		xfs_add_frextents(mp, rtexts);
	}

	/*
@@ -5007,7 +5008,7 @@ xfs_bmap_del_extent_delay(
	if (!isrt)
		da_diff += del->br_blockcount;
	if (da_diff) {
		xfs_mod_fdblocks(mp, da_diff, false);
		xfs_add_fdblocks(mp, da_diff);
		xfs_mod_delalloc(mp, -da_diff);
	}
	return error;
Loading