lkml.org 
[lkml]   [2020]   [Aug]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.7 045/124] xfs: fix inode quota reservation checks
    Date
    From: Darrick J. Wong <darrick.wong@oracle.com>

    [ Upstream commit f959b5d037e71a4d69b5bf71faffa065d9269b4a ]

    xfs_trans_dqresv is the function that we use to make reservations
    against resource quotas. Each resource contains two counters: the
    q_core counter, which tracks resources allocated on disk; and the dquot
    reservation counter, which tracks how much of that resource has either
    been allocated or reserved by threads that are working on metadata
    updates.

    For disk blocks, we compare the proposed reservation counter against the
    hard and soft limits to decide if we're going to fail the operation.
    However, for inodes we inexplicably compare against the q_core counter,
    not the incore reservation count.

    Since the q_core counter is always lower than the reservation count and
    we unlock the dquot between reservation and transaction commit, this
    means that multiple threads can reserve the last inode count before we
    hit the hard limit, and when they commit, we'll be well over the hard
    limit.

    Fix this by checking against the incore inode reservation counter, since
    we would appear to maintain that correctly (and that's what we report in
    GETQUOTA).

    Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
    Reviewed-by: Allison Collins <allison.henderson@oracle.com>
    Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/xfs/xfs_trans_dquot.c | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
    index d1b9869bc5fa6..af3636a99bf60 100644
    --- a/fs/xfs/xfs_trans_dquot.c
    +++ b/fs/xfs/xfs_trans_dquot.c
    @@ -647,7 +647,7 @@ xfs_trans_dqresv(
    }
    }
    if (ninos > 0) {
    - total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos;
    + total_count = dqp->q_res_icount + ninos;
    timer = be32_to_cpu(dqp->q_core.d_itimer);
    warns = be16_to_cpu(dqp->q_core.d_iwarns);
    warnlimit = dqp->q_mount->m_quotainfo->qi_iwarnlimit;
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-08-24 11:49    [W:2.392 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site