mm: mempolicy: fix the wrong return value and potential pages leak of mbind
[linux-2.6-microblaze.git] / mm / mempolicy.c
index 4ae967b..e08c941 100644 (file)
@@ -672,7 +672,9 @@ static const struct mm_walk_ops queue_pages_walk_ops = {
  * 1 - there is unmovable page, but MPOL_MF_MOVE* & MPOL_MF_STRICT were
  *     specified.
  * 0 - queue pages successfully or no misplaced page.
- * -EIO - there is misplaced page and only MPOL_MF_STRICT was specified.
+ * errno - i.e. misplaced pages with MPOL_MF_STRICT specified (-EIO) or
+ *         memory range specified by nodemask and maxnode points outside
+ *         your accessible address space (-EFAULT)
  */
 static int
 queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end,
@@ -1286,7 +1288,7 @@ static long do_mbind(unsigned long start, unsigned long len,
                          flags | MPOL_MF_INVERT, &pagelist);
 
        if (ret < 0) {
-               err = -EIO;
+               err = ret;
                goto up_out;
        }
 
@@ -1305,10 +1307,12 @@ static long do_mbind(unsigned long start, unsigned long len,
 
                if ((ret > 0) || (nr_failed && (flags & MPOL_MF_STRICT)))
                        err = -EIO;
-       } else
-               putback_movable_pages(&pagelist);
-
+       } else {
 up_out:
+               if (!list_empty(&pagelist))
+                       putback_movable_pages(&pagelist);
+       }
+
        up_write(&mm->mmap_sem);
 mpol_out:
        mpol_put(new);