From 0ecc833bac594099505a090cbca6ccd5b83d5975 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 29 Mar 2013 12:23:28 -0400 Subject: mode_t, whack-a-mole at 11... Signed-off-by: Al Viro --- fs/proc/self.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/proc/self.c') diff --git a/fs/proc/self.c b/fs/proc/self.c index aa5cc3bff140..d8a025296613 100644 --- a/fs/proc/self.c +++ b/fs/proc/self.c @@ -51,7 +51,7 @@ static const struct inode_operations proc_self_inode_operations = { void __init proc_self_init(void) { struct proc_dir_entry *proc_self_symlink; - mode_t mode; + umode_t mode; mode = S_IFLNK | S_IRWXUGO; proc_self_symlink = proc_create("self", mode, NULL, NULL ); -- cgit v1.2.3 From 021ada7dff22d0d9540ff596cb0f8bb866755ee1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 29 Mar 2013 19:27:05 -0400 Subject: procfs: switch /proc/self away from proc_dir_entry Just have it pinned in dcache all along and let procfs ->kill_sb() drop it before kill_anon_super(). Signed-off-by: Al Viro --- fs/proc/base.c | 16 +++++++++++---- fs/proc/inode.c | 2 +- fs/proc/internal.h | 1 + fs/proc/root.c | 2 ++ fs/proc/self.c | 46 ++++++++++++++++++++++++++++++++++++------- include/linux/pid_namespace.h | 1 + 6 files changed, 56 insertions(+), 12 deletions(-) (limited to 'fs/proc/self.c') diff --git a/fs/proc/base.c b/fs/proc/base.c index 69078c7cef1f..593e7c5ddb49 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2794,7 +2794,7 @@ retry: return iter; } -#define TGID_OFFSET (FIRST_PROCESS_ENTRY) +#define TGID_OFFSET (FIRST_PROCESS_ENTRY + 1) static int proc_pid_fill_cache(struct file *filp, void *dirent, filldir_t filldir, struct tgid_iter iter) @@ -2817,13 +2817,21 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) struct tgid_iter iter; struct pid_namespace *ns; filldir_t __filldir; + loff_t pos = filp->f_pos; - if (filp->f_pos >= PID_MAX_LIMIT + TGID_OFFSET) + if (pos >= PID_MAX_LIMIT + TGID_OFFSET) goto out; - ns = filp->f_dentry->d_sb->s_fs_info; + if (pos == TGID_OFFSET - 1) { + if (proc_fill_cache(filp, dirent, filldir, "self", 4, + NULL, NULL, NULL) < 0) + goto out; + iter.tgid = 0; + } else { + iter.tgid = pos - TGID_OFFSET; + } iter.task = NULL; - iter.tgid = filp->f_pos - TGID_OFFSET; + ns = filp->f_dentry->d_sb->s_fs_info; for (iter = next_tgid(ns, iter); iter.task; iter.tgid += 1, iter = next_tgid(ns, iter)) { diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 869116c2afbe..908e97457319 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -506,5 +506,5 @@ int proc_fill_super(struct super_block *s) return -ENOMEM; } - return 0; + return proc_setup_self(s); } diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 85ff3a4598b3..9c93a53f371d 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -205,3 +205,4 @@ int proc_setattr(struct dentry *dentry, struct iattr *attr); extern const struct inode_operations proc_ns_dir_inode_operations; extern const struct file_operations proc_ns_dir_operations; +extern int proc_setup_self(struct super_block *); diff --git a/fs/proc/root.c b/fs/proc/root.c index c6e9fac26bac..20834b3c8ea3 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -137,6 +137,8 @@ static void proc_kill_sb(struct super_block *sb) struct pid_namespace *ns; ns = (struct pid_namespace *)sb->s_fs_info; + if (ns->proc_self) + dput(ns->proc_self); kill_anon_super(sb); put_pid_ns(ns); } diff --git a/fs/proc/self.c b/fs/proc/self.c index d8a025296613..21940d89977e 100644 --- a/fs/proc/self.c +++ b/fs/proc/self.c @@ -1,6 +1,7 @@ -#include #include #include +#include +#include "internal.h" /* * /proc/self: @@ -48,12 +49,43 @@ static const struct inode_operations proc_self_inode_operations = { .put_link = proc_self_put_link, }; -void __init proc_self_init(void) +static unsigned self_inum; + +int proc_setup_self(struct super_block *s) { - struct proc_dir_entry *proc_self_symlink; - umode_t mode; + struct inode *root_inode = s->s_root->d_inode; + struct pid_namespace *ns = s->s_fs_info; + struct dentry *self; + + mutex_lock(&root_inode->i_mutex); + self = d_alloc_name(s->s_root, "self"); + if (self) { + struct inode *inode = new_inode_pseudo(s); + if (inode) { + inode->i_ino = self_inum; + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mode = S_IFLNK | S_IRWXUGO; + inode->i_uid = GLOBAL_ROOT_UID; + inode->i_gid = GLOBAL_ROOT_GID; + inode->i_op = &proc_self_inode_operations; + d_add(self, inode); + } else { + dput(self); + self = ERR_PTR(-ENOMEM); + } + } else { + self = ERR_PTR(-ENOMEM); + } + mutex_unlock(&root_inode->i_mutex); + if (IS_ERR(self)) { + pr_err("proc_fill_super: can't allocate /proc/self\n"); + return PTR_ERR(self); + } + ns->proc_self = self; + return 0; +} - mode = S_IFLNK | S_IRWXUGO; - proc_self_symlink = proc_create("self", mode, NULL, NULL ); - proc_self_symlink->proc_iops = &proc_self_inode_operations; +void __init proc_self_init(void) +{ + proc_alloc_inum(&self_inum); } diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index 215e5e3dda10..5524f8cfa950 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h @@ -28,6 +28,7 @@ struct pid_namespace { struct pid_namespace *parent; #ifdef CONFIG_PROC_FS struct vfsmount *proc_mnt; + struct dentry *proc_self; #endif #ifdef CONFIG_BSD_PROCESS_ACCT struct bsd_acct_struct *bacct; -- cgit v1.2.3 From 0d01ff2583086fd532181d2ee16112f5342eb78d Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 11 Apr 2013 23:51:01 +0100 Subject: Include missing linux/slab.h inclusions Include missing linux/slab.h inclusions where the source file is currently expecting to get kmalloc() and co. through linux/proc_fs.h. Signed-off-by: David Howells Acked-by: Greg Kroah-Hartman cc: linux-s390@vger.kernel.org cc: sparclinux@vger.kernel.org cc: linux-efi@vger.kernel.org cc: linux-mtd@lists.infradead.org cc: devel@driverdev.osuosl.org cc: x86@kernel.org Signed-off-by: Al Viro --- arch/s390/kernel/os_info.c | 1 + arch/sparc/kernel/sun4d_irq.c | 1 + arch/x86/platform/efi/efi.c | 1 + arch/x86/platform/efi/efi_64.c | 1 + drivers/mtd/mtdcore.c | 1 + drivers/pps/clients/pps_parport.c | 1 + drivers/staging/dgrp/dgrp_dpa_ops.c | 1 + drivers/staging/dgrp/dgrp_mon_ops.c | 1 + drivers/staging/dgrp/dgrp_net_ops.c | 2 +- drivers/staging/dgrp/dgrp_specproc.c | 1 + fs/proc/self.c | 1 + 11 files changed, 11 insertions(+), 1 deletion(-) (limited to 'fs/proc/self.c') diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index 46480d81df00..d112fc66f993 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index e490ac9327c7..f8933be3ca8b 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -6,6 +6,7 @@ */ #include +#include #include #include diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 5f2ecaf3f9d8..55ea7dfb5b3c 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 2b2003860615..39a0e7f1f0a3 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 61d5f56473e1..322ca65b0cc5 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c index e1b4705ae3ec..38a8bbe74810 100644 --- a/drivers/pps/clients/pps_parport.c +++ b/drivers/pps/clients/pps_parport.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/dgrp/dgrp_dpa_ops.c b/drivers/staging/dgrp/dgrp_dpa_ops.c index 43209c163a43..1fc13de4bdd6 100644 --- a/drivers/staging/dgrp/dgrp_dpa_ops.c +++ b/drivers/staging/dgrp/dgrp_dpa_ops.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "dgrp_common.h" diff --git a/drivers/staging/dgrp/dgrp_mon_ops.c b/drivers/staging/dgrp/dgrp_mon_ops.c index 6edbbf069150..d18be4180e3b 100644 --- a/drivers/staging/dgrp/dgrp_mon_ops.c +++ b/drivers/staging/dgrp/dgrp_mon_ops.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/dgrp/dgrp_net_ops.c b/drivers/staging/dgrp/dgrp_net_ops.c index 5448fc78bcad..9914f1c5bcd3 100644 --- a/drivers/staging/dgrp/dgrp_net_ops.c +++ b/drivers/staging/dgrp/dgrp_net_ops.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/staging/dgrp/dgrp_specproc.c b/drivers/staging/dgrp/dgrp_specproc.c index b990b2686ba9..205d80ef4455 100644 --- a/drivers/staging/dgrp/dgrp_specproc.c +++ b/drivers/staging/dgrp/dgrp_specproc.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/fs/proc/self.c b/fs/proc/self.c index 21940d89977e..6b6a993b5c25 100644 --- a/fs/proc/self.c +++ b/fs/proc/self.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "internal.h" -- cgit v1.2.3