aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_buf.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-08-23 04:28:05 -0400
committerAlex Elder <aelder@sgi.com>2011-10-11 22:14:59 -0400
commit5a8ee6bafdd0ab8555adceac8b2cec539a552a1f (patch)
tree58ee49a1a736bac15082444e3cd85f0ba568d63d /fs/xfs/xfs_buf.c
parent527cfdf19dd538a5a9e46b9bed0f30a38c28438d (diff)
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.c31
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
937xfs_buf_unlock( 937xfs_buf_unlock(
938 struct xfs_buf *bp) 938 struct xfs_buf *bp)
939{ 939{
940 if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) { 940 if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI)
941 atomic_inc(&bp->b_hold);
942 bp->b_flags |= XBF_ASYNC;
943 xfs_buf_delwri_queue(bp); 941 xfs_buf_delwri_queue(bp);
944 }
945 942
946 XB_CLEAR_OWNER(bp); 943 XB_CLEAR_OWNER(bp);
947 up(&bp->b_sema); 944 up(&bp->b_sema);
@@ -1046,11 +1043,8 @@ xfs_bdwrite(
1046{ 1043{
1047 trace_xfs_buf_bdwrite(bp, _RET_IP_); 1044 trace_xfs_buf_bdwrite(bp, _RET_IP_);
1048 1045
1049 bp->b_flags &= ~XBF_READ;
1050 bp->b_flags |= (XBF_DELWRI | XBF_ASYNC);
1051
1052 xfs_buf_delwri_queue(bp); 1046 xfs_buf_delwri_queue(bp);
1053 xfs_buf_unlock(bp); 1047 xfs_buf_relse(bp);
1054} 1048}
1055 1049
1056/* 1050/*
@@ -1570,23 +1564,22 @@ xfs_buf_delwri_queue(
1570 1564
1571 trace_xfs_buf_delwri_queue(bp, _RET_IP_); 1565 trace_xfs_buf_delwri_queue(bp, _RET_IP_);
1572 1566
1573 ASSERT((bp->b_flags&(XBF_DELWRI|XBF_ASYNC)) == (XBF_DELWRI|XBF_ASYNC)); 1567 ASSERT(!(bp->b_flags & XBF_READ));
1574 1568
1575 spin_lock(dwlk); 1569 spin_lock(dwlk);
1576 /* If already in the queue, dequeue and place at tail */
1577 if (!list_empty(&bp->b_list)) { 1570 if (!list_empty(&bp->b_list)) {
1571 /* if already in the queue, move it to the tail */
1578 ASSERT(bp->b_flags & _XBF_DELWRI_Q); 1572 ASSERT(bp->b_flags & _XBF_DELWRI_Q);
1579 atomic_dec(&bp->b_hold); 1573 list_move_tail(&bp->b_list, dwq);
1580 list_del(&bp->b_list); 1574 } else {
1581 }
1582
1583 if (list_empty(dwq)) {
1584 /* start xfsbufd as it is about to have something to do */ 1575 /* start xfsbufd as it is about to have something to do */
1585 wake_up_process(bp->b_target->bt_task); 1576 if (list_empty(dwq))
1586 } 1577 wake_up_process(bp->b_target->bt_task);
1587 1578
1588 bp->b_flags |= _XBF_DELWRI_Q; 1579 atomic_inc(&bp->b_hold);
1589 list_add_tail(&bp->b_list, dwq); 1580 bp->b_flags |= XBF_DELWRI | _XBF_DELWRI_Q | XBF_ASYNC;
1581 list_add_tail(&bp->b_list, dwq);
1582 }
1590 bp->b_queuetime = jiffies; 1583 bp->b_queuetime = jiffies;
1591 spin_unlock(dwlk); 1584 spin_unlock(dwlk);
1592} 1585}