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

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

Advertisement

Kernel v2.4.4 /mm/mmap.c

Filename:/mm/mmap.c
Lines Added:46
Lines Deleted:19
Also changed in: (Previous) 2.4.4-pre8  2.4.4-pre7  2.4.4-pre6  2.4.4-pre5  2.4.4-pre4  2.4.4-pre3 
(Following) 2.4.4-ac1  2.4.4-ac2  2.4.4-ac3  2.4.4-ac4  2.4.4-ac5  2.4.4-ac6 

Location
[  2.4.4
  [  mm
     o  mmap.c

Patch

diff -u --recursive --new-file v2.4.3/linux/mm/mmap.c linux/mm/mmap.c
--- v2.4.3/linux/mm/mmap.c   Wed Mar 28 12:55:34 2001
+++ linux/mm/mmap.c   Fri Apr 13 20:15:55 2001
@@ -64,6 +64,15 @@
    free += atomic_read(&page_cache_size);
    free += nr_free_pages();
    free += nr_swap_pages;
+
+   /*
+    * This double-counts: the nrpages are both in the page-cache
+    * and in the swapper space. At the same time, this compensates
+    * for the swap-space over-allocation (ie "nr_swap_pages" being
+    * too small. 
+    */
+   free += swapper_space.nrpages;
+
    /*
     * The code below doesn't account for free space in the inode
     * and dentry slab cache, slab cache fragmentation, inodes and
@@ -224,14 +233,9 @@
    /* Obtain the address to map to. we verify (or select) it and ensure
     * that it represents a valid section of the address space.
     */
-   if (flags & MAP_FIXED) {
-      if (addr & ~PAGE_MASK)
-         return -EINVAL;
-   } else {
-      addr = get_unmapped_area(addr, len);
-      if (!addr)
-         return -ENOMEM;
-   }
+   addr = get_unmapped_area(file, addr, len, pgoff, flags);
+   if (addr & ~PAGE_MASK)
+      return addr;
 
    /* Do simple checking here so the lower-level routines won't have
     * to. we assume access permissions have been handled by the open
@@ -384,30 +388,53 @@
 }
 
 /* Get an address range which is currently unmapped.
- * For mmap() without MAP_FIXED and shmat() with addr=0.
- * Return value 0 means ENOMEM.
+ * For shmat() with addr=0.
+ *
+ * Ugly calling convention alert:
+ * Return value with the low bits set means error value,
+ * ie
+ *   if (ret & ~PAGE_MASK)
+ *      error = ret;
+ *
+ * This function "knows" that -ENOMEM has the bits set.
  */
 #ifndef HAVE_ARCH_UNMAPPED_AREA
-unsigned long get_unmapped_area(unsigned long addr, unsigned long len)
+static inline unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, u+
nsigned long flags)
 {
-   struct vm_area_struct * vmm;
+   struct vm_area_struct *vma;
 
    if (len > TASK_SIZE)
-      return 0;
+      return -ENOMEM;
    if (!addr)
       addr = TASK_UNMAPPED_BASE;
    addr = PAGE_ALIGN(addr);
 
-   for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
-      /* At this point:  (!vmm || addr < vmm->vm_end). */
+   for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
+      /* At this point:  (!vma || addr < vma->vm_end). */
       if (TASK_SIZE - len < addr)
-         return 0;
-      if (!vmm || addr + len <= vmm->vm_start)
+         return -ENOMEM;
+      if (!vma || addr + len <= vma->vm_start)
          return addr;
-      addr = vmm->vm_end;
+      addr = vma->vm_end;
    }
 }
-#endif
+#else
+extern unsigned long arch_get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+#endif   
+
+unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+   if (flags & MAP_FIXED) {
+      if (addr & ~PAGE_MASK)
+         return -EINVAL;
+      return addr;
+   }
+
+   if (file && file->f_op && file->f_op->get_unmapped_area)
+      return file->f_op->get_unmapped_area(file, addr, len, pgoff, flags);
+
+   return arch_get_unmapped_area(file, addr, len, pgoff, flags);
+}
 
 #define vm_avl_empty   (struct vm_area_struct *) NULL
 


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