diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-08-23 08:28:05 +0000 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2011-10-11 21:14:59 -0500 |
commit | 5a8ee6bafdd0ab8555adceac8b2cec539a552a1f (patch) | |
tree | 58ee49a1a736bac15082444e3cd85f0ba568d63d /fs/xfs/xfs_buf.c | |
parent | 527cfdf19dd538a5a9e46b9bed0f30a38c28438d (diff) | |
download | linux-5a8ee6bafdd0ab8555adceac8b2cec539a552a1f.tar.bz2 |
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>
Diffstat (limited to 'fs/xfs/xfs_buf.c')
-rw-r--r-- | fs/xfs/xfs_buf.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 04689dbbcbba..86c0945053c9 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -937,11 +937,8 @@ void xfs_buf_unlock( struct xfs_buf *bp) { - if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) { - atomic_inc(&bp->b_hold); - bp->b_flags |= XBF_ASYNC; + if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) xfs_buf_delwri_queue(bp); - } XB_CLEAR_OWNER(bp); up(&bp->b_sema); @@ -1046,11 +1043,8 @@ xfs_bdwrite( { 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_unlock(bp); + xfs_buf_relse(bp); } /* @@ -1570,23 +1564,22 @@ xfs_buf_delwri_queue( 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); - /* If already in the queue, dequeue and place at tail */ if (!list_empty(&bp->b_list)) { + /* if already in the queue, move it to the tail */ ASSERT(bp->b_flags & _XBF_DELWRI_Q); - atomic_dec(&bp->b_hold); - list_del(&bp->b_list); - } - - if (list_empty(dwq)) { + list_move_tail(&bp->b_list, dwq); + } else { /* 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; - list_add_tail(&bp->b_list, dwq); + atomic_inc(&bp->b_hold); + bp->b_flags |= XBF_DELWRI | _XBF_DELWRI_Q | XBF_ASYNC; + list_add_tail(&bp->b_list, dwq); + } bp->b_queuetime = jiffies; spin_unlock(dwlk); } |