diff options
author | Hisashi Hifumi <hifumi.hisashi@oss.ntt.co.jp> | 2008-04-28 05:12:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-28 11:58:18 -0400 |
commit | 0dd1334faf7e075bfdb6f5284eed65210b296fc1 (patch) | |
tree | d64b7b1d4035d8b524b01d5cd3800135edcacc25 /mm/truncate.c | |
parent | ddc81ed2c5d47a078a3b02c5c3a4345bc2bc3c9b (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>
Diffstat (limited to 'mm/truncate.c')
-rw-r--r-- | mm/truncate.c | 11 |
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); |