As Stephen Tweedie points out, 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: Andrew Morton --- 25-akpm/mm/truncate.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diff -puN mm/truncate.c~invalidate_inode_pages2_range-livelock-fix mm/truncate.c --- 25/mm/truncate.c~invalidate_inode_pages2_range-livelock-fix Mon Mar 7 15:47:25 2005 +++ 25-akpm/mm/truncate.c Mon Mar 7 15:49:09 2005 @@ -305,15 +305,22 @@ int invalidate_inode_pages2_range(struct 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) { + page_index = page->index; + if (page_index > end) { + next = page_index; + unlock_page(page); + break; + } + if (page->mapping != mapping) { unlock_page(page); continue; } wait_on_page_writeback(page); - next = page->index + 1; + next = page_index + 1; if (next == 0) wrapped = 1; while (page_mapped(page)) { @@ -323,7 +330,7 @@ int invalidate_inode_pages2_range(struct */ unmap_mapping_range(mapping, page->index << PAGE_CACHE_SHIFT, - (end - page->index + 1) + (end - page_index + 1) << PAGE_CACHE_SHIFT, 0); did_range_unmap = 1; @@ -332,7 +339,7 @@ int invalidate_inode_pages2_range(struct * Just zap this page */ unmap_mapping_range(mapping, - page->index << PAGE_CACHE_SHIFT, + page_index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE, 0); } } _