patch-2.3.11 linux/fs/exec.c

Next file: linux/fs/fcntl.c
Previous file: linux/fs/buffer.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.10/linux/fs/exec.c linux/fs/exec.c
@@ -366,54 +366,41 @@
 static int exec_mmap(void)
 {
 	struct mm_struct * mm, * old_mm;
-	int retval, nr;
 
-	if (atomic_read(&current->mm->count) == 1) {
-		flush_cache_mm(current->mm);
+	old_mm = current->mm;
+	if (old_mm && atomic_read(&old_mm->mm_users) == 1) {
+		flush_cache_mm(old_mm);
 		mm_release();
-		release_segments(current->mm);
-		exit_mmap(current->mm);
-		flush_tlb_mm(current->mm);
+		release_segments(old_mm);
+		exit_mmap(old_mm);
+		flush_tlb_mm(old_mm);
 		return 0;
 	}
 
-	retval = -ENOMEM;
 	mm = mm_alloc();
-	if (!mm)
-		goto fail_nomem;
-
-	mm->cpu_vm_mask = (1UL << smp_processor_id());
-	mm->total_vm = 0;
-	mm->rss = 0;
-	/*
-	 * Make sure we have a private ldt if needed ...
-	 */
-	nr = current->tarray_ptr - &task[0]; 
-	copy_segments(nr, current, mm);
-
-	old_mm = current->mm;
-	current->mm = mm;
-	retval = new_page_tables(current);
-	if (retval)
-		goto fail_restore;
-	activate_context(current);
-	up(&mm->mmap_sem);
-	mm_release();
-	mmput(old_mm);
-	return 0;
-
-	/*
-	 * Failure ... restore the prior mm_struct.
-	 */
-fail_restore:
-	current->mm = old_mm;
-	/* restore the ldt for this task */
-	copy_segments(nr, current, NULL);
-	release_segments(mm);
-	kmem_cache_free(mm_cachep, mm);
-
-fail_nomem:
-	return retval;
+	if (mm) {
+		mm->cpu_vm_mask = (1UL << smp_processor_id());
+		mm->total_vm = 0;
+		mm->rss = 0;
+		mm->pgd = pgd_alloc();
+		if (mm->pgd) {
+			struct mm_struct *active_mm = current->active_mm;
+
+			current->mm = mm;
+			current->active_mm = mm;
+			SET_PAGE_DIR(current, mm->pgd);
+			activate_context(current);
+			mm_release();
+			if (old_mm) {
+				mmput(old_mm);
+				return 0;
+			}
+			mmdrop(active_mm);
+			return 0;
+		}
+		kmem_cache_free(mm_cachep, mm);
+	}
+	return -ENOMEM;
 }
 
 /*
@@ -632,7 +619,7 @@
 	if (id_change || cap_raised) {
 		/* We can't suid-execute if we're sharing parts of the executable */
 		/* or if we're being traced (or if suid execs are not allowed)    */
-		/* (current->mm->count > 1 is ok, as we'll get a new mm anyway)   */
+		/* (current->mm->mm_users > 1 is ok, as we'll get a new mm anyway)   */
 		if (IS_NOSUID(inode)
 		    || must_not_trace_exec(current)
 		    || (atomic_read(&current->fs->count) > 1)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)