/* * 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); }
/* * 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; }