
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~AA-PM-11.1-migrate-truncate-breakout mm/truncate.c
--- memhotplug/mm/truncate.c~AA-PM-11.1-migrate-truncate-breakout	2005-03-28 16:38:18.000000000 -0800
+++ memhotplug-dave/mm/truncate.c	2005-03-28 16:38:18.000000000 -0800
@@ -253,6 +253,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_range - remove range of pages from an address_space
  * @mapping - the address_space
@@ -280,11 +308,11 @@ int invalidate_inode_pages2_range(struct
 		pagevec_lookup(&pvec, mapping, next,
 			min(end - next, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) {
 		for (i = 0; !ret && i < pagevec_count(&pvec); i++) {
-			struct page *page = pvec.pages[i];
+			struct page *page;
 			pgoff_t page_index;
 			int was_dirty;
 
-			lock_page(page);
+			page = lock_replace_page(&pvec, i, mapping);
 			if (page->mapping != mapping) {
 				unlock_page(page);
 				continue;
_
