From: Hirokazu Takahashi Hi Dave, The following patch makes truncate_inode_pages_range() call lock_replace_page(), which is also called from invalidate_inode_pages2(). Please apply it after P11.1-migrate-truncate-breakout.patch . Thanks, Hirokazu Takahashi. Signed-off-by: Dave Hansen --- memhotplug-dave/mm/truncate.c | 72 ++++++++++++++++++------------------------ 1 files changed, 31 insertions(+), 41 deletions(-) diff -puN mm/truncate.c~AA-PM-11.2-truncate-use-lock_replace_page mm/truncate.c --- memhotplug/mm/truncate.c~AA-PM-11.2-truncate-use-lock_replace_page 2005-07-28 13:50:41.000000000 -0700 +++ memhotplug-dave/mm/truncate.c 2005-07-28 13:50:41.000000000 -0700 @@ -90,6 +90,34 @@ invalidate_complete_page(struct address_ return 1; } +static inline struct page *lock_replace_page(struct page **p, struct address_space *mapping) +{ + struct page *page = *p; + struct page *newpage; + + 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); + *p = newpage; + return newpage; +} + /** * truncate_inode_pages - truncate *all* the pages from an offset * @mapping: mapping to truncate @@ -170,19 +198,9 @@ void truncate_inode_pages(struct address continue; } for (i = 0; i < pagevec_count(&pvec); i++) { - struct page *page = pvec.pages[i]; + struct page *page; - 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); - } + page = lock_replace_page(&pvec.pages[i], mapping); wait_on_page_writeback(page); if (page->index > next) next = page->index; @@ -253,34 +271,6 @@ 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 @@ -312,7 +302,7 @@ int invalidate_inode_pages2_range(struct pgoff_t page_index; int was_dirty; - page = lock_replace_page(&pvec, i, mapping); + page = lock_replace_page(&pvec.pages[i], mapping); if (page->mapping != mapping) { unlock_page(page); continue; _