|
@@ -973,7 +973,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|
|
unsigned long stack_start,
|
|
|
struct pt_regs *regs,
|
|
|
unsigned long stack_size,
|
|
|
- int __user *parent_tidptr,
|
|
|
int __user *child_tidptr,
|
|
|
struct pid *pid)
|
|
|
{
|
|
@@ -1043,11 +1042,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|
|
p->did_exec = 0;
|
|
|
delayacct_tsk_init(p); /* Must remain after dup_task_struct() */
|
|
|
copy_flags(clone_flags, p);
|
|
|
- retval = -EFAULT;
|
|
|
- if (clone_flags & CLONE_PARENT_SETTID)
|
|
|
- if (put_user(p->pid, parent_tidptr))
|
|
|
- goto bad_fork_cleanup_delays_binfmt;
|
|
|
-
|
|
|
INIT_LIST_HEAD(&p->children);
|
|
|
INIT_LIST_HEAD(&p->sibling);
|
|
|
p->vfork_done = NULL;
|
|
@@ -1289,11 +1283,22 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
|
|
__ptrace_link(p, current->parent);
|
|
|
|
|
|
if (thread_group_leader(p)) {
|
|
|
- p->signal->tty = current->signal->tty;
|
|
|
- p->signal->pgrp = task_pgrp_nr(current);
|
|
|
- set_task_session(p, task_session_nr(current));
|
|
|
- attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
|
|
|
- attach_pid(p, PIDTYPE_SID, task_session(current));
|
|
|
+ if (clone_flags & CLONE_NEWPID) {
|
|
|
+ p->nsproxy->pid_ns->child_reaper = p;
|
|
|
+ p->signal->tty = NULL;
|
|
|
+ p->signal->pgrp = p->pid;
|
|
|
+ set_task_session(p, p->pid);
|
|
|
+ attach_pid(p, PIDTYPE_PGID, pid);
|
|
|
+ attach_pid(p, PIDTYPE_SID, pid);
|
|
|
+ } else {
|
|
|
+ p->signal->tty = current->signal->tty;
|
|
|
+ p->signal->pgrp = task_pgrp_nr(current);
|
|
|
+ set_task_session(p, task_session_nr(current));
|
|
|
+ attach_pid(p, PIDTYPE_PGID,
|
|
|
+ task_pgrp(current));
|
|
|
+ attach_pid(p, PIDTYPE_SID,
|
|
|
+ task_session(current));
|
|
|
+ }
|
|
|
|
|
|
list_add_tail_rcu(&p->tasks, &init_task.tasks);
|
|
|
__get_cpu_var(process_counts)++;
|
|
@@ -1339,7 +1344,6 @@ bad_fork_cleanup_policy:
|
|
|
bad_fork_cleanup_cgroup:
|
|
|
#endif
|
|
|
cgroup_exit(p, cgroup_callbacks_done);
|
|
|
-bad_fork_cleanup_delays_binfmt:
|
|
|
delayacct_tsk_free(p);
|
|
|
if (p->binfmt)
|
|
|
module_put(p->binfmt->module);
|
|
@@ -1366,7 +1370,7 @@ struct task_struct * __cpuinit fork_idle(int cpu)
|
|
|
struct task_struct *task;
|
|
|
struct pt_regs regs;
|
|
|
|
|
|
- task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, NULL,
|
|
|
+ task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL,
|
|
|
&init_struct_pid);
|
|
|
if (!IS_ERR(task))
|
|
|
init_idle(task, cpu);
|
|
@@ -1414,7 +1418,7 @@ long do_fork(unsigned long clone_flags,
|
|
|
}
|
|
|
|
|
|
p = copy_process(clone_flags, stack_start, regs, stack_size,
|
|
|
- parent_tidptr, child_tidptr, NULL);
|
|
|
+ child_tidptr, NULL);
|
|
|
/*
|
|
|
* Do this prior waking up the new thread - the thread pointer
|
|
|
* might get invalid after that point, if the thread exits quickly.
|
|
@@ -1422,7 +1426,16 @@ long do_fork(unsigned long clone_flags,
|
|
|
if (!IS_ERR(p)) {
|
|
|
struct completion vfork;
|
|
|
|
|
|
- nr = pid_nr(task_pid(p));
|
|
|
+ /*
|
|
|
+ * this is enough to call pid_nr_ns here, but this if
|
|
|
+ * improves optimisation of regular fork()
|
|
|
+ */
|
|
|
+ nr = (clone_flags & CLONE_NEWPID) ?
|
|
|
+ task_pid_nr_ns(p, current->nsproxy->pid_ns) :
|
|
|
+ task_pid_vnr(p);
|
|
|
+
|
|
|
+ if (clone_flags & CLONE_PARENT_SETTID)
|
|
|
+ put_user(nr, parent_tidptr);
|
|
|
|
|
|
if (clone_flags & CLONE_VFORK) {
|
|
|
p->vfork_done = &vfork;
|