]> git.baikalelectronics.ru Git - kernel.git/commitdiff
xfs: trylock underlying buffer on dquot flush
authorBrian Foster <bfoster@redhat.com>
Fri, 27 Mar 2020 15:29:45 +0000 (08:29 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Sat, 28 Mar 2020 16:40:11 +0000 (09:40 -0700)
A dquot flush currently blocks on the buffer lock for the underlying
dquot buffer. In turn, this causes xfsaild to block rather than
continue processing other items in the meantime. Update
xfs_qm_dqflush() to trylock the buffer, similar to how inode buffers
are handled, and return -EAGAIN if the lock fails. Fix up any
callers that don't currently handle the error properly.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/xfs_dquot.c
fs/xfs/xfs_dquot_item.c
fs/xfs/xfs_qm.c

index 711376ca269f6718d5438381ae5518b4f97473cb..af2c8e5ceea0288dcb94dd177c447de92ea4ad69 100644 (file)
@@ -1105,8 +1105,8 @@ xfs_qm_dqflush(
         * Get the buffer containing the on-disk dquot
         */
        error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno,
-                                  mp->m_quotainfo->qi_dqchunklen, 0, &bp,
-                                  &xfs_dquot_buf_ops);
+                                  mp->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK,
+                                  &bp, &xfs_dquot_buf_ops);
        if (error)
                goto out_unlock;
 
@@ -1177,7 +1177,7 @@ xfs_qm_dqflush(
 
 out_unlock:
        xfs_dqfunlock(dqp);
-       return -EIO;
+       return error;
 }
 
 /*
index cf65e2e43c6e2cb8a5772b7ee1c883d9bfb10e4a..baad1748d0d101eef191fb981619c918241cb539 100644 (file)
@@ -189,7 +189,8 @@ xfs_qm_dquot_logitem_push(
                if (!xfs_buf_delwri_queue(bp, buffer_list))
                        rval = XFS_ITEM_FLUSHING;
                xfs_buf_relse(bp);
-       }
+       } else if (error == -EAGAIN)
+               rval = XFS_ITEM_LOCKED;
 
        spin_lock(&lip->li_ailp->ail_lock);
 out_unlock:
index cabdb755adaec6e023107c9cffb27d61ae494926..c225691fad156f729bafdb9b0b91602d70ce2d21 100644 (file)
@@ -121,12 +121,11 @@ xfs_qm_dqpurge(
 {
        struct xfs_mount        *mp = dqp->q_mount;
        struct xfs_quotainfo    *qi = mp->m_quotainfo;
+       int                     error = -EAGAIN;
 
        xfs_dqlock(dqp);
-       if ((dqp->dq_flags & XFS_DQ_FREEING) || dqp->q_nrefs != 0) {
-               xfs_dqunlock(dqp);
-               return -EAGAIN;
-       }
+       if ((dqp->dq_flags & XFS_DQ_FREEING) || dqp->q_nrefs != 0)
+               goto out_unlock;
 
        dqp->dq_flags |= XFS_DQ_FREEING;
 
@@ -139,7 +138,6 @@ xfs_qm_dqpurge(
         */
        if (XFS_DQ_IS_DIRTY(dqp)) {
                struct xfs_buf  *bp = NULL;
-               int             error;
 
                /*
                 * We don't care about getting disk errors here. We need
@@ -149,6 +147,8 @@ xfs_qm_dqpurge(
                if (!error) {
                        error = xfs_bwrite(bp);
                        xfs_buf_relse(bp);
+               } else if (error == -EAGAIN) {
+                       goto out_unlock;
                }
                xfs_dqflock(dqp);
        }
@@ -174,6 +174,10 @@ xfs_qm_dqpurge(
 
        xfs_qm_dqdestroy(dqp);
        return 0;
+
+out_unlock:
+       xfs_dqunlock(dqp);
+       return error;
 }
 
 /*