

Memory migration might be rolled back during file truncation.
In this case these pages must be checked whether it has happned.

Signed-off-by: Hirokazu Takahashi <taka@valinux.co.jp>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 memhotplug-dave/mm/truncate.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+)

diff -puN mm/truncate.c~P11-migrate-truncate mm/truncate.c
--- memhotplug/mm/truncate.c~P11-migrate-truncate	2004-10-12 10:11:15.000000000 -0700
+++ memhotplug-dave/mm/truncate.c	2004-10-12 10:11:15.000000000 -0700
@@ -162,6 +162,9 @@ void truncate_inode_pages_range(struct a
 				unlock_page(page);
 				continue;
 			}
+			/* page->mapping check is done in
+			 * truncate_complete_page() when the page has been
+			 * migrated. */
 			truncate_complete_page(mapping, page);
 			unlock_page(page);
 		}
@@ -198,6 +201,16 @@ void truncate_inode_pages_range(struct a
 			if (page->index > end)
 				break;
 			lock_page(page);
+			if (page->mapping == NULL) {
+				struct page *newpage;
+				unlock_page(page);
+				if ((newpage = find_lock_page(mapping, page->index))) {
+					/* memory migration has been rolled back. */
+					page_cache_release(page);
+					pvec.pages[i] = page = newpage;
+				} else
+					lock_page(page);
+			}
 			wait_on_page_writeback(page);
 			if (page->index > next)
 				next = page->index;
@@ -306,6 +319,16 @@ void invalidate_inode_pages2(struct addr
 			struct page *page = pvec.pages[i];
 
 			lock_page(page);
+			if (page->mapping == NULL) {
+				struct page *newpage;
+				unlock_page(page);
+				if ((newpage = find_lock_page(mapping, page->index))) {
+					/* memory migration has been rolled back. */
+					page_cache_release(page);
+					pvec.pages[i] = page = newpage;
+				} else
+					lock_page(page);
+			}
 			if (page->mapping == mapping) {	/* truncate race? */
 				wait_on_page_writeback(page);
 				next = page->index + 1;
_
