Commit f9e697a2 authored by Stephen C. Tweedie's avatar Stephen C. Tweedie Committed by Linus Torvalds

[PATCH] invalidate_inode_pages2_range livelock fix

With Andrew Morton

invalidate_inode_pages2_range() can livelock if all the pages in the pagevec
are outside the end of teh range which we're trying to invalidate.

Fix that up in a similar manner to the truncate_inode_pages_range() handling.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent cbd24e68
......@@ -268,25 +268,31 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
min(end - next, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
struct page *page = pvec.pages[i];
pgoff_t page_index;
int was_dirty;
lock_page(page);
if (page->mapping != mapping || page->index > end) {
if (page->mapping != mapping) {
unlock_page(page);
continue;
}
wait_on_page_writeback(page);
next = page->index + 1;
page_index = page->index;
next = page_index + 1;
if (next == 0)
wrapped = 1;
if (page_index > end) {
unlock_page(page);
break;
}
wait_on_page_writeback(page);
while (page_mapped(page)) {
if (!did_range_unmap) {
/*
* Zap the rest of the file in one hit.
*/
unmap_mapping_range(mapping,
page->index << PAGE_CACHE_SHIFT,
(end - page->index + 1)
page_index << PAGE_CACHE_SHIFT,
(end - page_index + 1)
<< PAGE_CACHE_SHIFT,
0);
did_range_unmap = 1;
......@@ -295,7 +301,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
* Just zap this page
*/
unmap_mapping_range(mapping,
page->index << PAGE_CACHE_SHIFT,
page_index << PAGE_CACHE_SHIFT,
PAGE_CACHE_SIZE, 0);
}
}
......
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