aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2004-10-18 08:56:50 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-10-18 08:56:50 -0700
commit9ee4f026a1a053c522f93982793d0e29d7db6a1f (patch)
tree8eb16ea0c6eb4a2875b45927a054052a619bb46c /mm
parent524396e721dc1a74d0f9f8e6e6667ad6f7dc6ff5 (diff)
downloadhistory-9ee4f026a1a053c522f93982793d0e29d7db6a1f.tar.gz
[PATCH] invalidate page race fix
invalidate_inode_pages() and invalidate_inode_pages2() can mark pages not uptodate while read() is trying to read from them. This is interpreted as an I/O error. Fix that by teaching the invalidate code to leave the page alone if someone else has a ref on it. Signed-off-by: Jens Axboe <axboe@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/truncate.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/mm/truncate.c b/mm/truncate.c
index 0ab3a157e985f4..7cd2ed501bb2f2 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -79,6 +79,12 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
spin_unlock_irq(&mapping->tree_lock);
return 0;
}
+
+ BUG_ON(PagePrivate(page));
+ if (page_count(page) != 2) {
+ spin_unlock_irq(&mapping->tree_lock);
+ return 0;
+ }
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
ClearPageUptodate(page);
@@ -269,7 +275,11 @@ void invalidate_inode_pages2(struct address_space *mapping)
clear_page_dirty(page);
ClearPageUptodate(page);
} else {
- invalidate_complete_page(mapping, page);
+ if (!invalidate_complete_page(mapping,
+ page)) {
+ clear_page_dirty(page);
+ ClearPageUptodate(page);
+ }
}
}
unlock_page(page);