lkml.org 
[lkml]   [2022]   [Aug]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 241/244] xfs: fix overfilling of reserve pool
    Date
    From: "Darrick J. Wong" <djwong@kernel.org>

    [ Upstream commit 82be38bcf8a2e056b4c99ce79a3827fa743df6ec ]

    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>
    Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
    Acked-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/xfs/xfs_fsops.c | 13 ++++++-------
    1 file changed, 6 insertions(+), 7 deletions(-)

    --- 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) {

    \
     
     \ /
      Last update: 2022-08-23 12:34    [W:2.677 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site