]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/mmap.c
Pull bugfix into test branch
[linux-2.6-omap-h63xx.git] / mm / mmap.c
index e66a0b524affef544588a8c4f8a92d3473b79a34..9717337293c3a7f3eb51ed60d70369efa8a24bb3 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -64,6 +64,13 @@ pgprot_t protection_map[16] = {
        __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
 };
 
+pgprot_t vm_get_page_prot(unsigned long vm_flags)
+{
+       return protection_map[vm_flags &
+                               (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+}
+EXPORT_SYMBOL(vm_get_page_prot);
+
 int sysctl_overcommit_memory = OVERCOMMIT_GUESS;  /* heuristic overcommit */
 int sysctl_overcommit_ratio = 50;      /* default is 50% */
 int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
@@ -109,7 +116,7 @@ int __vm_enough_memory(long pages, int cap_sys_admin)
                 * which are reclaimable, under pressure.  The dentry
                 * cache and most inode caches should fall into this
                 */
-               free += atomic_read(&slab_reclaim_pages);
+               free += global_page_state(NR_SLAB_RECLAIMABLE);
 
                /*
                 * Leave the last 3% for root
@@ -181,7 +188,7 @@ static void __remove_shared_vm_struct(struct vm_area_struct *vma,
                struct file *file, struct address_space *mapping)
 {
        if (vma->vm_flags & VM_DENYWRITE)
-               atomic_inc(&file->f_dentry->d_inode->i_writecount);
+               atomic_inc(&file->f_path.dentry->d_inode->i_writecount);
        if (vma->vm_flags & VM_SHARED)
                mapping->i_mmap_writable--;
 
@@ -392,7 +399,7 @@ static inline void __vma_link_file(struct vm_area_struct *vma)
                struct address_space *mapping = file->f_mapping;
 
                if (vma->vm_flags & VM_DENYWRITE)
-                       atomic_dec(&file->f_dentry->d_inode->i_writecount);
+                       atomic_dec(&file->f_path.dentry->d_inode->i_writecount);
                if (vma->vm_flags & VM_SHARED)
                        mapping->i_mmap_writable++;
 
@@ -893,17 +900,6 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
        int accountable = 1;
        unsigned long charged = 0, reqprot = prot;
 
-       if (file) {
-               if (is_file_hugepages(file))
-                       accountable = 0;
-
-               if (!file->f_op || !file->f_op->mmap)
-                       return -ENODEV;
-
-               if ((prot & PROT_EXEC) &&
-                   (file->f_vfsmnt->mnt_flags & MNT_NOEXEC))
-                       return -EPERM;
-       }
        /*
         * Does the application expect PROT_READ to imply PROT_EXEC?
         *
@@ -911,7 +907,7 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
         *  mounted, in which case we dont add PROT_EXEC.)
         */
        if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
-               if (!(file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC)))
+               if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
                        prot |= PROT_EXEC;
 
        if (!len)
@@ -964,7 +960,7 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
                        return -EAGAIN;
        }
 
-       inode = file ? file->f_dentry->d_inode : NULL;
+       inode = file ? file->f_path.dentry->d_inode : NULL;
 
        if (file) {
                switch (flags & MAP_TYPE) {
@@ -993,6 +989,16 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
                case MAP_PRIVATE:
                        if (!(file->f_mode & FMODE_READ))
                                return -EACCES;
+                       if (file->f_path.mnt->mnt_flags & MNT_NOEXEC) {
+                               if (vm_flags & VM_EXEC)
+                                       return -EPERM;
+                               vm_flags &= ~VM_MAYEXEC;
+                       }
+                       if (is_file_hugepages(file))
+                               accountable = 0;
+
+                       if (!file->f_op || !file->f_op->mmap)
+                               return -ENODEV;
                        break;
 
                default:
@@ -1098,12 +1104,6 @@ munmap_back:
                        goto free_vma;
        }
 
-       /* Don't make the VMA automatically writable if it's shared, but the
-        * backer wishes to know when pages are first written to */
-       if (vma->vm_ops && vma->vm_ops->page_mkwrite)
-               vma->vm_page_prot =
-                       protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
-
        /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
         * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
         * that memory reservation must be checked; but that reservation
@@ -1121,6 +1121,10 @@ munmap_back:
        pgoff = vma->vm_pgoff;
        vm_flags = vma->vm_flags;
 
+       if (vma_wants_writenotify(vma))
+               vma->vm_page_prot =
+                       protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
+
        if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
                        vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
                file = vma->vm_file;
@@ -1375,7 +1379,7 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
                 * Check if the given range is hugepage aligned, and
                 * can be made suitable for hugepages.
                 */
-               ret = prepare_hugepage_range(addr, len);
+               ret = prepare_hugepage_range(addr, len, pgoff);
        } else {
                /*
                 * Ensure that a normal request is not falling in a
@@ -1732,7 +1736,7 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
        if (mm->map_count >= sysctl_max_map_count)
                return -ENOMEM;
 
-       new = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+       new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
        if (!new)
                return -ENOMEM;
 
@@ -1876,6 +1880,9 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
        if ((addr + len) > TASK_SIZE || (addr + len) < addr)
                return -EINVAL;
 
+       if (is_hugepage_only_range(mm, addr, len))
+               return -EINVAL;
+
        flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
 
        error = arch_mmap_check(addr, len, flags);
@@ -2050,7 +2057,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
                    vma_start < new_vma->vm_end)
                        *vmap = new_vma;
        } else {
-               new_vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+               new_vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
                if (new_vma) {
                        *new_vma = *vma;
                        pol = mpol_copy(vma_policy(vma));