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: 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>
This commit is contained in:
Родитель
63337b63e7
Коммит
8d3d7e2b35
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче