
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 memhotplug-dave/mm/truncate.c |   32 ++++++++++++++++++++++++++++++--
 1 files changed, 30 insertions(+), 2 deletions(-)

diff -puN mm/truncate.c~P11.1-migrate-truncate-breakout mm/truncate.c
--- memhotplug/mm/truncate.c~P11.1-migrate-truncate-breakout	2004-12-10 13:53:09.000000000 -0800
+++ memhotplug-dave/mm/truncate.c	2004-12-10 13:53:09.000000000 -0800
@@ -291,6 +291,34 @@ unsigned long invalidate_inode_pages(str
 
 EXPORT_SYMBOL(invalidate_inode_pages);
 
+static inline struct page *lock_replace_page(struct pagevec *pvec, int i, struct address_space *mapping)
+{
+	struct page *newpage;
+	struct page *page = pvec->pages[i];
+
+	lock_page(page);
+
+	if (page->mapping != NULL)
+		return page;
+
+	unlock_page(page);
+
+	newpage = find_lock_page(mapping, page->index);
+	if (!newpage) {
+		/*
+		 * put the page back the way it was and let
+		 * the normal truncate code handle it
+		 */
+		lock_page(page);
+		return page;
+	}
+
+	/* memory migration has been rolled back. */
+	page_cache_release(page);
+	pvec->pages[i] = newpage;
+	return newpage;
+}
+
 /**
  * invalidate_inode_pages2 - remove all pages from an address_space
  * @mapping - the address_space
@@ -311,10 +339,10 @@ int invalidate_inode_pages2(struct addre
 	pagevec_init(&pvec, 0);
 	while (!ret && pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
 		for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
-			struct page *page = pvec.pages[i];
+			struct page *page;
 			int was_dirty;
 
-			lock_page(page);
+			page = lock_replace_page(&pvec, i, mapping);
 			if (page->mapping != mapping) {	/* truncate race? */
 				unlock_page(page);
 				continue;
_
