proc: seqfile convert proc_pid_status to properly handle pid namespaces
[powerpc.git] / fs / proc / base.c
index c59852b..8a19a8a 100644 (file)
@@ -121,6 +121,10 @@ struct pid_entry {
        NOD(NAME, (S_IFREG|(MODE)),                     \
                NULL, &proc_info_file_operations,       \
                { .proc_read = &proc_##OTYPE } )
+#define ONE(NAME, MODE, OTYPE)                         \
+       NOD(NAME, (S_IFREG|(MODE)),                     \
+               NULL, &proc_single_file_operations,     \
+               { .proc_show = &proc_##OTYPE } )
 
 int maps_protect;
 EXPORT_SYMBOL(maps_protect);
@@ -658,6 +662,45 @@ static const struct file_operations proc_info_file_operations = {
        .read           = proc_info_read,
 };
 
+static int proc_single_show(struct seq_file *m, void *v)
+{
+       struct inode *inode = m->private;
+       struct pid_namespace *ns;
+       struct pid *pid;
+       struct task_struct *task;
+       int ret;
+
+       ns = inode->i_sb->s_fs_info;
+       pid = proc_pid(inode);
+       task = get_pid_task(pid, PIDTYPE_PID);
+       if (!task)
+               return -ESRCH;
+
+       ret = PROC_I(inode)->op.proc_show(m, ns, pid, task);
+
+       put_task_struct(task);
+       return ret;
+}
+
+static int proc_single_open(struct inode *inode, struct file *filp)
+{
+       int ret;
+       ret = single_open(filp, proc_single_show, NULL);
+       if (!ret) {
+               struct seq_file *m = filp->private_data;
+
+               m->private = inode;
+       }
+       return ret;
+}
+
+static const struct file_operations proc_single_file_operations = {
+       .open           = proc_single_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 static int mem_open(struct inode* inode, struct file* file)
 {
        file->private_data = (void*)((long)current->self_exec_id);
@@ -2231,14 +2274,14 @@ static const struct pid_entry tgid_base_stuff[] = {
        DIR("fdinfo",     S_IRUSR|S_IXUSR, fdinfo),
        REG("environ",    S_IRUSR, environ),
        INF("auxv",       S_IRUSR, pid_auxv),
-       INF("status",     S_IRUGO, pid_status),
+       ONE("status",     S_IRUGO, pid_status),
        INF("limits",     S_IRUSR, pid_limits),
 #ifdef CONFIG_SCHED_DEBUG
        REG("sched",      S_IRUGO|S_IWUSR, pid_sched),
 #endif
        INF("cmdline",    S_IRUGO, pid_cmdline),
-       INF("stat",       S_IRUGO, tgid_stat),
-       INF("statm",      S_IRUGO, pid_statm),
+       ONE("stat",       S_IRUGO, tgid_stat),
+       ONE("statm",      S_IRUGO, pid_statm),
        REG("maps",       S_IRUGO, maps),
 #ifdef CONFIG_NUMA
        REG("numa_maps",  S_IRUGO, numa_maps),
@@ -2562,14 +2605,14 @@ static const struct pid_entry tid_base_stuff[] = {
        DIR("fdinfo",    S_IRUSR|S_IXUSR, fdinfo),
        REG("environ",   S_IRUSR, environ),
        INF("auxv",      S_IRUSR, pid_auxv),
-       INF("status",    S_IRUGO, pid_status),
+       ONE("status",    S_IRUGO, pid_status),
        INF("limits",    S_IRUSR, pid_limits),
 #ifdef CONFIG_SCHED_DEBUG
        REG("sched",     S_IRUGO|S_IWUSR, pid_sched),
 #endif
        INF("cmdline",   S_IRUGO, pid_cmdline),
-       INF("stat",      S_IRUGO, tid_stat),
-       INF("statm",     S_IRUGO, pid_statm),
+       ONE("stat",      S_IRUGO, tid_stat),
+       ONE("statm",     S_IRUGO, pid_statm),
        REG("maps",      S_IRUGO, maps),
 #ifdef CONFIG_NUMA
        REG("numa_maps", S_IRUGO, numa_maps),