summaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
commit230e5ab6a084ed50470f101934782dbf54b0d06b (patch)
tree5dd821c8d33f450470588e7a543f74bf74306e9e /kernel/fork.c
parentc9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff)
Merge with Linux 2.1.67.
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 4974d5dac..116e02786 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -208,7 +208,6 @@ static inline int dup_mmap(struct mm_struct * mm)
struct vm_area_struct * mpnt, *tmp, **pprev;
int retval;
- mm->mmap = mm->mmap_cache = NULL;
flush_cache_mm(current->mm);
pprev = &mm->mmap;
for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
@@ -254,8 +253,7 @@ static inline int dup_mmap(struct mm_struct * mm)
if (retval)
goto fail_nomem;
}
- flush_tlb_mm(current->mm);
- return 0;
+ retval = 0;
fail_nomem:
flush_tlb_mm(current->mm);
@@ -276,7 +274,10 @@ struct mm_struct * mm_alloc(void)
mm->count = 1;
mm->def_flags = 0;
mm->mmap_sem = MUTEX;
- mm->pgd = NULL;
+ /*
+ * Leave mm->pgd set to the parent's pgd
+ * so that pgd_offset() is always valid.
+ */
mm->mmap = mm->mmap_cache = NULL;
/* It has not run yet, so cannot be present in anyone's
@@ -324,10 +325,12 @@ static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
goto free_mm;
retval = dup_mmap(mm);
if (retval)
- goto free_mm;
+ goto free_pt;
return 0;
free_mm:
+ mm->pgd = NULL;
+free_pt:
tsk->mm = NULL;
mmput(mm);
fail_nomem:
@@ -376,7 +379,13 @@ static inline int copy_files(unsigned long clone_flags, struct task_struct * tsk
struct files_struct *oldf, *newf;
struct file **old_fds, **new_fds;
+ /*
+ * A background process may not have any files ...
+ */
oldf = current->files;
+ if (!oldf)
+ return 0;
+
if (clone_flags & CLONE_FILES) {
oldf->count++;
return 0;
@@ -497,6 +506,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
/* ok, now we should be set up.. */
p->swappable = 1;
p->exit_signal = clone_flags & CSIGNAL;
+ p->pdeath_signal = 0;
/*
* "share" dynamic priority between parent and child, thus the
@@ -515,7 +525,9 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
}
++total_forks;
error = p->pid;
- goto fork_out;
+bad_fork:
+ unlock_kernel();
+ return error;
bad_fork_cleanup_sighand:
exit_sighand(p);
@@ -535,10 +547,7 @@ bad_fork_cleanup:
nr_tasks--;
bad_fork_free:
free_task_struct(p);
-bad_fork:
-fork_out:
- unlock_kernel();
- return error;
+ goto bad_fork;
}
static void files_ctor(void *fp, kmem_cache_t *cachep, unsigned long flags)