xfs: move more delwri setup into xfs_buf_delwri_queue
authorChristoph Hellwig <hch@infradead.org>
Tue, 23 Aug 2011 08:28:05 +0000 (08:28 +0000)
committerAlex Elder <aelder@sgi.com>
Wed, 12 Oct 2011 02:14:59 +0000 (21:14 -0500)
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>
fs/xfs/xfs_buf.c

index 04689db..86c0945 100644 (file)
@@ -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);
 }