From 0dd1334faf7e075bfdb6f5284eed65210b296fc1 Mon Sep 17 00:00:00 2001 From: Hisashi Hifumi Date: Mon, 28 Apr 2008 02:12:08 -0700 Subject: 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 Cc: Badari Pulavarty Cc: Ken Chen Cc: Zach Brown Cc: Nick Piggin Cc: Trond Myklebust Cc: "J. Bruce Fields" Cc: Chuck Lever Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/truncate.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'mm/truncate.c') diff --git a/mm/truncate.c b/mm/truncate.c index 7d20ce41ecf..b8961cb6341 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -391,6 +391,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping, pgoff_t next; int i; int ret = 0; + int ret2 = 0; int did_range_unmap = 0; int wrapped = 0; @@ -438,9 +439,13 @@ int invalidate_inode_pages2_range(struct address_space *mapping, } } BUG_ON(page_mapped(page)); - ret = do_launder_page(mapping, page); - if (ret == 0 && !invalidate_complete_page2(mapping, page)) - ret = -EIO; + ret2 = do_launder_page(mapping, page); + if (ret2 == 0) { + if (!invalidate_complete_page2(mapping, page)) + ret2 = -EIO; + } + if (ret2 < 0) + ret = ret2; unlock_page(page); } pagevec_release(&pvec); -- cgit v1.2.3