mm: fix various kernel-doc comments
[safe/jmp/linux-2.6] / mm / mmap.c
index facc1a7..a32d28c 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
 #define arch_mmap_check(addr, len, flags)      (0)
 #endif
 
+#ifndef arch_rebalance_pgtables
+#define arch_rebalance_pgtables(addr, len)             (addr)
+#endif
+
 static void unmap_region(struct mm_struct *mm,
                struct vm_area_struct *vma, struct vm_area_struct *prev,
                unsigned long start, unsigned long end);
@@ -241,7 +245,7 @@ asmlinkage unsigned long sys_brk(unsigned long brk)
 
        down_write(&mm->mmap_sem);
 
-       if (brk < mm->end_code)
+       if (brk < mm->start_brk)
                goto out;
 
        /*
@@ -251,7 +255,8 @@ asmlinkage unsigned long sys_brk(unsigned long brk)
         * not page aligned -Ram Gupta
         */
        rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
-       if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
+       if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
+                       (mm->end_data - mm->start_data) > rlim)
                goto out;
 
        newbrk = PAGE_ALIGN(brk);
@@ -912,6 +917,9 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
        if (!len)
                return -EINVAL;
 
+       if (!(flags & MAP_FIXED))
+               addr = round_hint_to_min(addr);
+
        error = arch_mmap_check(addr, len, flags);
        if (error)
                return error;
@@ -1420,7 +1428,7 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
        if (addr & ~PAGE_MASK)
                return -EINVAL;
 
-       return addr;
+       return arch_rebalance_pgtables(addr, len);
 }
 
 EXPORT_SYMBOL(get_unmapped_area);
@@ -1615,6 +1623,12 @@ static inline int expand_downwards(struct vm_area_struct *vma,
         */
        if (unlikely(anon_vma_prepare(vma)))
                return -ENOMEM;
+
+       address &= PAGE_MASK;
+       error = security_file_mmap(NULL, 0, 0, 0, address, 1);
+       if (error)
+               return error;
+
        anon_vma_lock(vma);
 
        /*
@@ -1622,8 +1636,6 @@ static inline int expand_downwards(struct vm_area_struct *vma,
         * is required to hold the mmap_sem in read mode.  We need the
         * anon_vma lock to serialize against concurrent expand_stacks.
         */
-       address &= PAGE_MASK;
-       error = 0;
 
        /* Somebody else might have raced and expanded it already */
        if (address < vma->vm_start) {
@@ -1934,6 +1946,10 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
        if (is_hugepage_only_range(mm, addr, len))
                return -EINVAL;
 
+       error = security_file_mmap(NULL, 0, 0, 0, addr, 1);
+       if (error)
+               return error;
+
        flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
 
        error = arch_mmap_check(addr, len, flags);
@@ -2149,24 +2165,31 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
 }
 
 
-static struct page *special_mapping_nopage(struct vm_area_struct *vma,
-                                          unsigned long address, int *type)
+static int special_mapping_fault(struct vm_area_struct *vma,
+                               struct vm_fault *vmf)
 {
+       pgoff_t pgoff;
        struct page **pages;
 
-       BUG_ON(address < vma->vm_start || address >= vma->vm_end);
+       /*
+        * special mappings have no vm_file, and in that case, the mm
+        * uses vm_pgoff internally. So we have to subtract it from here.
+        * We are allowed to do this because we are the mm; do not copy
+        * this code into drivers!
+        */
+       pgoff = vmf->pgoff - vma->vm_pgoff;
 
-       address -= vma->vm_start;
-       for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
-               address -= PAGE_SIZE;
+       for (pages = vma->vm_private_data; pgoff && *pages; ++pages)
+               pgoff--;
 
        if (*pages) {
                struct page *page = *pages;
                get_page(page);
-               return page;
+               vmf->page = page;
+               return 0;
        }
 
-       return NOPAGE_SIGBUS;
+       return VM_FAULT_SIGBUS;
 }
 
 /*
@@ -2178,7 +2201,7 @@ static void special_mapping_close(struct vm_area_struct *vma)
 
 static struct vm_operations_struct special_mapping_vmops = {
        .close = special_mapping_close,
-       .nopage = special_mapping_nopage,
+       .fault = special_mapping_fault,
 };
 
 /*
@@ -2204,7 +2227,7 @@ int install_special_mapping(struct mm_struct *mm,
        vma->vm_start = addr;
        vma->vm_end = addr + len;
 
-       vma->vm_flags = vm_flags | mm->def_flags;
+       vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 
        vma->vm_ops = &special_mapping_vmops;