aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_buf.c38
-rw-r--r--fs/xfs/xfs_buf.h5
2 files changed, 28 insertions, 15 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 62fa39276a24..07b77b73b024 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -97,12 +97,16 @@ static inline void
97xfs_buf_ioacct_inc( 97xfs_buf_ioacct_inc(
98 struct xfs_buf *bp) 98 struct xfs_buf *bp)
99{ 99{
100 if (bp->b_flags & (XBF_NO_IOACCT|_XBF_IN_FLIGHT)) 100 if (bp->b_flags & XBF_NO_IOACCT)
101 return; 101 return;
102 102
103 ASSERT(bp->b_flags & XBF_ASYNC); 103 ASSERT(bp->b_flags & XBF_ASYNC);
104 bp->b_flags |= _XBF_IN_FLIGHT; 104 spin_lock(&bp->b_lock);
105 percpu_counter_inc(&bp->b_target->bt_io_count); 105 if (!(bp->b_state & XFS_BSTATE_IN_FLIGHT)) {
106 bp->b_state |= XFS_BSTATE_IN_FLIGHT;
107 percpu_counter_inc(&bp->b_target->bt_io_count);
108 }
109 spin_unlock(&bp->b_lock);
106} 110}
107 111
108/* 112/*
@@ -110,14 +114,24 @@ xfs_buf_ioacct_inc(
110 * freed and unaccount from the buftarg. 114 * freed and unaccount from the buftarg.
111 */ 115 */
112static inline void 116static inline void
113xfs_buf_ioacct_dec( 117__xfs_buf_ioacct_dec(
114 struct xfs_buf *bp) 118 struct xfs_buf *bp)
115{ 119{
116 if (!(bp->b_flags & _XBF_IN_FLIGHT)) 120 ASSERT(spin_is_locked(&bp->b_lock));
117 return;
118 121
119 bp->b_flags &= ~_XBF_IN_FLIGHT; 122 if (bp->b_state & XFS_BSTATE_IN_FLIGHT) {
120 percpu_counter_dec(&bp->b_target->bt_io_count); 123 bp->b_state &= ~XFS_BSTATE_IN_FLIGHT;
124 percpu_counter_dec(&bp->b_target->bt_io_count);
125 }
126}
127
128static inline void
129xfs_buf_ioacct_dec(
130 struct xfs_buf *bp)
131{
132 spin_lock(&bp->b_lock);
133 __xfs_buf_ioacct_dec(bp);
134 spin_unlock(&bp->b_lock);
121} 135}
122 136
123/* 137/*
@@ -149,9 +163,9 @@ xfs_buf_stale(
149 * unaccounted (released to LRU) before that occurs. Drop in-flight 163 * unaccounted (released to LRU) before that occurs. Drop in-flight
150 * status now to preserve accounting consistency. 164 * status now to preserve accounting consistency.
151 */ 165 */
152 xfs_buf_ioacct_dec(bp);
153
154 spin_lock(&bp->b_lock); 166 spin_lock(&bp->b_lock);
167 __xfs_buf_ioacct_dec(bp);
168
155 atomic_set(&bp->b_lru_ref, 0); 169 atomic_set(&bp->b_lru_ref, 0);
156 if (!(bp->b_state & XFS_BSTATE_DISPOSE) && 170 if (!(bp->b_state & XFS_BSTATE_DISPOSE) &&
157 (list_lru_del(&bp->b_target->bt_lru, &bp->b_lru))) 171 (list_lru_del(&bp->b_target->bt_lru, &bp->b_lru)))
@@ -979,12 +993,12 @@ xfs_buf_rele(
979 * ensures the decrement occurs only once per-buf. 993 * ensures the decrement occurs only once per-buf.
980 */ 994 */
981 if ((atomic_read(&bp->b_hold) == 1) && !list_empty(&bp->b_lru)) 995 if ((atomic_read(&bp->b_hold) == 1) && !list_empty(&bp->b_lru))
982 xfs_buf_ioacct_dec(bp); 996 __xfs_buf_ioacct_dec(bp);
983 goto out_unlock; 997 goto out_unlock;
984 } 998 }
985 999
986 /* the last reference has been dropped ... */ 1000 /* the last reference has been dropped ... */
987 xfs_buf_ioacct_dec(bp); 1001 __xfs_buf_ioacct_dec(bp);
988 if (!(bp->b_flags & XBF_STALE) && atomic_read(&bp->b_lru_ref)) { 1002 if (!(bp->b_flags & XBF_STALE) && atomic_read(&bp->b_lru_ref)) {
989 /* 1003 /*
990 * If the buffer is added to the LRU take a new reference to the 1004 * If the buffer is added to the LRU take a new reference to the
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 8d1d44f87ce9..1508121f29f2 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -63,7 +63,6 @@ typedef enum {
63#define _XBF_KMEM (1 << 21)/* backed by heap memory */ 63#define _XBF_KMEM (1 << 21)/* backed by heap memory */
64#define _XBF_DELWRI_Q (1 << 22)/* buffer on a delwri queue */ 64#define _XBF_DELWRI_Q (1 << 22)/* buffer on a delwri queue */
65#define _XBF_COMPOUND (1 << 23)/* compound buffer */ 65#define _XBF_COMPOUND (1 << 23)/* compound buffer */
66#define _XBF_IN_FLIGHT (1 << 25) /* I/O in flight, for accounting purposes */
67 66
68typedef unsigned int xfs_buf_flags_t; 67typedef unsigned int xfs_buf_flags_t;
69 68
@@ -84,14 +83,14 @@ typedef unsigned int xfs_buf_flags_t;
84 { _XBF_PAGES, "PAGES" }, \ 83 { _XBF_PAGES, "PAGES" }, \
85 { _XBF_KMEM, "KMEM" }, \ 84 { _XBF_KMEM, "KMEM" }, \
86 { _XBF_DELWRI_Q, "DELWRI_Q" }, \ 85 { _XBF_DELWRI_Q, "DELWRI_Q" }, \
87 { _XBF_COMPOUND, "COMPOUND" }, \ 86 { _XBF_COMPOUND, "COMPOUND" }
88 { _XBF_IN_FLIGHT, "IN_FLIGHT" }
89 87
90 88
91/* 89/*
92 * Internal state flags. 90 * Internal state flags.
93 */ 91 */
94#define XFS_BSTATE_DISPOSE (1 << 0) /* buffer being discarded */ 92#define XFS_BSTATE_DISPOSE (1 << 0) /* buffer being discarded */
93#define XFS_BSTATE_IN_FLIGHT (1 << 1) /* I/O in flight */
95 94
96/* 95/*
97 * The xfs_buftarg contains 2 notions of "sector size" - 96 * The xfs_buftarg contains 2 notions of "sector size" -