Esempio n. 1
0
/*
 * This is called to attempt to lock the dquot associated with this
 * dquot log item.  Don't sleep on the dquot lock or the flush lock.
 * If the flush lock is already held, indicating that the dquot has
 * been or is in the process of being flushed, then see if we can
 * find the dquot's buffer in the buffer cache without sleeping.  If
 * we can and it is marked delayed write, then we want to send it out.
 * We delay doing so until the push routine, though, to avoid sleeping
 * in any device strategy routines.
 */
STATIC uint
xfs_qm_dquot_logitem_trylock(
	xfs_dq_logitem_t	*qip)
{
	xfs_dquot_t		*dqp;
	uint			retval;

	dqp = qip->qli_dquot;
	if (dqp->q_pincount > 0)
		return (XFS_ITEM_PINNED);

	if (! xfs_qm_dqlock_nowait(dqp))
		return (XFS_ITEM_LOCKED);

	retval = XFS_ITEM_SUCCESS;
	if (! xfs_qm_dqflock_nowait(dqp)) {
		/*
		 * The dquot is already being flushed.	It may have been
		 * flushed delayed write, however, and we don't want to
		 * get stuck waiting for that to complete.  So, we want to check
		 * to see if we can lock the dquot's buffer without sleeping.
		 * If we can and it is marked for delayed write, then we
		 * hold it and send it out from the push routine.  We don't
		 * want to do that now since we might sleep in the device
		 * strategy routine.  We also don't want to grab the buffer lock
		 * here because we'd like not to call into the buffer cache
		 * while holding the AIL lock.
		 * Make sure to only return PUSHBUF if we set pushbuf_flag
		 * ourselves.  If someone else is doing it then we don't
		 * want to go to the push routine and duplicate their efforts.
		 */
		if (qip->qli_pushbuf_flag == 0) {
			qip->qli_pushbuf_flag = 1;
			ASSERT(qip->qli_format.qlf_blkno == dqp->q_blkno);
#ifdef DEBUG
			qip->qli_push_owner = current_pid();
#endif
			/*
			 * The dquot is left locked.
			 */
			retval = XFS_ITEM_PUSHBUF;
		} else {
			retval = XFS_ITEM_FLUSHING;
			xfs_dqunlock_nonotify(dqp);
		}
	}

	ASSERT(qip->qli_item.li_flags & XFS_LI_IN_AIL);
	return (retval);
}
Esempio n. 2
0
/*
 * This is called to attempt to lock the dquot associated with this
 * dquot log item.  Don't sleep on the dquot lock or the flush lock.
 * If the flush lock is already held, indicating that the dquot has
 * been or is in the process of being flushed, then see if we can
 * find the dquot's buffer in the buffer cache without sleeping.  If
 * we can and it is marked delayed write, then we want to send it out.
 * We delay doing so until the push routine, though, to avoid sleeping
 * in any device strategy routines.
 */
STATIC uint
xfs_qm_dquot_logitem_trylock(
	struct xfs_log_item	*lip)
{
	struct xfs_dquot	*dqp = DQUOT_ITEM(lip)->qli_dquot;

	if (atomic_read(&dqp->q_pincount) > 0)
		return XFS_ITEM_PINNED;

	if (!xfs_qm_dqlock_nowait(dqp))
		return XFS_ITEM_LOCKED;

	if (!xfs_dqflock_nowait(dqp)) {
		/*
		 * dquot has already been flushed to the backing buffer,
		 * leave it locked, pushbuf routine will unlock it.
		 */
		return XFS_ITEM_PUSHBUF;
	}

	ASSERT(lip->li_flags & XFS_LI_IN_AIL);
	return XFS_ITEM_SUCCESS;
}