diff --git a/as_ops.c b/as_ops.c index 393e9d1..df856df 100644 --- a/as_ops.c +++ b/as_ops.c @@ -309,9 +309,45 @@ int reiser4_releasepage(struct page *page, gfp_t gfp UNUSED_ARG) int reiser4_migratepage(struct address_space *mapping, struct page *newpage, struct page *page, enum migrate_mode mode) { - /* TODO: implement movable mapping + int result; + jnode *node; + + assert("intelfx-62", PageLocked(page)); + assert("intelfx-63", !PageWriteback(page)); + assert("intelfx-64", reiser4_schedulable()); + assert("intelfx-65", page->mapping != NULL); + assert("intelfx-66", page->mapping->host != NULL); + + if (!PagePrivate(page)) + /* + * anonymous, not yet captured page + */ + return migrate_page(mapping, newpage, page, mode); + /* + * page has an attached jnode. That jnode should be + * linked with the new page. Otherwise, everyone + * calling jnode_page(), etc will get invalid data */ - return -EIO; + node = jnode_by_page(page); + spin_lock_jnode(node); + spin_lock(&(node->load)); + + page_clear_jnode(page, node); + set_page_private(newpage, 0ul); + + result = migrate_page(mapping, newpage, page, mode); + if (unlikely(result)) + /* + * migration failed - reattach the old page + */ + jnode_attach_page(node, page); + else + jnode_attach_page(node, newpage); + spin_unlock(&(node->load)); + spin_unlock_jnode(node); + + assert("intelfx-67", reiser4_schedulable()); + return result; } #endif /* CONFIG_MIGRATION */