[RFC PATCH 5/5] proc: unify proc_pid_*maps* stuff

From: Oleg Nesterov
Date: Fri Aug 08 2014 - 15:00:53 EST


A single seq_operations/file_operations pair can handle maps, smaps,
and numa_maps files. Just the generic ->open() needs to look at
pid_entry_name() and initialize priv->show() accordingly.

Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx>
---
fs/proc/base.c | 8 ++--
fs/proc/internal.h | 3 +-
fs/proc/task_mmu.c | 123 +++++++++++++++++++++-------------------------------
3 files changed, 54 insertions(+), 80 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 81d372c..4018a86 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2585,7 +2585,7 @@ static const struct pid_entry tgid_base_stuff[] = {
ONE("statm", S_IRUGO, proc_pid_statm),
REG("maps", S_IRUGO, proc_pid_maps_operations),
#ifdef CONFIG_NUMA
- REG("numa_maps", S_IRUGO, proc_pid_numa_maps_operations),
+ REG("numa_maps", S_IRUGO, proc_pid_maps_operations),
#endif
REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
LNK("cwd", proc_cwd_link),
@@ -2596,7 +2596,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("mountstats", S_IRUSR, proc_mountstats_operations),
#ifdef CONFIG_PROC_PAGE_MONITOR
REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
- REG("smaps", S_IRUGO, proc_pid_smaps_operations),
+ REG("smaps", S_IRUGO, proc_pid_maps_operations),
REG("pagemap", S_IRUSR, proc_pagemap_operations),
#endif
#ifdef CONFIG_SECURITY
@@ -2924,7 +2924,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("children", S_IRUGO, proc_tid_children_operations),
#endif
#ifdef CONFIG_NUMA
- REG("numa_maps", S_IRUGO, proc_pid_numa_maps_operations),
+ REG("numa_maps", S_IRUGO, proc_pid_maps_operations),
#endif
REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
LNK("cwd", proc_cwd_link),
@@ -2934,7 +2934,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("mountinfo", S_IRUGO, proc_mountinfo_operations),
#ifdef CONFIG_PROC_PAGE_MONITOR
REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
- REG("smaps", S_IRUGO, proc_pid_smaps_operations),
+ REG("smaps", S_IRUGO, proc_pid_maps_operations),
REG("pagemap", S_IRUSR, proc_pagemap_operations),
#endif
#ifdef CONFIG_SECURITY
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index c162db2..17091c9 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -270,6 +270,7 @@ extern int proc_remount(struct super_block *, int *, char *);
struct proc_maps_private {
struct pid *pid;
bool is_tgid;
+ int (*show)(struct seq_file *m, void *v);
struct task_struct *task;
struct mm_struct *mm;
#ifdef CONFIG_MMU
@@ -283,8 +284,6 @@ struct proc_maps_private {
struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode);

extern const struct file_operations proc_pid_maps_operations;
-extern const struct file_operations proc_pid_numa_maps_operations;
-extern const struct file_operations proc_pid_smaps_operations;
extern const struct file_operations proc_clear_refs_operations;
extern const struct file_operations proc_pagemap_operations;

diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 7618ef8..4ef991a 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -222,26 +222,6 @@ static void m_stop(struct seq_file *m, void *v)
}
}

