Signed-off-by: Dave Hansen --- 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-07-28 13:50:41.000000000 -0700 +++ memhotplug-dave/mm/truncate.c 2005-07-28 13:50:41.000000000 -0700 @@ -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; _