aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_aops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_aops.c')
-rw-r--r--fs/xfs/xfs_aops.c119
1 files changed, 42 insertions, 77 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 8c37dde4c521..11b2aad982d4 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -38,40 +38,6 @@
38#include <linux/pagevec.h> 38#include <linux/pagevec.h>
39#include <linux/writeback.h> 39#include <linux/writeback.h>
40 40
41
42/*
43 * Prime number of hash buckets since address is used as the key.
44 */
45#define NVSYNC 37
46#define to_ioend_wq(v) (&xfs_ioend_wq[((unsigned long)v) % NVSYNC])
47static wait_queue_head_t xfs_ioend_wq[NVSYNC];
48
49void __init
50xfs_ioend_init(void)
51{
52 int i;
53
54 for (i = 0; i < NVSYNC; i++)
55 init_waitqueue_head(&xfs_ioend_wq[i]);
56}
57
58void
59xfs_ioend_wait(
60 xfs_inode_t *ip)
61{
62 wait_queue_head_t *wq = to_ioend_wq(ip);
63
64 wait_event(*wq, (atomic_read(&ip->i_iocount) == 0));
65}
66
67STATIC void
68xfs_ioend_wake(
69 xfs_inode_t *ip)
70{
71 if (atomic_dec_and_test(&ip->i_iocount))
72 wake_up(to_ioend_wq(ip));
73}
74
75void 41void
76xfs_count_page_state( 42xfs_count_page_state(
77 struct page *page, 43 struct page *page,
@@ -115,25 +81,20 @@ xfs_destroy_ioend(
115 xfs_ioend_t *ioend) 81 xfs_ioend_t *ioend)
116{ 82{
117 struct buffer_head *bh, *next; 83 struct buffer_head *bh, *next;
118 struct xfs_inode *ip = XFS_I(ioend->io_inode);
119 84
120 for (bh = ioend->io_buffer_head; bh; bh = next) { 85 for (bh = ioend->io_buffer_head; bh; bh = next) {
121 next = bh->b_private; 86 next = bh->b_private;
122 bh->b_end_io(bh, !ioend->io_error); 87 bh->b_end_io(bh, !ioend->io_error);
123 } 88 }
124 89
125 /* 90 if (ioend->io_iocb) {
126 * Volume managers supporting multiple paths can send back ENODEV 91 if (ioend->io_isasync) {
127 * when the final path disappears. In this case continuing to fill 92 aio_complete(ioend->io_iocb, ioend->io_error ?
128 * the page cache with dirty data which cannot be written out is 93 ioend->io_error : ioend->io_result, 0);
129 * evil, so prevent that. 94 }
130 */ 95 inode_dio_done(ioend->io_inode);
131 if (unlikely(ioend->io_error == -ENODEV)) {
132 xfs_do_force_shutdown(ip->i_mount, SHUTDOWN_DEVICE_REQ,
133 __FILE__, __LINE__);
134 } 96 }
135 97
136 xfs_ioend_wake(ip);
137 mempool_free(ioend, xfs_ioend_pool); 98 mempool_free(ioend, xfs_ioend_pool);
138} 99}
139 100
@@ -156,6 +117,15 @@ xfs_ioend_new_eof(
156} 117}
157 118
158/* 119/*
120 * Fast and loose check if this write could update the on-disk inode size.
121 */
122static inline bool xfs_ioend_is_append(struct xfs_ioend *ioend)
123{
124 return ioend->io_offset + ioend->io_size >
125 XFS_I(ioend->io_inode)->i_d.di_size;
126}
127
128/*
159 * Update on-disk file size now that data has been written to disk. The 129 * Update on-disk file size now that data has been written to disk. The
160 * current in-memory file size is i_size. If a write is beyond eof i_new_size 130 * current in-memory file size is i_size. If a write is beyond eof i_new_size
161 * will be the intended file size until i_size is updated. If this write does 131 * will be the intended file size until i_size is updated. If this write does
@@ -173,9 +143,6 @@ xfs_setfilesize(
173 xfs_inode_t *ip = XFS_I(ioend->io_inode); 143 xfs_inode_t *ip = XFS_I(ioend->io_inode);
174 xfs_fsize_t isize; 144 xfs_fsize_t isize;
175 145
176 if (unlikely(ioend->io_error))
177 return 0;
178
179 if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) 146 if (!xfs_ilock_nowait(ip, XFS_ILOCK_EXCL))
180 return EAGAIN; 147 return EAGAIN;
181 148
@@ -192,6 +159,9 @@ xfs_setfilesize(
192 159
193/* 160/*
194 * Schedule IO completion handling on the final put of an ioend. 161 * Schedule IO completion handling on the final put of an ioend.
162 *
163 * If there is no work to do we might as well call it a day and free the
164 * ioend right now.
195 */ 165 */
196STATIC void 166STATIC void
197xfs_finish_ioend( 167xfs_finish_ioend(
@@ -200,8 +170,10 @@ xfs_finish_ioend(
200 if (atomic_dec_and_test(&ioend->io_remaining)) { 170 if (atomic_dec_and_test(&ioend->io_remaining)) {
201 if (ioend->io_type == IO_UNWRITTEN) 171 if (ioend->io_type == IO_UNWRITTEN)
202 queue_work(xfsconvertd_workqueue, &ioend->io_work); 172 queue_work(xfsconvertd_workqueue, &ioend->io_work);
203 else 173 else if (xfs_ioend_is_append(ioend))
204 queue_work(xfsdatad_workqueue, &ioend->io_work); 174 queue_work(xfsdatad_workqueue, &ioend->io_work);
175 else
176 xfs_destroy_ioend(ioend);
205 } 177 }
206} 178}
207 179
@@ -216,17 +188,24 @@ xfs_end_io(
216 struct xfs_inode *ip = XFS_I(ioend->io_inode); 188 struct xfs_inode *ip = XFS_I(ioend->io_inode);
217 int error = 0; 189 int error = 0;
218 190
191 if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
192 error = -EIO;
193 goto done;
194 }
195 if (ioend->io_error)
196 goto done;
197
219 /* 198 /*
220 * For unwritten extents we need to issue transactions to convert a 199 * For unwritten extents we need to issue transactions to convert a
221 * range to normal written extens after the data I/O has finished. 200 * range to normal written extens after the data I/O has finished.
222 */ 201 */
223 if (ioend->io_type == IO_UNWRITTEN && 202 if (ioend->io_type == IO_UNWRITTEN) {
224 likely(!ioend->io_error && !XFS_FORCED_SHUTDOWN(ip->i_mount))) {
225
226 error = xfs_iomap_write_unwritten(ip, ioend->io_offset, 203 error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
227 ioend->io_size); 204 ioend->io_size);
228 if (error) 205 if (error) {
229 ioend->io_error = error; 206 ioend->io_error = -error;
207 goto done;
208 }
230 } 209 }
231 210
232 /* 211 /*
@@ -236,6 +215,7 @@ xfs_end_io(
236 error = xfs_setfilesize(ioend); 215 error = xfs_setfilesize(ioend);
237 ASSERT(!error || error == EAGAIN); 216 ASSERT(!error || error == EAGAIN);
238 217
218done:
239 /* 219 /*
240 * If we didn't complete processing of the ioend, requeue it to the 220 * If we didn't complete processing of the ioend, requeue it to the
241 * tail of the workqueue for another attempt later. Otherwise destroy 221 * tail of the workqueue for another attempt later. Otherwise destroy
@@ -247,8 +227,6 @@ xfs_end_io(
247 /* ensure we don't spin on blocked ioends */ 227 /* ensure we don't spin on blocked ioends */
248 delay(1); 228 delay(1);
249 } else { 229 } else {
250 if (ioend->io_iocb)
251 aio_complete(ioend->io_iocb, ioend->io_result, 0);
252 xfs_destroy_ioend(ioend); 230 xfs_destroy_ioend(ioend);
253 } 231 }
254} 232}
@@ -285,13 +263,13 @@ xfs_alloc_ioend(
285 * all the I/O from calling the completion routine too early. 263 * all the I/O from calling the completion routine too early.
286 */ 264 */
287 atomic_set(&ioend->io_remaining, 1); 265 atomic_set(&ioend->io_remaining, 1);
266 ioend->io_isasync = 0;
288 ioend->io_error = 0; 267 ioend->io_error = 0;
289 ioend->io_list = NULL; 268 ioend->io_list = NULL;
290 ioend->io_type = type; 269 ioend->io_type = type;
291 ioend->io_inode = inode; 270 ioend->io_inode = inode;
292 ioend->io_buffer_head = NULL; 271 ioend->io_buffer_head = NULL;
293 ioend->io_buffer_tail = NULL; 272 ioend->io_buffer_tail = NULL;
294 atomic_inc(&XFS_I(ioend->io_inode)->i_iocount);
295 ioend->io_offset = 0; 273 ioend->io_offset = 0;
296 ioend->io_size = 0; 274 ioend->io_size = 0;
297 ioend->io_iocb = NULL; 275 ioend->io_iocb = NULL;
@@ -337,8 +315,8 @@ xfs_map_blocks(
337 count = mp->m_maxioffset - offset; 315 count = mp->m_maxioffset - offset;
338 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); 316 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
339 offset_fsb = XFS_B_TO_FSBT(mp, offset); 317 offset_fsb = XFS_B_TO_FSBT(mp, offset);
340 error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb, 318 error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
341 bmapi_flags, NULL, 0, imap, &nimaps, NULL); 319 imap, &nimaps, bmapi_flags);
342 xfs_iunlock(ip, XFS_ILOCK_SHARED); 320 xfs_iunlock(ip, XFS_ILOCK_SHARED);
343 321
344 if (error) 322 if (error)
@@ -551,7 +529,6 @@ xfs_cancel_ioend(
551 unlock_buffer(bh); 529 unlock_buffer(bh);
552 } while ((bh = next_bh) != NULL); 530 } while ((bh = next_bh) != NULL);
553 531
554 xfs_ioend_wake(XFS_I(ioend->io_inode));
555 mempool_free(ioend, xfs_ioend_pool); 532 mempool_free(ioend, xfs_ioend_pool);
556 } while ((ioend = next) != NULL); 533 } while ((ioend = next) != NULL);
557} 534}
@@ -1161,8 +1138,8 @@ __xfs_get_blocks(
1161 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size); 1138 end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size);
1162 offset_fsb = XFS_B_TO_FSBT(mp, offset); 1139 offset_fsb = XFS_B_TO_FSBT(mp, offset);
1163 1140
1164 error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb, 1141 error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
1165 XFS_BMAPI_ENTIRE, NULL, 0, &imap, &nimaps, NULL); 1142 &imap, &nimaps, XFS_BMAPI_ENTIRE);
1166 if (error) 1143 if (error)
1167 goto out_unlock; 1144 goto out_unlock;
1168 1145
@@ -1300,7 +1277,6 @@ xfs_end_io_direct_write(
1300 bool is_async) 1277 bool is_async)
1301{ 1278{
1302 struct xfs_ioend *ioend = iocb->private; 1279 struct xfs_ioend *ioend = iocb->private;
1303 struct inode *inode = ioend->io_inode;
1304 1280
1305 /* 1281 /*
1306 * blockdev_direct_IO can return an error even after the I/O 1282 * blockdev_direct_IO can return an error even after the I/O
@@ -1311,28 +1287,17 @@ xfs_end_io_direct_write(
1311 1287
1312 ioend->io_offset = offset; 1288 ioend->io_offset = offset;
1313 ioend->io_size = size; 1289 ioend->io_size = size;
1290 ioend->io_iocb = iocb;
1291 ioend->io_result = ret;
1314 if (private && size > 0) 1292 if (private && size > 0)
1315 ioend->io_type = IO_UNWRITTEN; 1293 ioend->io_type = IO_UNWRITTEN;
1316 1294
1317 if (is_async) { 1295 if (is_async) {
1318 /* 1296 ioend->io_isasync = 1;
1319 * If we are converting an unwritten extent we need to delay
1320 * the AIO completion until after the unwrittent extent
1321 * conversion has completed, otherwise do it ASAP.
1322 */
1323 if (ioend->io_type == IO_UNWRITTEN) {
1324 ioend->io_iocb = iocb;
1325 ioend->io_result = ret;
1326 } else {
1327 aio_complete(iocb, ret, 0);
1328 }
1329 xfs_finish_ioend(ioend); 1297 xfs_finish_ioend(ioend);
1330 } else { 1298 } else {
1331 xfs_finish_ioend_sync(ioend); 1299 xfs_finish_ioend_sync(ioend);
1332 } 1300 }
1333
1334 /* XXX: probably should move into the real I/O completion handler */
1335 inode_dio_done(inode);
1336} 1301}
1337 1302
1338STATIC ssize_t 1303STATIC ssize_t