diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-08-23 04:28:05 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2011-10-11 22:14:59 -0400 |
commit | 5a8ee6bafdd0ab8555adceac8b2cec539a552a1f (patch) | |
tree | 58ee49a1a736bac15082444e3cd85f0ba568d63d /fs/xfs/xfs_buf.c | |
parent | 527cfdf19dd538a5a9e46b9bed0f30a38c28438d (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.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 | |||
937 | xfs_buf_unlock( | 937 | xfs_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 | } |