xfs: always succeed at setting the reserve pool size
commit 0baa2657dc4d79202148be79a3dc36c35f425060 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: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Amir Goldstein <amir73il@gmail.com> Acked-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
cb41f22df3
commit
72a259bdd5
@@ -380,11 +380,14 @@ xfs_reserve_blocks(
|
|||||||
* The code below estimates how many blocks it can request from
|
* The code below estimates how many blocks it can request from
|
||||||
* fdblocks to stash in the reserve pool. This is a classic TOCTOU
|
* fdblocks to stash in the reserve pool. This is a classic TOCTOU
|
||||||
* race since fdblocks updates are not always coordinated via
|
* 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) -
|
free = percpu_counter_sum(&mp->m_fdblocks) -
|
||||||
xfs_fdblocks_unavailable(mp);
|
xfs_fdblocks_unavailable(mp);
|
||||||
delta = request - mp->m_resblks;
|
delta = request - mp->m_resblks;
|
||||||
|
mp->m_resblks = request;
|
||||||
if (delta > 0 && free > 0) {
|
if (delta > 0 && free > 0) {
|
||||||
/*
|
/*
|
||||||
* We'll either succeed in getting space from the free block
|
* We'll either succeed in getting space from the free block
|
||||||
@@ -401,10 +404,8 @@ xfs_reserve_blocks(
|
|||||||
* Update the reserve counters if blocks have been successfully
|
* Update the reserve counters if blocks have been successfully
|
||||||
* allocated.
|
* allocated.
|
||||||
*/
|
*/
|
||||||
if (!error) {
|
if (!error)
|
||||||
mp->m_resblks += fdblks_delta;
|
|
||||||
mp->m_resblks_avail += fdblks_delta;
|
mp->m_resblks_avail += fdblks_delta;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (outval) {
|
if (outval) {
|
||||||
|
Reference in New Issue
Block a user