fix invalidate_inode_pages2_range() to not clear ret
authorHisashi Hifumi <[email protected]>
Mon, 28 Apr 2008 09:12:08 +0000 (02:12 -0700)
committerLinus Torvalds <[email protected]>
Mon, 28 Apr 2008 15:58:18 +0000 (08:58 -0700)
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.

[[email protected]: coding-style fixes]
Signed-off-by: Hisashi Hifumi <[email protected]>
Cc: Badari Pulavarty <[email protected]>
Cc: Ken Chen <[email protected]>
Cc: Zach Brown <[email protected]>
Cc: Nick Piggin <[email protected]>
Cc: Trond Myklebust <[email protected]>
Cc: "J. Bruce Fields" <[email protected]>
Cc: Chuck Lever <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
mm/truncate.c

index 7d20ce41ecf52c2cd4027207558734f835124992..b8961cb6341401e27f9debffc5832154525fadcb 100644 (file)
@@ -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);