mmap: allow MAP_HUGETLB for hugetlbfs files v2
authorJörn Engel <joern@logfs.org>
Mon, 8 Jul 2013 23:00:26 +0000 (16:00 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jul 2013 17:33:24 +0000 (10:33 -0700)
It is counterintuitive at best that mmap'ing a hugetlbfs file with
MAP_HUGETLB fails, while mmap'ing it without will a) succeed and b)
return huge pages.

v2: use is_file_hugepages(), as suggested by Jianguo

Signed-off-by: Joern Engel <joern@logfs.org>
Cc: Jianguo Wu <wujianguo@huawei.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/mmap.c

index 8468ffd05baec80b81c13f5fa1a2a27e9b90f625..0718c175db8f3eb6236e167d561e25fcad818972 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1358,13 +1358,14 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
 
        if (!(flags & MAP_ANONYMOUS)) {
                audit_mmap_fd(fd, flags);
-               if (unlikely(flags & MAP_HUGETLB))
-                       return -EINVAL;
                file = fget(fd);
                if (!file)
                        goto out;
                if (is_file_hugepages(file))
                        len = ALIGN(len, huge_page_size(hstate_file(file)));
+               retval = -EINVAL;
+               if (unlikely(flags & MAP_HUGETLB && !is_file_hugepages(file)))
+                       goto out_fput;
        } else if (flags & MAP_HUGETLB) {
                struct user_struct *user = NULL;
                struct hstate *hs = hstate_sizelog((flags >> MAP_HUGE_SHIFT) &
@@ -1391,6 +1392,7 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
        retval = vm_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+out_fput:
        if (file)
                fput(file);
 out: