patch-2.1.130 linux/mm/mmap.c

Next file: linux/mm/mprotect.c
Previous file: linux/mm/mlock.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.129/linux/mm/mmap.c linux/mm/mmap.c
@@ -3,24 +3,17 @@
  *
  * Written by obz.
  */
-#include <linux/stat.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/shm.h>
-#include <linux/errno.h>
 #include <linux/mman.h>
-#include <linux/string.h>
 #include <linux/pagemap.h>
 #include <linux/swap.h>
-#include <linux/smp.h>
+#include <linux/swapctl.h>
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/file.h>
 
 #include <asm/uaccess.h>
-#include <asm/system.h>
 #include <asm/pgtable.h>
 
 /* description of effects of mapping type and prot in current implementation.
@@ -57,6 +50,12 @@
 	 * simple, it hopefully works in most obvious cases.. Easy to
 	 * fool it, but this should catch most mistakes.
 	 */
+	/* 23/11/98 NJC: Somewhat less stupid version of algorithm,
+	 * which tries to do "TheRightThing".  Instead of using half of
+	 * (buffers+cache), use the minimum values.  Allow an extra 2%
+	 * of num_physpages for safety margin.
+	 */
+
 	long free;
 	
         /* Sometimes we want to use more memory than we have. */
@@ -65,10 +64,9 @@
 
 	free = buffermem >> PAGE_SHIFT;
 	free += page_cache_size;
-	free >>= 1;
 	free += nr_free_pages;
 	free += nr_swap_pages;
-	free -= num_physpages >> 4;
+	free -= (page_cache.min_percent + buffer_mem.min_percent + 2)*num_physpages/100; 
 	return free > pages;
 }
 
@@ -176,7 +174,7 @@
 {
 	struct mm_struct * mm = current->mm;
 	struct vm_area_struct * vma;
-	int correct_wcount = 0, error;
+	int error;
 
 	if ((len = PAGE_ALIGN(len)) == 0)
 		return addr;
@@ -300,30 +298,28 @@
 	    !vm_enough_memory(len >> PAGE_SHIFT))
 		goto free_vma;
 
-	error = 0;
 	if (file) {
+		int correct_wcount = 0;
 		if (vma->vm_flags & VM_DENYWRITE) {
-			if (file->f_dentry->d_inode->i_writecount > 0)
+			if (file->f_dentry->d_inode->i_writecount > 0) {
 				error = -ETXTBSY;
-			else {
-	        		/* f_op->mmap might possibly sleep
-				 * (generic_file_mmap doesn't, but other code
-				 * might). In any case, this takes care of any
-				 * race that this might cause.
-				 */
-				file->f_dentry->d_inode->i_writecount--;
-				correct_wcount = 1;
+				goto free_vma;
 			}
+	        	/* f_op->mmap might possibly sleep
+			 * (generic_file_mmap doesn't, but other code
+			 * might). In any case, this takes care of any
+			 * race that this might cause.
+			 */
+			file->f_dentry->d_inode->i_writecount--;
+			correct_wcount = 1;
 		}
-		if (!error)
-			error = file->f_op->mmap(file, vma);
-	
+		error = file->f_op->mmap(file, vma);
+		/* Fix up the count if necessary, then check for an error */
+		if (correct_wcount)
+			file->f_dentry->d_inode->i_writecount++;
+		if (error)
+			goto unmap_and_free_vma;
 	}
-	/* Fix up the count if necessary, then check for an error */
-	if (correct_wcount)
-		file->f_dentry->d_inode->i_writecount++;
-	if (error)
-		goto free_vma;
 
 	/*
 	 * merge_segments may merge our vma, so we can't refer to it
@@ -341,6 +337,11 @@
 	}
 	return addr;
 
+unmap_and_free_vma:
+	/* Undo any partial mapping done by a device driver. */
+	flush_cache_range(mm, vma->vm_start, vma->vm_end);
+	zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
+	flush_tlb_range(mm, vma->vm_start, vma->vm_end);
 free_vma:
 	kmem_cache_free(vm_area_cachep, vma);
 	return error;
@@ -432,6 +433,7 @@
 		mpnt->vm_ops = area->vm_ops;
 		mpnt->vm_offset = area->vm_offset + (end - area->vm_start);
 		mpnt->vm_file = area->vm_file;
+		mpnt->vm_pte = area->vm_pte;
 		if (mpnt->vm_file)
 			mpnt->vm_file->f_count++;
 		if (mpnt->vm_ops && mpnt->vm_ops->open)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov