aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c43
1 files changed, 28 insertions, 15 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index bab34192799..f252784f933 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -973,7 +973,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
973 unsigned long stack_start, 973 unsigned long stack_start,
974 struct pt_regs *regs, 974 struct pt_regs *regs,
975 unsigned long stack_size, 975 unsigned long stack_size,
976 int __user *parent_tidptr,
977 int __user *child_tidptr, 976 int __user *child_tidptr,
978 struct pid *pid) 977 struct pid *pid)
979{ 978{
@@ -1043,11 +1042,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1043 p->did_exec = 0; 1042 p->did_exec = 0;
1044 delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ 1043 delayacct_tsk_init(p); /* Must remain after dup_task_struct() */
1045 copy_flags(clone_flags, p); 1044 copy_flags(clone_flags, p);
1046 retval = -EFAULT;
1047 if (clone_flags & CLONE_PARENT_SETTID)
1048 if (put_user(p->pid, parent_tidptr))
1049 goto bad_fork_cleanup_delays_binfmt;
1050
1051 INIT_LIST_HEAD(&p->children); 1045 INIT_LIST_HEAD(&p->children);
1052 INIT_LIST_HEAD(&p->sibling); 1046 INIT_LIST_HEAD(&p->sibling);
1053 p->vfork_done = NULL; 1047 p->vfork_done = NULL;
@@ -1289,11 +1283,22 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1289 __ptrace_link(p, current->parent); 1283 __ptrace_link(p, current->parent);
1290 1284
1291 if (thread_group_leader(p)) { 1285 if (thread_group_leader(p)) {
1292 p->signal->tty = current->signal->tty; 1286 if (clone_flags & CLONE_NEWPID) {
1293 p->signal->pgrp = task_pgrp_nr(current); 1287 p->nsproxy->pid_ns->child_reaper = p;
1294 set_task_session(p, task_session_nr(current)); 1288 p->signal->tty = NULL;
1295 attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); 1289 p->signal->pgrp = p->pid;
1296 attach_pid(p, PIDTYPE_SID, task_session(current)); 1290 set_task_session(p, p->pid);
1291 attach_pid(p, PIDTYPE_PGID, pid);
1292 attach_pid(p, PIDTYPE_SID, pid);
1293 } else {
1294 p->signal->tty = current->signal->tty;
1295 p->signal->pgrp = task_pgrp_nr(current);
1296 set_task_session(p, task_session_nr(current));
1297 attach_pid(p, PIDTYPE_PGID,
1298 task_pgrp(current));
1299 attach_pid(p, PIDTYPE_SID,
1300 task_session(current));
1301 }
1297 1302
1298 list_add_tail_rcu(&p->tasks, &init_task.tasks); 1303 list_add_tail_rcu(&p->tasks, &init_task.tasks);
1299 __get_cpu_var(process_counts)++; 1304 __get_cpu_var(process_counts)++;
@@ -1339,7 +1344,6 @@ bad_fork_cleanup_policy:
1339bad_fork_cleanup_cgroup: 1344bad_fork_cleanup_cgroup:
1340#endif 1345#endif
1341 cgroup_exit(p, cgroup_callbacks_done); 1346 cgroup_exit(p, cgroup_callbacks_done);
1342bad_fork_cleanup_delays_binfmt:
1343 delayacct_tsk_free(p); 1347 delayacct_tsk_free(p);
1344 if (p->binfmt) 1348 if (p->binfmt)
1345 module_put(p->binfmt->module); 1349 module_put(p->binfmt->module);
@@ -1366,7 +1370,7 @@ struct task_struct * __cpuinit fork_idle(int cpu)
1366 struct task_struct *task; 1370 struct task_struct *task;
1367 struct pt_regs regs; 1371 struct pt_regs regs;
1368 1372
1369 task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL, 1373 task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
1370 &init_struct_pid); 1374 &init_struct_pid);
1371 if (!IS_ERR(task)) 1375 if (!IS_ERR(task))
1372 init_idle(task, cpu); 1376 init_idle(task, cpu);
@@ -1414,7 +1418,7 @@ long do_fork(unsigned long clone_flags,
1414 } 1418 }
1415 1419
1416 p = copy_process(clone_flags, stack_start, regs, stack_size, 1420 p = copy_process(clone_flags, stack_start, regs, stack_size,
1417 parent_tidptr, child_tidptr, NULL); 1421 child_tidptr, NULL);
1418 /* 1422 /*
1419 * Do this prior waking up the new thread - the thread pointer 1423 * Do this prior waking up the new thread - the thread pointer
1420 * might get invalid after that point, if the thread exits quickly. 1424 * might get invalid after that point, if the thread exits quickly.
@@ -1422,7 +1426,16 @@ long do_fork(unsigned long clone_flags,
1422 if (!IS_ERR(p)) { 1426 if (!IS_ERR(p)) {
1423 struct completion vfork; 1427 struct completion vfork;
1424 1428
1425 nr = pid_nr(task_pid(p)); 1429 /*
1430 * this is enough to call pid_nr_ns here, but this if
1431 * improves optimisation of regular fork()
1432 */
1433 nr = (clone_flags & CLONE_NEWPID) ?
1434 task_pid_nr_ns(p, current->nsproxy->pid_ns) :
1435 task_pid_vnr(p);
1436
1437 if (clone_flags & CLONE_PARENT_SETTID)
1438 put_user(nr, parent_tidptr);
1426 1439
1427 if (clone_flags & CLONE_VFORK) { 1440 if (clone_flags & CLONE_VFORK) {
1428 p->vfork_done = &vfork; 1441 p->vfork_done = &vfork;