From: Darrick J. Wong Date: Thu, 24 Mar 2022 17:57:07 +0000 (-0700) Subject: xfs: fix overfilling of reserve pool X-Git-Tag: v6.1-rc5~1628^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=82be38bcf8a2e056b4c99ce79a3827fa743df6ec;p=platform%2Fkernel%2Flinux-starfive.git xfs: fix overfilling of reserve pool Due to cycling of m_sb_lock, it's possible for multiple callers of xfs_reserve_blocks to race at changing the pool size, subtracting blocks from fdblocks, and actually putting it in the pool. The result of all this is that we can overfill the reserve pool to hilarious levels. xfs_mod_fdblocks, when called with a positive value, already knows how to take freed blocks and either fill the reserve until it's full, or put them in fdblocks. Use that instead of setting m_resblks_avail directly. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 5c2bea1..5b5b68a 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -448,18 +448,17 @@ xfs_reserve_blocks( * count or we'll get an ENOSPC. Don't set the reserved flag * here - we don't want to reserve the extra reserve blocks * from the reserve. + * + * The desired reserve size can change after we drop the lock. + * Use mod_fdblocks to put the space into the reserve or into + * fdblocks as appropriate. */ fdblks_delta = min(free, delta); spin_unlock(&mp->m_sb_lock); error = xfs_mod_fdblocks(mp, -fdblks_delta, 0); - spin_lock(&mp->m_sb_lock); - - /* - * Update the reserve counters if blocks have been successfully - * allocated. - */ if (!error) - mp->m_resblks_avail += fdblks_delta; + xfs_mod_fdblocks(mp, fdblks_delta, 0); + spin_lock(&mp->m_sb_lock); } out: if (outval) {