xfs: move more delwri setup into xfs_buf_delwri_queue
Do not transfer a reference held by the caller to the buffer on the list, or decrement it in xfs_buf_delwri_queue, but instead grab a new reference if needed, and let the caller drop its own reference. Also move setting of the XBF_DELWRI and XBF_ASYNC flags into xfs_buf_delwri_queue, and only do it if needed. Note that for now xfs_buf_unlock already has XBF_DELWRI, but that will change in the following patches. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Alex Elder <aelder@sgi.com>
This commit is contained in:
parent
527cfdf19d
commit
5a8ee6bafd
|
@ -937,11 +937,8 @@ void
|
||||||
xfs_buf_unlock(
|
xfs_buf_unlock(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) {
|
if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI)
|
||||||
atomic_inc(&bp->b_hold);
|
|
||||||
bp->b_flags |= XBF_ASYNC;
|
|
||||||
xfs_buf_delwri_queue(bp);
|
xfs_buf_delwri_queue(bp);
|
||||||
}
|
|
||||||
|
|
||||||
XB_CLEAR_OWNER(bp);
|
XB_CLEAR_OWNER(bp);
|
||||||
up(&bp->b_sema);
|
up(&bp->b_sema);
|
||||||
|
@ -1046,11 +1043,8 @@ xfs_bdwrite(
|
||||||
{
|
{
|
||||||
trace_xfs_buf_bdwrite(bp, _RET_IP_);
|
trace_xfs_buf_bdwrite(bp, _RET_IP_);
|
||||||
|
|
||||||
bp->b_flags &= ~XBF_READ;
|
|
||||||
bp->b_flags |= (XBF_DELWRI | XBF_ASYNC);
|
|
||||||
|
|
||||||
xfs_buf_delwri_queue(bp);
|
xfs_buf_delwri_queue(bp);
|
||||||
xfs_buf_unlock(bp);
|
xfs_buf_relse(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1570,23 +1564,22 @@ xfs_buf_delwri_queue(
|
||||||
|
|
||||||
trace_xfs_buf_delwri_queue(bp, _RET_IP_);
|
trace_xfs_buf_delwri_queue(bp, _RET_IP_);
|
||||||
|
|
||||||
ASSERT((bp->b_flags&(XBF_DELWRI|XBF_ASYNC)) == (XBF_DELWRI|XBF_ASYNC));
|
ASSERT(!(bp->b_flags & XBF_READ));
|
||||||
|
|
||||||
spin_lock(dwlk);
|
spin_lock(dwlk);
|
||||||
/* If already in the queue, dequeue and place at tail */
|
|
||||||
if (!list_empty(&bp->b_list)) {
|
if (!list_empty(&bp->b_list)) {
|
||||||
|
/* if already in the queue, move it to the tail */
|
||||||
ASSERT(bp->b_flags & _XBF_DELWRI_Q);
|
ASSERT(bp->b_flags & _XBF_DELWRI_Q);
|
||||||
atomic_dec(&bp->b_hold);
|
list_move_tail(&bp->b_list, dwq);
|
||||||
list_del(&bp->b_list);
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
if (list_empty(dwq)) {
|
|
||||||
/* start xfsbufd as it is about to have something to do */
|
/* start xfsbufd as it is about to have something to do */
|
||||||
wake_up_process(bp->b_target->bt_task);
|
if (list_empty(dwq))
|
||||||
}
|
wake_up_process(bp->b_target->bt_task);
|
||||||
|
|
||||||
bp->b_flags |= _XBF_DELWRI_Q;
|
atomic_inc(&bp->b_hold);
|
||||||
list_add_tail(&bp->b_list, dwq);
|
bp->b_flags |= XBF_DELWRI | _XBF_DELWRI_Q | XBF_ASYNC;
|
||||||
|
list_add_tail(&bp->b_list, dwq);
|
||||||
|
}
|
||||||
bp->b_queuetime = jiffies;
|
bp->b_queuetime = jiffies;
|
||||||
spin_unlock(dwlk);
|
spin_unlock(dwlk);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue