Commit 9ee4f026 authored by Jens Axboe's avatar Jens Axboe Committed by Linus Torvalds

[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: default avatarJens Axboe <axboe@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 524396e7
...@@ -79,6 +79,12 @@ invalidate_complete_page(struct address_space *mapping, struct page *page) ...@@ -79,6 +79,12 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
spin_unlock_irq(&mapping->tree_lock); spin_unlock_irq(&mapping->tree_lock);
return 0; return 0;
} }
BUG_ON(PagePrivate(page));
if (page_count(page) != 2) {
spin_unlock_irq(&mapping->tree_lock);
return 0;
}
__remove_from_page_cache(page); __remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock); spin_unlock_irq(&mapping->tree_lock);
ClearPageUptodate(page); ClearPageUptodate(page);
...@@ -269,7 +275,11 @@ void invalidate_inode_pages2(struct address_space *mapping) ...@@ -269,7 +275,11 @@ void invalidate_inode_pages2(struct address_space *mapping)
clear_page_dirty(page); clear_page_dirty(page);
ClearPageUptodate(page); ClearPageUptodate(page);
} else { } else {
invalidate_complete_page(mapping, page); if (!invalidate_complete_page(mapping,
page)) {
clear_page_dirty(page);
ClearPageUptodate(page);
}
} }
} }
unlock_page(page); unlock_page(page);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment