From 33084fd5d6b205629a4b3079fbf0255e6c84c06a Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 18 Oct 2007 23:40:11 -0700 Subject: [PATCH] --- yaml --- r: 71455 b: refs/heads/master c: 6f4e643353aea52d80f33960bd88954a7c074f0f h: refs/heads/master i: 71453: a4cbfda21b394749edada27217c3529811d01f02 71451: f5585ecdeda31a6bf0c9b628f28a929f312209ab 71447: ea78ba426bd015b9e6d6799acaf534895fdbc4ad 71439: a271650e8c7ea2921e7554cd6673c48955699438 71423: a710eead3e4a1db4396808cb73ebd33d27d7f1a9 v: v3 --- [refs] | 2 +- trunk/fs/proc/base.c | 4 ++++ trunk/fs/proc/root.c | 16 ++++++++++++++++ trunk/include/linux/proc_fs.h | 12 ++++++++++++ trunk/kernel/fork.c | 7 +++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 4eaa7d5dc2a7..e0cbbcab975d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 130f77ecb2e7d5ac3e53e620f55e374f4a406b20 +refs/heads/master: 6f4e643353aea52d80f33960bd88954a7c074f0f diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 5e0c6a1ce8b3..21510c9aa89c 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -2275,6 +2275,10 @@ void proc_flush_task(struct task_struct *task) proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, leader ? 0 : tgid->numbers[i].nr); } + + upid = &pid->numbers[pid->level]; + if (upid->nr == 1) + pid_ns_release_proc(upid->ns); } static struct dentry *proc_pid_instantiate(struct inode *dir, diff --git a/trunk/fs/proc/root.c b/trunk/fs/proc/root.c index 94e9d734384e..ec9cb3b6c93b 100644 --- a/trunk/fs/proc/root.c +++ b/trunk/fs/proc/root.c @@ -212,6 +212,22 @@ struct proc_dir_entry proc_root = { .parent = &proc_root, }; +int pid_ns_prepare_proc(struct pid_namespace *ns) +{ + struct vfsmount *mnt; + + mnt = kern_mount_data(&proc_fs_type, ns); + if (IS_ERR(mnt)) + return PTR_ERR(mnt); + + return 0; +} + +void pid_ns_release_proc(struct pid_namespace *ns) +{ + mntput(ns->proc_mnt); +} + EXPORT_SYMBOL(proc_symlink); EXPORT_SYMBOL(proc_mkdir); EXPORT_SYMBOL(create_proc_entry); diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index cbc1038c7900..1ff461672060 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -143,6 +143,9 @@ extern const struct file_operations proc_kcore_operations; extern const struct file_operations proc_kmsg_operations; extern const struct file_operations ppc_htab_operations; +extern int pid_ns_prepare_proc(struct pid_namespace *ns); +extern void pid_ns_release_proc(struct pid_namespace *ns); + /* * proc_tty.c */ @@ -235,6 +238,15 @@ static inline void proc_tty_unregister_driver(struct tty_driver *driver) {}; extern struct proc_dir_entry proc_root; +static inline int pid_ns_prepare_proc(struct pid_namespace *ns) +{ + return 0; +} + +static inline void pid_ns_release_proc(struct pid_namespace *ns) +{ +} + #endif /* CONFIG_PROC_FS */ #if !defined(CONFIG_PROC_KCORE) diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index f252784f9330..ce9297e4e7d4 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -1150,6 +1151,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, pid = alloc_pid(task_active_pid_ns(p)); if (!pid) goto bad_fork_cleanup_namespaces; + + if (clone_flags & CLONE_NEWPID) { + retval = pid_ns_prepare_proc(task_active_pid_ns(p)); + if (retval < 0) + goto bad_fork_free_pid; + } } p->pid = pid_nr(pid);