Skip to content

Commit 82be38b

Browse files
author
Darrick J. Wong
committed
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 <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com>
1 parent 0baa265 commit 82be38b

1 file changed

Lines changed: 6 additions & 7 deletions

File tree

fs/xfs/xfs_fsops.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -448,18 +448,17 @@ xfs_reserve_blocks(
448448
* count or we'll get an ENOSPC. Don't set the reserved flag
449449
* here - we don't want to reserve the extra reserve blocks
450450
* from the reserve.
451+
*
452+
* The desired reserve size can change after we drop the lock.
453+
* Use mod_fdblocks to put the space into the reserve or into
454+
* fdblocks as appropriate.
451455
*/
452456
fdblks_delta = min(free, delta);
453457
spin_unlock(&mp->m_sb_lock);
454458
error = xfs_mod_fdblocks(mp, -fdblks_delta, 0);
455-
spin_lock(&mp->m_sb_lock);
456-
457-
/*
458-
* Update the reserve counters if blocks have been successfully
459-
* allocated.
460-
*/
461459
if (!error)
462-
mp->m_resblks_avail += fdblks_delta;
460+
xfs_mod_fdblocks(mp, fdblks_delta, 0);
461+
spin_lock(&mp->m_sb_lock);
463462
}
464463
out:
465464
if (outval) {

0 commit comments

Comments
 (0)