Commit 8d3d7e2b authored by Brian Foster's avatar Brian Foster Committed by Darrick J. Wong

xfs: trylock underlying buffer on dquot flush

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: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 63337b63
...@@ -1105,8 +1105,8 @@ xfs_qm_dqflush( ...@@ -1105,8 +1105,8 @@ xfs_qm_dqflush(
* Get the buffer containing the on-disk dquot * Get the buffer containing the on-disk dquot
*/ */
error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno, error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno,
mp->m_quotainfo->qi_dqchunklen, 0, &bp, mp->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK,
&xfs_dquot_buf_ops); &bp, &xfs_dquot_buf_ops);
if (error) if (error)
goto out_unlock; goto out_unlock;
...@@ -1177,7 +1177,7 @@ xfs_qm_dqflush( ...@@ -1177,7 +1177,7 @@ xfs_qm_dqflush(
out_unlock: out_unlock:
xfs_dqfunlock(dqp); xfs_dqfunlock(dqp);
return -EIO; return error;
} }
/* /*
......
...@@ -189,7 +189,8 @@ xfs_qm_dquot_logitem_push( ...@@ -189,7 +189,8 @@ xfs_qm_dquot_logitem_push(
if (!xfs_buf_delwri_queue(bp, buffer_list)) if (!xfs_buf_delwri_queue(bp, buffer_list))
rval = XFS_ITEM_FLUSHING; rval = XFS_ITEM_FLUSHING;
xfs_buf_relse(bp); xfs_buf_relse(bp);
} } else if (error == -EAGAIN)
rval = XFS_ITEM_LOCKED;
spin_lock(&lip->li_ailp->ail_lock); spin_lock(&lip->li_ailp->ail_lock);
out_unlock: out_unlock:
......
...@@ -121,12 +121,11 @@ xfs_qm_dqpurge( ...@@ -121,12 +121,11 @@ xfs_qm_dqpurge(
{ {
struct xfs_mount *mp = dqp->q_mount; struct xfs_mount *mp = dqp->q_mount;
struct xfs_quotainfo *qi = mp->m_quotainfo; struct xfs_quotainfo *qi = mp->m_quotainfo;
int error = -EAGAIN;
xfs_dqlock(dqp); xfs_dqlock(dqp);
if ((dqp->dq_flags & XFS_DQ_FREEING) || dqp->q_nrefs != 0) { if ((dqp->dq_flags & XFS_DQ_FREEING) || dqp->q_nrefs != 0)
xfs_dqunlock(dqp); goto out_unlock;
return -EAGAIN;
}
dqp->dq_flags |= XFS_DQ_FREEING; dqp->dq_flags |= XFS_DQ_FREEING;
...@@ -139,7 +138,6 @@ xfs_qm_dqpurge( ...@@ -139,7 +138,6 @@ xfs_qm_dqpurge(
*/ */
if (XFS_DQ_IS_DIRTY(dqp)) { if (XFS_DQ_IS_DIRTY(dqp)) {
struct xfs_buf *bp = NULL; struct xfs_buf *bp = NULL;
int error;
/* /*
* We don't care about getting disk errors here. We need * We don't care about getting disk errors here. We need
...@@ -149,6 +147,8 @@ xfs_qm_dqpurge( ...@@ -149,6 +147,8 @@ xfs_qm_dqpurge(
if (!error) { if (!error) {
error = xfs_bwrite(bp); error = xfs_bwrite(bp);
xfs_buf_relse(bp); xfs_buf_relse(bp);
} else if (error == -EAGAIN) {
goto out_unlock;
} }
xfs_dqflock(dqp); xfs_dqflock(dqp);
} }
...@@ -174,6 +174,10 @@ xfs_qm_dqpurge( ...@@ -174,6 +174,10 @@ xfs_qm_dqpurge(
xfs_qm_dqdestroy(dqp); xfs_qm_dqdestroy(dqp);
return 0; return 0;
out_unlock:
xfs_dqunlock(dqp);
return error;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment