aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHisashi Hifumi <hifumi.hisashi@oss.ntt.co.jp>2008-04-28 05:12:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-28 11:58:18 -0400
commit0dd1334faf7e075bfdb6f5284eed65210b296fc1 (patch)
treed64b7b1d4035d8b524b01d5cd3800135edcacc25
parentddc81ed2c5d47a078a3b02c5c3a4345bc2bc3c9b (diff)
fix invalidate_inode_pages2_range() to not clear ret
DIO invalidates page cache through invalidate_inode_pages2_range(). invalidate_inode_pages2_range() sets ret=-EIO when invalidate_complete_page2() fails, but this ret is cleared if do_launder_page() succeed on a page of next index. In this case, dio is carried out even if invalidate_complete_page2() fails on some pages. This can cause inconsistency between memory and blocks on HDD because the page cache still exists. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Hisashi Hifumi <hifumi.hisashi@oss.ntt.co.jp> Cc: Badari Pulavarty <pbadari@us.ibm.com> Cc: Ken Chen <kenchen@google.com> Cc: Zach Brown <zach.brown@oracle.com> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Cc: Trond Myklebust <trond.myklebust@fys.uio.no> Cc: "J. Bruce Fields" <bfields@fieldses.org> Cc: Chuck Lever <cel@citi.umich.edu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/truncate.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/mm/truncate.c b/mm/truncate.c
index 7d20ce41ecf5..b8961cb63414 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -391,6 +391,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
391 pgoff_t next; 391 pgoff_t next;
392 int i; 392 int i;
393 int ret = 0; 393 int ret = 0;
394 int ret2 = 0;
394 int did_range_unmap = 0; 395 int did_range_unmap = 0;
395 int wrapped = 0; 396 int wrapped = 0;
396 397
@@ -438,9 +439,13 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
438 } 439 }
439 } 440 }
440 BUG_ON(page_mapped(page)); 441 BUG_ON(page_mapped(page));
441 ret = do_launder_page(mapping, page); 442 ret2 = do_launder_page(mapping, page);
442 if (ret == 0 && !invalidate_complete_page2(mapping, page)) 443 if (ret2 == 0) {
443 ret = -EIO; 444 if (!invalidate_complete_page2(mapping, page))
445 ret2 = -EIO;
446 }
447 if (ret2 < 0)
448 ret = ret2;
444 unlock_page(page); 449 unlock_page(page);
445 } 450 }
446 pagevec_release(&pvec); 451 pagevec_release(&pvec);