Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f1172b08 authored by Brian Foster's avatar Brian Foster Committed by Greg Kroah-Hartman
Browse files

xfs: trylock underlying buffer on dquot flush



commit 8d3d7e2b35ea7d91d6e085c93b5efecfb0fba307 upstream.

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>
Acked-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandan.babu@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 890d7dff
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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;

@@ -1176,7 +1176,7 @@ xfs_qm_dqflush(

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

/*
+2 −1
Original line number Diff line number Diff line
@@ -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:
+9 −5
Original line number Diff line number Diff line
@@ -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;
}

/*