X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=mm%2Fmincore.c;h=8cb508f84ea49ca03a7005574208ab3ec4a4e567;hb=7e0f7cf582abd6c85232331dfe726a4e4b0fd98e;hp=9780097e3812cf2c5c57a2fa3e21517215fedb8d;hpb=30fcffed8149df18592b3e006b829232b7b3844f;p=safe%2Fjmp%2Flinux-2.6 diff --git a/mm/mincore.c b/mm/mincore.c index 9780097..8cb508f 100644 --- a/mm/mincore.c +++ b/mm/mincore.c @@ -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;