[ARM] 4341/1: iop13xx: fix i/o address translation
[pandora-kernel.git] / mm / migrate.c
index b4979d4..7a66ca2 100644 (file)
@@ -294,7 +294,7 @@ out:
 static int migrate_page_move_mapping(struct address_space *mapping,
                struct page *newpage, struct page *page)
 {
-       struct page **radix_pointer;
+       void **pslot;
 
        if (!mapping) {
                /* Anonymous page */
@@ -305,12 +305,11 @@ static int migrate_page_move_mapping(struct address_space *mapping,
 
        write_lock_irq(&mapping->tree_lock);
 
-       radix_pointer = (struct page **)radix_tree_lookup_slot(
-                                               &mapping->page_tree,
-                                               page_index(page));
+       pslot = radix_tree_lookup_slot(&mapping->page_tree,
+                                       page_index(page));
 
        if (page_count(page) != 2 + !!PagePrivate(page) ||
-                       *radix_pointer != page) {
+                       (struct page *)radix_tree_deref_slot(pslot) != page) {
                write_unlock_irq(&mapping->tree_lock);
                return -EAGAIN;
        }
@@ -318,7 +317,7 @@ static int migrate_page_move_mapping(struct address_space *mapping,
        /*
         * Now we know that no one else is looking at the page.
         */
-       get_page(newpage);
+       get_page(newpage);      /* add cache reference */
 #ifdef CONFIG_SWAP
        if (PageSwapCache(page)) {
                SetPageSwapCache(newpage);
@@ -326,8 +325,14 @@ static int migrate_page_move_mapping(struct address_space *mapping,
        }
 #endif
 
-       *radix_pointer = newpage;
+       radix_tree_replace_slot(pslot, newpage);
+
+       /*
+        * Drop cache reference from old page.
+        * We know this isn't the last reference.
+        */
        __put_page(page);
+
        write_unlock_irq(&mapping->tree_lock);
 
        return 0;
@@ -776,7 +781,7 @@ static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
 
                err = -EFAULT;
                vma = find_vma(mm, pp->addr);
-               if (!vma)
+               if (!vma || !vma_migratable(vma))
                        goto set_status;
 
                page = follow_page(vma, pp->addr, FOLL_GET);