mm: prevent get_user_pages() from overflowing page refcount
[linux-2.6-microblaze.git] / mm / migrate.c
index d4fd680..181f5d2 100644 (file)
@@ -1315,6 +1315,16 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
                lock_page(hpage);
        }
 
+       /*
+        * Check for pages which are in the process of being freed.  Without
+        * page_mapping() set, hugetlbfs specific move page routine will not
+        * be called and we could leak usage counts for subpools.
+        */
+       if (page_private(hpage) && !page_mapping(hpage)) {
+               rc = -EBUSY;
+               goto out_unlock;
+       }
+
        if (PageAnon(hpage))
                anon_vma = page_get_anon_vma(hpage);
 
@@ -1345,6 +1355,7 @@ put_anon:
                put_new_page = NULL;
        }
 
+out_unlock:
        unlock_page(hpage);
 out:
        if (rc != -EAGAIN)