diff options
-rw-r--r-- | fs/xfs/xfs_buf.c | 38 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.h | 5 |
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 | |||
97 | xfs_buf_ioacct_inc( | 97 | xfs_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 | */ |
112 | static inline void | 116 | static inline void |
113 | xfs_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 | |||
128 | static inline void | ||
129 | xfs_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 | ||
68 | typedef unsigned int xfs_buf_flags_t; | 67 | typedef 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" - |