aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fs-writeback.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-03-05 03:21:21 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2010-03-05 13:25:10 -0500
commit26821ed40b4230259e770c9911180f38fcaa6f59 (patch)
tree40cd0fed705ec59dd3c909b96452bae1fc532796 /fs/fs-writeback.c
parent64ba9926759792cf7b95f823402e2781edd1b5d4 (diff)
make sure data is on disk before calling ->write_inode
Similar to the fsync issue fixed a while ago in commit 2daea67e966dc0c42067ebea015ddac6834cef88 we need to write for data to actually hit the disk before writing out the metadata to guarantee data integrity for filesystems that modify the inode in the data I/O completion path. Currently XFS and NFS handle this manually, and AFS has a write_inode method that does nothing but waiting for data, while others are possibly missing out on this. Fortunately this change has a lot less impact than the fsync change as none of the write_inode methods starts data writeout of any form by itself. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r--fs/fs-writeback.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 1a7c42c64ff4..5f2721b1e4be 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -461,15 +461,20 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
461 461
462 ret = do_writepages(mapping, wbc); 462 ret = do_writepages(mapping, wbc);
463 463
464 /* Don't write the inode if only I_DIRTY_PAGES was set */ 464 /*
465 if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) { 465 * Make sure to wait on the data before writing out the metadata.
466 int err = write_inode(inode, wait); 466 * This is important for filesystems that modify metadata on data
467 * I/O completion.
468 */
469 if (wait) {
470 int err = filemap_fdatawait(mapping);
467 if (ret == 0) 471 if (ret == 0)
468 ret = err; 472 ret = err;
469 } 473 }
470 474
471 if (wait) { 475 /* Don't write the inode if only I_DIRTY_PAGES was set */
472 int err = filemap_fdatawait(mapping); 476 if (dirty & (I_DIRTY_SYNC | I_DIRTY_DATASYNC)) {
477 int err = write_inode(inode, wait);
473 if (ret == 0) 478 if (ret == 0)
474 ret = err; 479 ret = err;
475 } 480 }