aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2007-06-05 02:24:36 -0400
committerTim Shimmin <tes@chook.melbourne.sgi.com>2007-07-14 01:30:52 -0400
commite927af90aaa7d75543edbbd9c2810e6963d0443f (patch)
tree56da842111210cd39bd45365a42f52f3c50eaf14 /fs/xfs
parentf4a9f28a909debe97cd3f6ca30e82e5811125bff (diff)
[XFS] Block on unwritten extent conversion during synchronous direct I/O.
Currently we do not wait on extent conversion to occur, and hence we can return to userspace from a synchronous direct I/O write without having completed all the actions in the write. Hence a read after the write may see zeroes (unwritten extent) rather than the data that was written. Block the I/O completion by triggering a synchronous workqueue flush to ensure that the conversion has occurred before we return to userspace. SGI-PV: 964092 SGI-Modid: xfs-linux-melb:xfs-kern:28775a Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 7361861e3aac..80a321462315 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -108,14 +108,19 @@ xfs_page_trace(
108 108
109/* 109/*
110 * Schedule IO completion handling on a xfsdatad if this was 110 * Schedule IO completion handling on a xfsdatad if this was
111 * the final hold on this ioend. 111 * the final hold on this ioend. If we are asked to wait,
112 * flush the workqueue.
112 */ 113 */
113STATIC void 114STATIC void
114xfs_finish_ioend( 115xfs_finish_ioend(
115 xfs_ioend_t *ioend) 116 xfs_ioend_t *ioend,
117 int wait)
116{ 118{
117 if (atomic_dec_and_test(&ioend->io_remaining)) 119 if (atomic_dec_and_test(&ioend->io_remaining)) {
118 queue_work(xfsdatad_workqueue, &ioend->io_work); 120 queue_work(xfsdatad_workqueue, &ioend->io_work);
121 if (wait)
122 flush_workqueue(xfsdatad_workqueue);
123 }
119} 124}
120 125
121/* 126/*
@@ -334,7 +339,7 @@ xfs_end_bio(
334 bio->bi_end_io = NULL; 339 bio->bi_end_io = NULL;
335 bio_put(bio); 340 bio_put(bio);
336 341
337 xfs_finish_ioend(ioend); 342 xfs_finish_ioend(ioend, 0);
338 return 0; 343 return 0;
339} 344}
340 345
@@ -470,7 +475,7 @@ xfs_submit_ioend(
470 } 475 }
471 if (bio) 476 if (bio)
472 xfs_submit_ioend_bio(ioend, bio); 477 xfs_submit_ioend_bio(ioend, bio);
473 xfs_finish_ioend(ioend); 478 xfs_finish_ioend(ioend, 0);
474 } while ((ioend = next) != NULL); 479 } while ((ioend = next) != NULL);
475} 480}
476 481
@@ -1416,6 +1421,13 @@ xfs_end_io_direct(
1416 * This is not necessary for synchronous direct I/O, but we do 1421 * This is not necessary for synchronous direct I/O, but we do
1417 * it anyway to keep the code uniform and simpler. 1422 * it anyway to keep the code uniform and simpler.
1418 * 1423 *
1424 * Well, if only it were that simple. Because synchronous direct I/O
1425 * requires extent conversion to occur *before* we return to userspace,
1426 * we have to wait for extent conversion to complete. Look at the
1427 * iocb that has been passed to us to determine if this is AIO or
1428 * not. If it is synchronous, tell xfs_finish_ioend() to kick the
1429 * workqueue and wait for it to complete.
1430 *
1419 * The core direct I/O code might be changed to always call the 1431 * The core direct I/O code might be changed to always call the
1420 * completion handler in the future, in which case all this can 1432 * completion handler in the future, in which case all this can
1421 * go away. 1433 * go away.
@@ -1423,9 +1435,9 @@ xfs_end_io_direct(
1423 ioend->io_offset = offset; 1435 ioend->io_offset = offset;
1424 ioend->io_size = size; 1436 ioend->io_size = size;
1425 if (ioend->io_type == IOMAP_READ) { 1437 if (ioend->io_type == IOMAP_READ) {
1426 xfs_finish_ioend(ioend); 1438 xfs_finish_ioend(ioend, 0);
1427 } else if (private && size > 0) { 1439 } else if (private && size > 0) {
1428 xfs_finish_ioend(ioend); 1440 xfs_finish_ioend(ioend, is_sync_kiocb(iocb));
1429 } else { 1441 } else {
1430 /* 1442 /*
1431 * A direct I/O write ioend starts it's life in unwritten 1443 * A direct I/O write ioend starts it's life in unwritten
@@ -1434,7 +1446,7 @@ xfs_end_io_direct(
1434 * handler. 1446 * handler.
1435 */ 1447 */
1436 INIT_WORK(&ioend->io_work, xfs_end_bio_written); 1448 INIT_WORK(&ioend->io_work, xfs_end_bio_written);
1437 xfs_finish_ioend(ioend); 1449 xfs_finish_ioend(ioend, 0);
1438 } 1450 }
1439 1451
1440 /* 1452 /*