aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-09-27 04:51:06 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-27 11:26:19 -0400
commitc18258c6f0848f97e85287f6271c511a092bb784 (patch)
tree16c057a171b7623895ee208459392c1104193b84 /fs/exec.c
parent35fa2048ab13d1be846be612e395c15c200bd51c (diff)
[PATCH] pid: Implement transfer_pid and use it to simplify de_thread
In de_thread we move pids from one process to another, a rather ugly case. The function transfer_pid makes it clear what we are doing, and makes the action atomic. This is useful we ever want to atomically traverse the process group and session lists, in a rcu safe manner. Even if the atomic properties this change should be a win as transfer_pid should be less code to execute than executing both attach_pid and detach_pid, and this should make de_thread slightly smaller as only a single function call needs to be emitted. The only downside is that the code might be slower to execute as the odds are against transfer_pid being in cache. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 54135df2a966..b7aa3d6422d6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -696,23 +696,20 @@ static int de_thread(struct task_struct *tsk)
696 */ 696 */
697 697
698 /* Become a process group leader with the old leader's pid. 698 /* Become a process group leader with the old leader's pid.
699 * Note: The old leader also uses thispid until release_task 699 * The old leader becomes a thread of the this thread group.
700 * Note: The old leader also uses this pid until release_task
700 * is called. Odd but simple and correct. 701 * is called. Odd but simple and correct.
701 */ 702 */
702 detach_pid(current, PIDTYPE_PID); 703 detach_pid(current, PIDTYPE_PID);
703 current->pid = leader->pid; 704 current->pid = leader->pid;
704 attach_pid(current, PIDTYPE_PID, current->pid); 705 attach_pid(current, PIDTYPE_PID, current->pid);
705 attach_pid(current, PIDTYPE_PGID, current->signal->pgrp); 706 transfer_pid(leader, current, PIDTYPE_PGID);
706 attach_pid(current, PIDTYPE_SID, current->signal->session); 707 transfer_pid(leader, current, PIDTYPE_SID);
707 list_replace_rcu(&leader->tasks, &current->tasks); 708 list_replace_rcu(&leader->tasks, &current->tasks);
708 709
709 current->group_leader = current; 710 current->group_leader = current;
710 leader->group_leader = current; 711 leader->group_leader = current;
711 712
712 /* Reduce leader to a thread */
713 detach_pid(leader, PIDTYPE_PGID);
714 detach_pid(leader, PIDTYPE_SID);
715
716 current->exit_signal = SIGCHLD; 713 current->exit_signal = SIGCHLD;
717 714
718 BUG_ON(leader->exit_state != EXIT_ZOMBIE); 715 BUG_ON(leader->exit_state != EXIT_ZOMBIE);