Commit ff31f017 authored by Darrick J. Wong's avatar Darrick J. Wong Committed by openeuler-sync-bot
Browse files

xfs: always succeed at setting the reserve pool size

stable inclusion
from stable-v5.10.141
commit 72a259bdd50dd6646a88e29fc769e50377e06d57
category: bugfix
bugzilla: 188251,https://gitee.com/openeuler/kernel/issues/I685FC
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=72a259bdd50dd6646a88e29fc769e50377e06d57



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

commit 0baa2657 upstream.

Nowadays, xfs_mod_fdblocks will always choose to fill the reserve pool
with freed blocks before adding to fdblocks.  Therefore, we can change
the behavior of xfs_reserve_blocks slightly -- setting the target size
of the pool should always succeed, since a deficiency will eventually
be made up as blocks get freed.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Signed-off-by: default avatarAmir Goldstein <amir73il@gmail.com>
Acked-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avataryangerkun <yangerkun@huawei.com>
Reviewed-by: default avatarZhang Yi <yi.zhang@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
(cherry picked from commit d7ed84ea)
parent 797a30ec
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -378,11 +378,14 @@ xfs_reserve_blocks(
	 * The code below estimates how many blocks it can request from
	 * fdblocks to stash in the reserve pool.  This is a classic TOCTOU
	 * race since fdblocks updates are not always coordinated via
	 * m_sb_lock.
	 * m_sb_lock.  Set the reserve size even if there's not enough free
	 * space to fill it because mod_fdblocks will refill an undersized
	 * reserve when it can.
	 */
	free = percpu_counter_sum(&mp->m_fdblocks) -
						xfs_fdblocks_unavailable(mp);
	delta = request - mp->m_resblks;
	mp->m_resblks = request;
	if (delta > 0 && free > 0) {
		/*
		 * We'll either succeed in getting space from the free block
@@ -399,11 +402,9 @@ xfs_reserve_blocks(
		 * Update the reserve counters if blocks have been successfully
		 * allocated.
		 */
		if (!error) {
			mp->m_resblks += fdblks_delta;
		if (!error)
			mp->m_resblks_avail += fdblks_delta;
	}
	}
out:
	if (outval) {
		outval->resblks = mp->m_resblks;