Skip to content

Commit

Permalink
xfs: trylock underlying buffer on dquot flush
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Brian Foster authored and Darrick J. Wong committed Mar 28, 2020
1 parent 63337b6 commit 8d3d7e2
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 9 deletions.
6 changes: 3 additions & 3 deletions fs/xfs/xfs_dquot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -1177,7 +1177,7 @@ xfs_qm_dqflush(

out_unlock:
xfs_dqfunlock(dqp);
return -EIO;
return error;
}

/*
Expand Down
3 changes: 2 additions & 1 deletion fs/xfs/xfs_dquot_item.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
14 changes: 9 additions & 5 deletions fs/xfs/xfs_qm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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
Expand All @@ -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);
}
Expand All @@ -174,6 +174,10 @@ xfs_qm_dqpurge(

xfs_qm_dqdestroy(dqp);
return 0;

out_unlock:
xfs_dqunlock(dqp);
return error;
}

/*
Expand Down

0 comments on commit 8d3d7e2

Please sign in to comment.