Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932336Ab0FPQde (ORCPT ); Wed, 16 Jun 2010 12:33:34 -0400 Received: from 101-97.80-90.static-ip.oleane.fr ([90.80.97.101]:42301 "EHLO bohort.kerlabs.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932139Ab0FPQdd (ORCPT ); Wed, 16 Jun 2010 12:33:33 -0400 From: Louis Rilling To: Andrew Morton Cc: Oleg Nesterov , Pavel Emelyanov , Linux Containers , linux-kernel@vger.kernel.org, Louis Rilling Subject: [PATCH] procfs: Do not release pid_ns->proc_mnt too early Date: Wed, 16 Jun 2010 18:34:28 +0200 Message-Id: <1276706068-18567-1-git-send-email-louis.rilling@kerlabs.com> X-Mailer: git-send-email 1.5.6.5 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3001 Lines: 94 [ Resending, hopefully with all pieces ] Detached tasks are not seen by zap_pid_ns_processes()->sys_wait4(), so that release_task()->proc_flush_task() of container init can be called before it is for some detached tasks in the namespace. Pin proc_mnt's in copy_process(), so that proc_flush_task() becomes safe whatever the ordering of tasks. Signed-off-by: Louis Rilling --- fs/proc/base.c | 18 ++++++++++++++++++ include/linux/proc_fs.h | 4 ++++ kernel/fork.c | 1 + 3 files changed, 23 insertions(+), 0 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index acb7ef8..d6cdd91 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2663,6 +2663,23 @@ static const struct inode_operations proc_tgid_base_inode_operations = { .setattr = proc_setattr, }; +/* + * Pin all proc_mnt so that detached tasks can safely call proc_flush_task() + * after container init calls itself proc_flush_task(). + */ +void proc_new_task(struct task_struct *task) +{ + struct pid *pid; + int i; + + if (!task->pid) + return; + + pid = task_pid(task); + for (i = 0; i <= pid->level; i++) + mntget(pid->numbers[i].ns->proc_mnt); +} + static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) { struct dentry *dentry, *leader, *dir; @@ -2744,6 +2761,7 @@ void proc_flush_task(struct task_struct *task) upid = &pid->numbers[i]; proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, tgid->numbers[i].nr); + mntput(upid->ns->proc_mnt); } upid = &pid->numbers[pid->level]; diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 379eaed..f24faa1 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -104,6 +104,7 @@ struct vmcore { extern void proc_root_init(void); +void proc_new_task(struct task_struct *task); void proc_flush_task(struct task_struct *task); extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, @@ -184,6 +185,9 @@ extern void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm); #define proc_net_fops_create(net, name, mode, fops) ({ (void)(mode), NULL; }) static inline void proc_net_remove(struct net *net, const char *name) {} +static inline void proc_new_task(struct task_struct *task) +{ +} static inline void proc_flush_task(struct task_struct *task) { } diff --git a/kernel/fork.c b/kernel/fork.c index b6cce14..c6c2874 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1281,6 +1281,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, total_forks++; spin_unlock(¤t->sighand->siglock); write_unlock_irq(&tasklist_lock); + proc_new_task(p); proc_fork_connector(p); cgroup_post_fork(p); perf_event_fork(p); -- 1.5.6.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/