aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/mincore.c29
1 files changed, 10 insertions, 19 deletions
diff --git a/mm/mincore.c b/mm/mincore.c
index b44d7f875cb6..566b6c2bae5f 100644
--- a/mm/mincore.c
+++ b/mm/mincore.c
@@ -49,29 +49,20 @@ static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pag
49 struct vm_area_struct *vma = find_vma(current->mm, addr); 49 struct vm_area_struct *vma = find_vma(current->mm, addr);
50 50
51 /* 51 /*
52 * find_vma() didn't find anything: the address 52 * find_vma() didn't find anything above us, or we're
53 * is above everything we have mapped. 53 * in an unmapped hole in the address space: ENOMEM.
54 */ 54 */
55 if (!vma) { 55 if (!vma || addr < vma->vm_start)
56 memset(vec, 0, pages); 56 return -ENOMEM;
57 return pages;
58 }
59
60 /*
61 * find_vma() found something, but we might be
62 * below it: check for that.
63 */
64 if (addr < vma->vm_start) {
65 unsigned long gap = (vma->vm_start - addr) >> PAGE_SHIFT;
66 if (gap > pages)
67 gap = pages;
68 memset(vec, 0, gap);
69 return gap;
70 }
71 57
72 /* 58 /*
73 * Ok, got it. But check whether it's a segment we support 59 * Ok, got it. But check whether it's a segment we support
74 * mincore() on. Right now, we don't do any anonymous mappings. 60 * mincore() on. Right now, we don't do any anonymous mappings.
61 *
62 * FIXME: This is just stupid. And returning ENOMEM is
63 * stupid too. We should just look at the page tables. But
64 * this is what we've traditionally done, so we'll just
65 * continue doing it.
75 */ 66 */
76 if (!vma->vm_file) 67 if (!vma->vm_file)
77 return -ENOMEM; 68 return -ENOMEM;
@@ -142,7 +133,7 @@ asmlinkage long sys_mincore(unsigned long start, size_t len,
142 133
143 tmp = (void *) __get_free_page(GFP_USER); 134 tmp = (void *) __get_free_page(GFP_USER);
144 if (!tmp) 135 if (!tmp)
145 return -ENOMEM; 136 return -EAGAIN;
146 137
147 retval = 0; 138 retval = 0;
148 while (pages) { 139 while (pages) {