lkml.org 
[lkml]   [2017]   [Jun]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.11 106/115] xfs: wait on new inodes during quotaoff dquot release
    Date
    4.11-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Brian Foster <bfoster@redhat.com>

    commit e20c8a517f259cb4d258e10b0cd5d4b30d4167a0 upstream.

    The quotaoff operation has a race with inode allocation that results
    in a livelock. An inode allocation that occurs before the quota
    status flags are updated acquires the appropriate dquots for the
    inode via xfs_qm_vop_dqalloc(). It then inserts the XFS_INEW inode
    into the perag radix tree, sometime later attaches the dquots to the
    inode and finally clears the XFS_INEW flag. Quotaoff expects to
    release the dquots from all inodes in the filesystem via
    xfs_qm_dqrele_all_inodes(). This invokes the AG inode iterator,
    which skips inodes in the XFS_INEW state because they are not fully
    constructed. If the scan occurs after dquots have been attached to
    an inode, but before XFS_INEW is cleared, the newly allocated inode
    will continue to hold a reference to the applicable dquots. When
    quotaoff invokes xfs_qm_dqpurge_all(), the reference count of those
    dquot(s) remain elevated and the dqpurge scan spins indefinitely.

    To address this problem, update the xfs_qm_dqrele_all_inodes() scan
    to wait on inodes marked on the XFS_INEW state. We wait on the
    inodes explicitly rather than skip and retry to avoid continuous
    retry loops due to a parallel inode allocation workload. Since
    quotaoff updates the quota state flags and uses a synchronous
    transaction before the dqrele scan, and dquots are attached to
    inodes after radix tree insertion iff quota is enabled, one INEW
    waiting pass through the AG guarantees that the scan has processed
    all inodes that could possibly hold dquot references.

    Reported-by: Eryu Guan <eguan@redhat.com>
    Signed-off-by: Brian Foster <bfoster@redhat.com>
    Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
    Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/xfs/xfs_qm_syscalls.c | 3 ++-
    1 file changed, 2 insertions(+), 1 deletion(-)

    --- a/fs/xfs/xfs_qm_syscalls.c
    +++ b/fs/xfs/xfs_qm_syscalls.c
    @@ -759,5 +759,6 @@ xfs_qm_dqrele_all_inodes(
    uint flags)
    {
    ASSERT(mp->m_quotainfo);
    - xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, NULL);
    + xfs_inode_ag_iterator_flags(mp, xfs_dqrele_inode, flags, NULL,
    + XFS_AGITER_INEW_WAIT);
    }

    \
     
     \ /
      Last update: 2017-06-12 00:24    [W:2.427 / U:0.268 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site