

As Stephen Tweedie <sct@redhat.com> 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 <akpm@osdl.org>
---

 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);
 				}
 			}
_
