Do not account for the address space used by hugetlbfs using VM_ACCOUNT
[linux-2.6-block.git] / mm / hugetlb.c
index 618e98304080a8bdb3ace929c8dcb8938662fad4..207464209546918457f9a06746f3f8383c006a80 100644 (file)
@@ -2269,14 +2269,12 @@ void hugetlb_change_protection(struct vm_area_struct *vma,
 
 int hugetlb_reserve_pages(struct inode *inode,
                                        long from, long to,
-                                       struct vm_area_struct *vma)
+                                       struct vm_area_struct *vma,
+                                       int acctflag)
 {
-       long ret, chg;
+       long ret = 0, chg;
        struct hstate *h = hstate_inode(inode);
 
-       if (vma && vma->vm_flags & VM_NORESERVE)
-               return 0;
-
        /*
         * Shared mappings base their reservation on the number of pages that
         * are already allocated on behalf of the file. Private mappings need
@@ -2285,22 +2283,25 @@ int hugetlb_reserve_pages(struct inode *inode,
         */
        if (!vma || vma->vm_flags & VM_SHARED)
                chg = region_chg(&inode->i_mapping->private_list, from, to);
-       else {
-               struct resv_map *resv_map = resv_map_alloc();
-               if (!resv_map)
-                       return -ENOMEM;
-
+       else
                chg = to - from;
 
-               set_vma_resv_map(vma, resv_map);
-               set_vma_resv_flags(vma, HPAGE_RESV_OWNER);
-       }
-
        if (chg < 0)
                return chg;
 
        if (hugetlb_get_quota(inode->i_mapping, chg))
                return -ENOSPC;
+
+       /*
+        * Only apply hugepage reservation if asked. We still have to
+        * take the filesystem quota because it is an upper limit
+        * defined for the mount and not necessarily memory as a whole
+        */
+       if (acctflag & VM_NORESERVE) {
+               reset_vma_resv_huge_pages(vma);
+               return 0;
+       }
+
        ret = hugetlb_acct_memory(h, chg);
        if (ret < 0) {
                hugetlb_put_quota(inode->i_mapping, chg);
@@ -2308,6 +2309,16 @@ int hugetlb_reserve_pages(struct inode *inode,
        }
        if (!vma || vma->vm_flags & VM_SHARED)
                region_add(&inode->i_mapping->private_list, from, to);
+       else {
+               struct resv_map *resv_map = resv_map_alloc();
+
+               if (!resv_map)
+                       return -ENOMEM;
+
+               set_vma_resv_map(vma, resv_map);
+               set_vma_resv_flags(vma, HPAGE_RESV_OWNER);
+       }
+
        return 0;
 }