-static int proc_maps_open(struct inode *inode, struct file *file,
- const struct seq_operations *ops, int psize)
-{
- struct proc_maps_private *priv = __seq_open_private(file, ops, psize);
-
- if (!priv)
- return -ENOMEM;
-
- priv->pid = proc_pid(inode);
- priv->is_tgid = is_tgid_pid_entry(PROC_I(inode)->pid_entry);
- priv->mm = proc_mem_open(inode, PTRACE_MODE_READ);
- if (IS_ERR(priv->mm)) {
- int err = PTR_ERR(priv->mm);
- seq_release_private(inode, file);
- return err;
- }
-
- return 0;
-}
-
static int proc_map_release(struct inode *inode, struct file *file)
{
struct seq_file *seq = file->private_data;
@@ -352,30 +332,9 @@ done:
static int show_pid_map(struct seq_file *m, void *v)
{
show_map_vma(m, v);
- m_cache_vma(m, v);
return 0;
}

-static const struct seq_operations proc_pid_maps_op = {
- .start = m_start,
- .next = m_next,
- .stop = m_stop,
- .show = show_pid_map
-};
-
-static int pid_maps_open(struct inode *inode, struct file *file)
-{
- return proc_maps_open(inode, file, &proc_pid_maps_op,
- sizeof(struct proc_maps_private));
-}
-
-const struct file_operations proc_pid_maps_operations = {
- .open = pid_maps_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = proc_map_release,
-};
-
/*
* Proportional Set Size(PSS): my share of RSS.
*
@@ -602,30 +561,9 @@ static int show_pid_smap(struct seq_file *m, void *v)
mss.nonlinear >> 10);

show_smap_vma_flags(m, vma);
- m_cache_vma(m, vma);
return 0;
}

-static const struct seq_operations proc_pid_smaps_op = {
- .start = m_start,
- .next = m_next,
- .stop = m_stop,
- .show = show_pid_smap
-};
-
-static int pid_smaps_open(struct inode *inode, struct file *file)
-{
- return proc_maps_open(inode, file, &proc_pid_smaps_op,
- sizeof(struct proc_maps_private));
-}
-
-const struct file_operations proc_pid_smaps_operations = {
- .open = pid_smaps_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = proc_map_release,
-};
-
/*
* We do not want to have constant page-shift bits sitting in
* pagemap entries and are about to reuse them some time soon.
@@ -1406,27 +1344,64 @@ static int show_pid_numa_map(struct seq_file *m, void *v)
seq_printf(m, " N%d=%lu", nid, md->node[nid]);
out:
seq_putc(m, '\n');
- m_cache_vma(m, vma);
return 0;
}
+#endif /* CONFIG_NUMA */

-static const struct seq_operations proc_pid_numa_maps_op = {
- .start = m_start,
- .next = m_next,
- .stop = m_stop,
- .show = show_pid_numa_map,
+static int m_show(struct seq_file *m, void *v)
+{
+ struct proc_maps_private *priv = m->private;
+ priv->show(m, v);
+ m_cache_vma(m, v);
+ return 0;
+}
+
+static const struct seq_operations proc_pid_maps_op = {
+ .start = m_start,
+ .next = m_next,
+ .stop = m_stop,
+ .show = m_show,
};

-static int pid_numa_maps_open(struct inode *inode, struct file *file)
+static int proc_maps_open(struct inode *inode, struct file *file)
{
- return proc_maps_open(inode, file, &proc_pid_numa_maps_op,
- sizeof(struct numa_maps_private));
+ const char *name = pid_entry_name(PROC_I(inode)->pid_entry);
+ int psize = sizeof(struct proc_maps_private);
+ int (*show)(struct seq_file *m, void *v);
+ struct proc_maps_private *priv;
+
+ if (strcmp(name, "maps") == 0)
+ show = show_pid_map;
+ else if (strcmp(name, "smaps") == 0)
+ show = show_pid_smap;
+ else if (strcmp(name, "numa_maps") == 0) {
+ show = show_pid_numa_map;
+ psize = sizeof(struct numa_maps_private);
+ }
+ else
+ BUG();
+
+ priv = __seq_open_private(file, &proc_pid_maps_op, psize);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->show = show;
+ priv->pid = proc_pid(inode);
+ priv->is_tgid = is_tgid_pid_entry(PROC_I(inode)->pid_entry);
+ priv->mm = proc_mem_open(inode, PTRACE_MODE_READ);
+ if (IS_ERR(priv->mm)) {
+ int err = PTR_ERR(priv->mm);
+ seq_release_private(inode, file);
+ return err;
+ }
+
+ return 0;
}

-const struct file_operations proc_pid_numa_maps_operations = {
- .open = pid_numa_maps_open,
+const struct file_operations proc_pid_maps_operations = {
+ .open = proc_maps_open,
.read = seq_read,
.llseek = seq_lseek,
.release = proc_map_release,
};
-#endif /* CONFIG_NUMA */
+
--
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/