Merge branch 'hch.procfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull procfs updates from Al Viro: "Christoph's proc_create_... cleanups series" * 'hch.procfs' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (44 commits) xfs, proc: hide unused xfs procfs helpers isdn/gigaset: add back gigaset_procinfo assignment proc: update SIZEOF_PDE_INLINE_NAME for the new pde fields tty: replace ->proc_fops with ->proc_show ide: replace ->proc_fops with ->proc_show ide: remove ide_driver_proc_write isdn: replace ->proc_fops with ->proc_show atm: switch to proc_create_seq_private atm: simplify procfs code bluetooth: switch to proc_create_seq_data netfilter/x_tables: switch to proc_create_seq_private netfilter/xt_hashlimit: switch to proc_create_{seq,single}_data neigh: switch to proc_create_seq_data hostap: switch to proc_create_{seq,single}_data bonding: switch to proc_create_seq_data rtc/proc: switch to proc_create_single_data drbd: switch to proc_create_single resource: switch to proc_create_seq_data staging/rtl8192u: simplify procfs code jfs: simplify procfs code ...
This commit is contained in:
@@ -702,25 +702,22 @@ out:
|
||||
|
||||
static int children_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct inode *inode = seq->private;
|
||||
pid_t pid;
|
||||
|
||||
pid = pid_nr_ns(v, inode->i_sb->s_fs_info);
|
||||
seq_printf(seq, "%d ", pid);
|
||||
struct inode *inode = file_inode(seq->file);
|
||||
|
||||
seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *children_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
return get_children_pid(seq->private, NULL, *pos);
|
||||
return get_children_pid(file_inode(seq->file), NULL, *pos);
|
||||
}
|
||||
|
||||
static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct pid *pid;
|
||||
|
||||
pid = get_children_pid(seq->private, v, *pos + 1);
|
||||
pid = get_children_pid(file_inode(seq->file), v, *pos + 1);
|
||||
put_pid(v);
|
||||
|
||||
++*pos;
|
||||
@@ -741,17 +738,7 @@ static const struct seq_operations children_seq_ops = {
|
||||
|
||||
static int children_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct seq_file *m;
|
||||
int ret;
|
||||
|
||||
ret = seq_open(file, &children_seq_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
m = file->private_data;
|
||||
m->private = inode;
|
||||
|
||||
return ret;
|
||||
return seq_open(file, &children_seq_ops);
|
||||
}
|
||||
|
||||
const struct file_operations proc_tid_children_operations = {
|
||||
|
@@ -698,7 +698,7 @@ static bool has_pid_permissions(struct pid_namespace *pid,
|
||||
|
||||
static int proc_pid_permission(struct inode *inode, int mask)
|
||||
{
|
||||
struct pid_namespace *pid = inode->i_sb->s_fs_info;
|
||||
struct pid_namespace *pid = proc_pid_ns(inode);
|
||||
struct task_struct *task;
|
||||
bool has_perms;
|
||||
|
||||
@@ -733,13 +733,11 @@ static const struct inode_operations proc_def_inode_operations = {
|
||||
static int proc_single_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct inode *inode = m->private;
|
||||
struct pid_namespace *ns;
|
||||
struct pid *pid;
|
||||
struct pid_namespace *ns = proc_pid_ns(inode);
|
||||
struct pid *pid = proc_pid(inode);
|
||||
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;
|
||||
@@ -1410,7 +1408,7 @@ static const struct file_operations proc_fail_nth_operations = {
|
||||
static int sched_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct inode *inode = m->private;
|
||||
struct pid_namespace *ns = inode->i_sb->s_fs_info;
|
||||
struct pid_namespace *ns = proc_pid_ns(inode);
|
||||
struct task_struct *p;
|
||||
|
||||
p = get_proc_task(inode);
|
||||
@@ -1782,8 +1780,8 @@ int pid_getattr(const struct path *path, struct kstat *stat,
|
||||
u32 request_mask, unsigned int query_flags)
|
||||
{
|
||||
struct inode *inode = d_inode(path->dentry);
|
||||
struct pid_namespace *pid = proc_pid_ns(inode);
|
||||
struct task_struct *task;
|
||||
struct pid_namespace *pid = path->dentry->d_sb->s_fs_info;
|
||||
|
||||
generic_fillattr(inode, stat);
|
||||
|
||||
@@ -2337,7 +2335,7 @@ static int proc_timers_open(struct inode *inode, struct file *file)
|
||||
return -ENOMEM;
|
||||
|
||||
tp->pid = proc_pid(inode);
|
||||
tp->ns = inode->i_sb->s_fs_info;
|
||||
tp->ns = proc_pid_ns(inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3239,7 +3237,7 @@ retry:
|
||||
int proc_pid_readdir(struct file *file, struct dir_context *ctx)
|
||||
{
|
||||
struct tgid_iter iter;
|
||||
struct pid_namespace *ns = file_inode(file)->i_sb->s_fs_info;
|
||||
struct pid_namespace *ns = proc_pid_ns(file_inode(file));
|
||||
loff_t pos = ctx->pos;
|
||||
|
||||
if (pos >= PID_MAX_LIMIT + TGID_OFFSET)
|
||||
@@ -3588,7 +3586,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
|
||||
/* f_version caches the tgid value that the last readdir call couldn't
|
||||
* return. lseek aka telldir automagically resets f_version to 0.
|
||||
*/
|
||||
ns = inode->i_sb->s_fs_info;
|
||||
ns = proc_pid_ns(inode);
|
||||
tid = (int)file->f_version;
|
||||
file->f_version = 0;
|
||||
for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
|
||||
|
@@ -11,21 +11,9 @@ static int cmdline_proc_show(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmdline_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, cmdline_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations cmdline_proc_fops = {
|
||||
.open = cmdline_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int __init proc_cmdline_init(void)
|
||||
{
|
||||
proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
|
||||
proc_create_single("cmdline", 0, NULL, cmdline_proc_show);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_cmdline_init);
|
||||
|
@@ -91,21 +91,9 @@ static const struct seq_operations consoles_op = {
|
||||
.show = show_console_dev
|
||||
};
|
||||
|
||||
static int consoles_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &consoles_op);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_consoles_operations = {
|
||||
.open = consoles_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init proc_consoles_init(void)
|
||||
{
|
||||
proc_create("consoles", 0, NULL, &proc_consoles_operations);
|
||||
proc_create_seq("consoles", 0, NULL, &consoles_op);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_consoles_init);
|
||||
|
@@ -51,21 +51,9 @@ static const struct seq_operations devinfo_ops = {
|
||||
.show = devinfo_show
|
||||
};
|
||||
|
||||
static int devinfo_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
return seq_open(filp, &devinfo_ops);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_devinfo_operations = {
|
||||
.open = devinfo_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init proc_devices_init(void)
|
||||
{
|
||||
proc_create("devices", 0, NULL, &proc_devinfo_operations);
|
||||
proc_create_seq("devices", 0, NULL, &devinfo_ops);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_devices_init);
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -346,13 +347,12 @@ static const struct inode_operations proc_dir_inode_operations = {
|
||||
.setattr = proc_notify_change,
|
||||
};
|
||||
|
||||
static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp)
|
||||
/* returns the registered entry, or frees dp and returns NULL on failure */
|
||||
struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
|
||||
struct proc_dir_entry *dp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = proc_alloc_inum(&dp->low_ino);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (proc_alloc_inum(&dp->low_ino))
|
||||
goto out_free_entry;
|
||||
|
||||
write_lock(&proc_subdir_lock);
|
||||
dp->parent = dir;
|
||||
@@ -360,12 +360,16 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
|
||||
WARN(1, "proc_dir_entry '%s/%s' already registered\n",
|
||||
dir->name, dp->name);
|
||||
write_unlock(&proc_subdir_lock);
|
||||
proc_free_inum(dp->low_ino);
|
||||
return -EEXIST;
|
||||
goto out_free_inum;
|
||||
}
|
||||
write_unlock(&proc_subdir_lock);
|
||||
|
||||
return 0;
|
||||
return dp;
|
||||
out_free_inum:
|
||||
proc_free_inum(dp->low_ino);
|
||||
out_free_entry:
|
||||
pde_free(dp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
|
||||
@@ -443,10 +447,7 @@ struct proc_dir_entry *proc_symlink(const char *name,
|
||||
if (ent->data) {
|
||||
strcpy((char*)ent->data,dest);
|
||||
ent->proc_iops = &proc_link_inode_operations;
|
||||
if (proc_register(parent, ent) < 0) {
|
||||
pde_free(ent);
|
||||
ent = NULL;
|
||||
}
|
||||
ent = proc_register(parent, ent);
|
||||
} else {
|
||||
pde_free(ent);
|
||||
ent = NULL;
|
||||
@@ -470,11 +471,9 @@ struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
|
||||
ent->proc_fops = &proc_dir_operations;
|
||||
ent->proc_iops = &proc_dir_inode_operations;
|
||||
parent->nlink++;
|
||||
if (proc_register(parent, ent) < 0) {
|
||||
pde_free(ent);
|
||||
ent = proc_register(parent, ent);
|
||||
if (!ent)
|
||||
parent->nlink--;
|
||||
ent = NULL;
|
||||
}
|
||||
}
|
||||
return ent;
|
||||
}
|
||||
@@ -505,47 +504,47 @@ struct proc_dir_entry *proc_create_mount_point(const char *name)
|
||||
ent->proc_fops = NULL;
|
||||
ent->proc_iops = NULL;
|
||||
parent->nlink++;
|
||||
if (proc_register(parent, ent) < 0) {
|
||||
pde_free(ent);
|
||||
ent = proc_register(parent, ent);
|
||||
if (!ent)
|
||||
parent->nlink--;
|
||||
ent = NULL;
|
||||
}
|
||||
}
|
||||
return ent;
|
||||
}
|
||||
EXPORT_SYMBOL(proc_create_mount_point);
|
||||
|
||||
struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
|
||||
struct proc_dir_entry *parent,
|
||||
const struct file_operations *proc_fops,
|
||||
void *data)
|
||||
struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
|
||||
struct proc_dir_entry **parent, void *data)
|
||||
{
|
||||
struct proc_dir_entry *pde;
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
if ((mode & S_IFMT) == 0)
|
||||
mode |= S_IFREG;
|
||||
|
||||
if (!S_ISREG(mode)) {
|
||||
WARN_ON(1); /* use proc_mkdir() */
|
||||
if ((mode & S_IALLUGO) == 0)
|
||||
mode |= S_IRUGO;
|
||||
if (WARN_ON_ONCE(!S_ISREG(mode)))
|
||||
return NULL;
|
||||
|
||||
p = __proc_create(parent, name, mode, 1);
|
||||
if (p) {
|
||||
p->proc_iops = &proc_file_inode_operations;
|
||||
p->data = data;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
|
||||
struct proc_dir_entry *parent,
|
||||
const struct file_operations *proc_fops, void *data)
|
||||
{
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
BUG_ON(proc_fops == NULL);
|
||||
|
||||
if ((mode & S_IALLUGO) == 0)
|
||||
mode |= S_IRUGO;
|
||||
pde = __proc_create(&parent, name, mode, 1);
|
||||
if (!pde)
|
||||
goto out;
|
||||
pde->proc_fops = proc_fops;
|
||||
pde->data = data;
|
||||
pde->proc_iops = &proc_file_inode_operations;
|
||||
if (proc_register(parent, pde) < 0)
|
||||
goto out_free;
|
||||
return pde;
|
||||
out_free:
|
||||
pde_free(pde);
|
||||
out:
|
||||
return NULL;
|
||||
p = proc_create_reg(name, mode, &parent, data);
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->proc_fops = proc_fops;
|
||||
return proc_register(parent, p);
|
||||
}
|
||||
EXPORT_SYMBOL(proc_create_data);
|
||||
|
||||
@@ -557,6 +556,67 @@ struct proc_dir_entry *proc_create(const char *name, umode_t mode,
|
||||
}
|
||||
EXPORT_SYMBOL(proc_create);
|
||||
|
||||
static int proc_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct proc_dir_entry *de = PDE(inode);
|
||||
|
||||
if (de->state_size)
|
||||
return seq_open_private(file, de->seq_ops, de->state_size);
|
||||
return seq_open(file, de->seq_ops);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_seq_fops = {
|
||||
.open = proc_seq_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
|
||||
struct proc_dir_entry *parent, const struct seq_operations *ops,
|
||||
unsigned int state_size, void *data)
|
||||
{
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
p = proc_create_reg(name, mode, &parent, data);
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->proc_fops = &proc_seq_fops;
|
||||
p->seq_ops = ops;
|
||||
p->state_size = state_size;
|
||||
return proc_register(parent, p);
|
||||
}
|
||||
EXPORT_SYMBOL(proc_create_seq_private);
|
||||
|
||||
static int proc_single_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct proc_dir_entry *de = PDE(inode);
|
||||
|
||||
return single_open(file, de->single_show, de->data);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_single_fops = {
|
||||
.open = proc_single_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
|
||||
struct proc_dir_entry *parent,
|
||||
int (*show)(struct seq_file *, void *), void *data)
|
||||
{
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
p = proc_create_reg(name, mode, &parent, data);
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->proc_fops = &proc_single_fops;
|
||||
p->single_show = show;
|
||||
return proc_register(parent, p);
|
||||
}
|
||||
EXPORT_SYMBOL(proc_create_single_data);
|
||||
|
||||
void proc_set_size(struct proc_dir_entry *de, loff_t size)
|
||||
{
|
||||
de->size = size;
|
||||
|
@@ -44,7 +44,12 @@ struct proc_dir_entry {
|
||||
struct completion *pde_unload_completion;
|
||||
const struct inode_operations *proc_iops;
|
||||
const struct file_operations *proc_fops;
|
||||
union {
|
||||
const struct seq_operations *seq_ops;
|
||||
int (*single_show)(struct seq_file *, void *);
|
||||
};
|
||||
void *data;
|
||||
unsigned int state_size;
|
||||
unsigned int low_ino;
|
||||
nlink_t nlink;
|
||||
kuid_t uid;
|
||||
@@ -57,9 +62,9 @@ struct proc_dir_entry {
|
||||
umode_t mode;
|
||||
u8 namelen;
|
||||
#ifdef CONFIG_64BIT
|
||||
#define SIZEOF_PDE_INLINE_NAME (192-139)
|
||||
#define SIZEOF_PDE_INLINE_NAME (192-155)
|
||||
#else
|
||||
#define SIZEOF_PDE_INLINE_NAME (128-87)
|
||||
#define SIZEOF_PDE_INLINE_NAME (128-95)
|
||||
#endif
|
||||
char inline_name[SIZEOF_PDE_INLINE_NAME];
|
||||
} __randomize_layout;
|
||||
@@ -162,6 +167,10 @@ extern bool proc_fill_cache(struct file *, struct dir_context *, const char *, i
|
||||
/*
|
||||
* generic.c
|
||||
*/
|
||||
struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
|
||||
struct proc_dir_entry **parent, void *data);
|
||||
struct proc_dir_entry *proc_register(struct proc_dir_entry *dir,
|
||||
struct proc_dir_entry *dp);
|
||||
extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int);
|
||||
struct dentry *proc_lookup_de(struct inode *, struct dentry *, struct proc_dir_entry *);
|
||||
extern int proc_readdir(struct file *, struct dir_context *);
|
||||
|
@@ -34,21 +34,9 @@ static const struct seq_operations int_seq_ops = {
|
||||
.show = show_interrupts
|
||||
};
|
||||
|
||||
static int interrupts_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
return seq_open(filp, &int_seq_ops);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_interrupts_operations = {
|
||||
.open = interrupts_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init proc_interrupts_init(void)
|
||||
{
|
||||
proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
|
||||
proc_create_seq("interrupts", 0, NULL, &int_seq_ops);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_interrupts_init);
|
||||
|
@@ -28,21 +28,9 @@ static int loadavg_proc_show(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int loadavg_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, loadavg_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations loadavg_proc_fops = {
|
||||
.open = loadavg_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int __init proc_loadavg_init(void)
|
||||
{
|
||||
proc_create("loadavg", 0, NULL, &loadavg_proc_fops);
|
||||
proc_create_single("loadavg", 0, NULL, loadavg_proc_show);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_loadavg_init);
|
||||
|
@@ -149,21 +149,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meminfo_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, meminfo_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations meminfo_proc_fops = {
|
||||
.open = meminfo_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int __init proc_meminfo_init(void)
|
||||
{
|
||||
proc_create("meminfo", 0, NULL, &meminfo_proc_fops);
|
||||
proc_create_single("meminfo", 0, NULL, meminfo_proc_show);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_meminfo_init);
|
||||
|
@@ -113,21 +113,9 @@ static const struct seq_operations proc_nommu_region_list_seqop = {
|
||||
.show = nommu_region_list_show
|
||||
};
|
||||
|
||||
static int proc_nommu_region_list_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &proc_nommu_region_list_seqop);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_nommu_region_list_operations = {
|
||||
.open = proc_nommu_region_list_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init proc_nommu_init(void)
|
||||
{
|
||||
proc_create("maps", S_IRUGO, NULL, &proc_nommu_region_list_operations);
|
||||
proc_create_seq("maps", S_IRUGO, NULL, &proc_nommu_region_list_seqop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -38,20 +38,20 @@ static struct net *get_proc_net(const struct inode *inode)
|
||||
return maybe_get_net(PDE_NET(PDE(inode)));
|
||||
}
|
||||
|
||||
int seq_open_net(struct inode *ino, struct file *f,
|
||||
const struct seq_operations *ops, int size)
|
||||
static int seq_open_net(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct net *net;
|
||||
unsigned int state_size = PDE(inode)->state_size;
|
||||
struct seq_net_private *p;
|
||||
struct net *net;
|
||||
|
||||
BUG_ON(size < sizeof(*p));
|
||||
WARN_ON_ONCE(state_size < sizeof(*p));
|
||||
|
||||
net = get_proc_net(ino);
|
||||
if (net == NULL)
|
||||
net = get_proc_net(inode);
|
||||
if (!net)
|
||||
return -ENXIO;
|
||||
|
||||
p = __seq_open_private(f, ops, size);
|
||||
if (p == NULL) {
|
||||
p = __seq_open_private(file, PDE(inode)->seq_ops, state_size);
|
||||
if (!p) {
|
||||
put_net(net);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@@ -60,51 +60,83 @@ int seq_open_net(struct inode *ino, struct file *f,
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(seq_open_net);
|
||||
|
||||
int single_open_net(struct inode *inode, struct file *file,
|
||||
int (*show)(struct seq_file *, void *))
|
||||
static int seq_release_net(struct inode *ino, struct file *f)
|
||||
{
|
||||
int err;
|
||||
struct net *net;
|
||||
|
||||
err = -ENXIO;
|
||||
net = get_proc_net(inode);
|
||||
if (net == NULL)
|
||||
goto err_net;
|
||||
|
||||
err = single_open(file, show, net);
|
||||
if (err < 0)
|
||||
goto err_open;
|
||||
|
||||
return 0;
|
||||
|
||||
err_open:
|
||||
put_net(net);
|
||||
err_net:
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(single_open_net);
|
||||
|
||||
int seq_release_net(struct inode *ino, struct file *f)
|
||||
{
|
||||
struct seq_file *seq;
|
||||
|
||||
seq = f->private_data;
|
||||
struct seq_file *seq = f->private_data;
|
||||
|
||||
put_net(seq_file_net(seq));
|
||||
seq_release_private(ino, f);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(seq_release_net);
|
||||
|
||||
int single_release_net(struct inode *ino, struct file *f)
|
||||
static const struct file_operations proc_net_seq_fops = {
|
||||
.open = seq_open_net,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release_net,
|
||||
};
|
||||
|
||||
struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode,
|
||||
struct proc_dir_entry *parent, const struct seq_operations *ops,
|
||||
unsigned int state_size, void *data)
|
||||
{
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
p = proc_create_reg(name, mode, &parent, data);
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->proc_fops = &proc_net_seq_fops;
|
||||
p->seq_ops = ops;
|
||||
p->state_size = state_size;
|
||||
return proc_register(parent, p);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(proc_create_net_data);
|
||||
|
||||
static int single_open_net(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct proc_dir_entry *de = PDE(inode);
|
||||
struct net *net;
|
||||
int err;
|
||||
|
||||
net = get_proc_net(inode);
|
||||
if (!net)
|
||||
return -ENXIO;
|
||||
|
||||
err = single_open(file, de->single_show, net);
|
||||
if (err)
|
||||
put_net(net);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int single_release_net(struct inode *ino, struct file *f)
|
||||
{
|
||||
struct seq_file *seq = f->private_data;
|
||||
put_net(seq->private);
|
||||
return single_release(ino, f);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(single_release_net);
|
||||
|
||||
static const struct file_operations proc_net_single_fops = {
|
||||
.open = single_open_net,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release_net,
|
||||
};
|
||||
|
||||
struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode,
|
||||
struct proc_dir_entry *parent,
|
||||
int (*show)(struct seq_file *, void *), void *data)
|
||||
{
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
p = proc_create_reg(name, mode, &parent, data);
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->proc_fops = &proc_net_single_fops;
|
||||
p->single_show = show;
|
||||
return proc_register(parent, p);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(proc_create_net_single);
|
||||
|
||||
static struct net *get_proc_task_net(struct inode *dir)
|
||||
{
|
||||
|
@@ -126,18 +126,6 @@ static const struct seq_operations tty_drivers_op = {
|
||||
.show = show_tty_driver
|
||||
};
|
||||
|
||||
static int tty_drivers_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &tty_drivers_op);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_tty_drivers_operations = {
|
||||
.open = tty_drivers_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
/*
|
||||
* This function is called by tty_register_driver() to handle
|
||||
* registering the driver's /proc handler into /proc/tty/driver/<foo>
|
||||
@@ -147,11 +135,11 @@ void proc_tty_register_driver(struct tty_driver *driver)
|
||||
struct proc_dir_entry *ent;
|
||||
|
||||
if (!driver->driver_name || driver->proc_entry ||
|
||||
!driver->ops->proc_fops)
|
||||
!driver->ops->proc_show)
|
||||
return;
|
||||
|
||||
ent = proc_create_data(driver->driver_name, 0, proc_tty_driver,
|
||||
driver->ops->proc_fops, driver);
|
||||
ent = proc_create_single_data(driver->driver_name, 0, proc_tty_driver,
|
||||
driver->ops->proc_show, driver);
|
||||
driver->proc_entry = ent;
|
||||
}
|
||||
|
||||
@@ -186,6 +174,6 @@ void __init proc_tty_init(void)
|
||||
* entry.
|
||||
*/
|
||||
proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL);
|
||||
proc_create("tty/ldiscs", 0, NULL, &tty_ldiscs_proc_fops);
|
||||
proc_create("tty/drivers", 0, NULL, &proc_tty_drivers_operations);
|
||||
proc_create_seq("tty/ldiscs", 0, NULL, &tty_ldiscs_seq_ops);
|
||||
proc_create_seq("tty/drivers", 0, NULL, &tty_drivers_op);
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ static const char *proc_self_get_link(struct dentry *dentry,
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct pid_namespace *ns = inode->i_sb->s_fs_info;
|
||||
struct pid_namespace *ns = proc_pid_ns(inode);
|
||||
pid_t tgid = task_tgid_nr_ns(current, ns);
|
||||
char *name;
|
||||
|
||||
@@ -36,7 +36,7 @@ static unsigned self_inum __ro_after_init;
|
||||
int proc_setup_self(struct super_block *s)
|
||||
{
|
||||
struct inode *root_inode = d_inode(s->s_root);
|
||||
struct pid_namespace *ns = s->s_fs_info;
|
||||
struct pid_namespace *ns = proc_pid_ns(root_inode);
|
||||
struct dentry *self;
|
||||
|
||||
inode_lock(root_inode);
|
||||
|
@@ -25,21 +25,9 @@ static int show_softirqs(struct seq_file *p, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int softirqs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, show_softirqs, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations proc_softirqs_operations = {
|
||||
.open = softirqs_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int __init proc_softirqs_init(void)
|
||||
{
|
||||
proc_create("softirqs", 0, NULL, &proc_softirqs_operations);
|
||||
proc_create_single("softirqs", 0, NULL, show_softirqs);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_softirqs_init);
|
||||
|
@@ -12,7 +12,7 @@ static const char *proc_thread_self_get_link(struct dentry *dentry,
|
||||
struct inode *inode,
|
||||
struct delayed_call *done)
|
||||
{
|
||||
struct pid_namespace *ns = inode->i_sb->s_fs_info;
|
||||
struct pid_namespace *ns = proc_pid_ns(inode);
|
||||
pid_t tgid = task_tgid_nr_ns(current, ns);
|
||||
pid_t pid = task_pid_nr_ns(current, ns);
|
||||
char *name;
|
||||
@@ -36,7 +36,7 @@ static unsigned thread_self_inum __ro_after_init;
|
||||
int proc_setup_thread_self(struct super_block *s)
|
||||
{
|
||||
struct inode *root_inode = d_inode(s->s_root);
|
||||
struct pid_namespace *ns = s->s_fs_info;
|
||||
struct pid_namespace *ns = proc_pid_ns(root_inode);
|
||||
struct dentry *thread_self;
|
||||
|
||||
inode_lock(root_inode);
|
||||
|
@@ -30,21 +30,9 @@ static int uptime_proc_show(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uptime_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, uptime_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations uptime_proc_fops = {
|
||||
.open = uptime_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int __init proc_uptime_init(void)
|
||||
{
|
||||
proc_create("uptime", 0, NULL, &uptime_proc_fops);
|
||||
proc_create_single("uptime", 0, NULL, uptime_proc_show);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_uptime_init);
|
||||
|
@@ -15,21 +15,9 @@ static int version_proc_show(struct seq_file *m, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int version_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, version_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations version_proc_fops = {
|
||||
.open = version_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int __init proc_version_init(void)
|
||||
{
|
||||
proc_create("version", 0, NULL, &version_proc_fops);
|
||||
proc_create_single("version", 0, NULL, version_proc_show);
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_version_init);
|
||||
|
Reference in New Issue
Block a user