summaryrefslogtreecommitdiff
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <greg@kroah.com>2004-10-18 18:03:51 -0700
committerGreg Kroah-Hartman <greg@kroah.com>2004-10-18 18:03:51 -0700
commitbffe01870598b7a0a77073e25ee94e026bc98e6b (patch)
treef5f5b65fec1239b18a4c2634807ff5d7e5729de9 /kernel/fork.c
parent23aebb6f8755121394ef088d84a7fa483b444aa9 (diff)
parenta4946826c30c56a5830326552a395c5b6afc13ef (diff)
merge
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 8c7ba481c9a5..3020dccc548f 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -86,7 +86,7 @@ EXPORT_SYMBOL(free_task);
void __put_task_struct(struct task_struct *tsk)
{
- WARN_ON(!(tsk->state & (TASK_DEAD | TASK_ZOMBIE)));
+ WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
WARN_ON(atomic_read(&tsk->usage));
WARN_ON(tsk == current);
@@ -249,8 +249,8 @@ void __init fork_init(unsigned long mempages)
if(max_threads < 20)
max_threads = 20;
- init_task.rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
- init_task.rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
+ init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
+ init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
}
static struct task_struct *dup_task_struct(struct task_struct *orig)
@@ -762,8 +762,17 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
for (i = open_files; i != 0; i--) {
struct file *f = *old_fds++;
- if (f)
+ if (f) {
get_file(f);
+ } else {
+ /*
+ * The fd may be claimed in the fd bitmap but not yet
+ * instantiated in the files array if a sibling thread
+ * is partway through open(). So make sure that this
+ * fd is available to the new process.
+ */
+ FD_CLR(open_files - i, newf->open_fds);
+ }
*new_fds++ = f;
}
spin_unlock(&oldf->file_lock);
@@ -872,6 +881,10 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
+ task_lock(current->group_leader);
+ memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
+ task_unlock(current->group_leader);
+
return 0;
}
@@ -941,7 +954,7 @@ static task_t *copy_process(unsigned long clone_flags,
retval = -EAGAIN;
if (atomic_read(&p->user->processes) >=
- p->rlim[RLIMIT_NPROC].rlim_cur) {
+ p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
p->user != &root_user)
goto bad_fork_free;
@@ -992,7 +1005,7 @@ static task_t *copy_process(unsigned long clone_flags,
p->utime = p->stime = 0;
p->lock_depth = -1; /* -1 = no lock */
- p->start_time = get_jiffies_64();
+ do_posix_clock_monotonic_gettime(&p->start_time);
p->security = NULL;
p->io_context = NULL;
p->io_wait = NULL;
@@ -1049,6 +1062,7 @@ static task_t *copy_process(unsigned long clone_flags,
/* ok, now we should be set up.. */
p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL);
p->pdeath_signal = 0;
+ p->exit_state = 0;
/* Perform scheduler related setup */
sched_fork(p);
@@ -1146,7 +1160,8 @@ fork_out:
bad_fork_cleanup_namespace:
exit_namespace(p);
bad_fork_cleanup_mm:
- mmput(p->mm);
+ if (p->mm)
+ mmput(p->mm);
bad_fork_cleanup_signal:
exit_signal(p);
bad_fork_cleanup_sighand: