HWPOISON: return early on non-LRU pages
[safe/jmp/linux-2.6] / mm / mincore.c
index 9780097..8cb508f 100644 (file)
@@ -33,7 +33,7 @@ static unsigned char mincore_page(struct address_space *mapping, pgoff_t pgoff)
         * When tmpfs swaps out a page from a file, any process mapping that
         * file will not get a swp_entry_t in its pte, but rather it is like
         * any other file mapping (ie. marked !present and faulted in with
-        * tmpfs's .nopage). So swapped out tmpfs mappings are tested here.
+        * tmpfs's .fault). So swapped out tmpfs mappings are tested here.
         *
         * However when tmpfs moves the page from pagecache and into swapcache,
         * it is still in core, but the find_get_page below won't find it.
@@ -77,8 +77,16 @@ static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pag
         * PTE array for our address.
         */
        nr = PTRS_PER_PTE - ((addr >> PAGE_SHIFT) & (PTRS_PER_PTE-1));
-       if (nr > pages)
-               nr = pages;
+
+       /*
+        * Don't overrun this vma
+        */
+       nr = min(nr, (vma->vm_end - addr) >> PAGE_SHIFT);
+
+       /*
+        * Don't return more than the caller asked for
+        */
+       nr = min(nr, pages);
 
        pgd = pgd_offset(vma->vm_mm, addr);
        if (pgd_none_or_clear_bad(pgd))
@@ -125,6 +133,8 @@ static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pag
 #endif
                        }
                }
+
+               vec[i] = present;
        }
        pte_unmap_unlock(ptep-1, ptl);
 
@@ -135,6 +145,9 @@ none_mapped:
                pgoff = linear_page_index(vma, addr);
                for (i = 0; i < nr; i++, pgoff++)
                        vec[i] = mincore_page(vma->vm_file->f_mapping, pgoff);
+       } else {
+               for (i = 0; i < nr; i++)
+                       vec[i] = 0;
        }
 
        return nr;
@@ -164,8 +177,8 @@ none_mapped:
  *             mapped
  *  -EAGAIN - A kernel resource was temporarily unavailable.
  */
-asmlinkage long sys_mincore(unsigned long start, size_t len,
-       unsigned char __user * vec)
+SYSCALL_DEFINE3(mincore, unsigned long, start, size_t, len,
+               unsigned char __user *, vec)
 {
        long retval;
        unsigned long pages;