Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.25-rc1 /mm/mmap.c

Filename:/mm/mmap.c
Lines Added:27
Lines Deleted:15
Also changed in: (Previous) 2.6.24-git22  2.6.24-git21  2.6.24-git20  2.6.24.1  2.6.24-git19  2.6.24-git18 
(Following) 2.6.25-rc2  2.6.25-rc3  2.6.25-rc4  2.6.25-rc5  2.6.25-rc6  2.6.25-rc7 

Location
[  2.6.25-rc1
  [  mm
     o  mmap.c

Patch

diff --git a/mm/mmap.c b/mm/mmap.c
index 15678aa..a32d28c 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -36,6 +36,10 @@
 #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);
@@ -1423,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);
@@ -1620,7 +1625,7 @@ static inline int expand_downwards(struct vm_area_struct *vma,
       return -ENOMEM;
 
    address &= PAGE_MASK;
-   error = security_file_mmap(0, 0, 0, 0, address, 1);
+   error = security_file_mmap(NULL, 0, 0, 0, address, 1);
    if (error)
       return error;
 
@@ -1941,7 +1946,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
    if (is_hugepage_only_range(mm, addr, len))
       return -EINVAL;
 
-   error = security_file_mmap(0, 0, 0, 0, addr, 1);
+   error = security_file_mmap(NULL, 0, 0, 0, addr, 1);
    if (error)
       return error;
 
@@ -2160,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;
 }
 
 /*
@@ -2189,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,
 };
 
 /*
@@ -2215,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;


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.