diff options
author | Christoph Hellwig <hch@lst.de> | 2018-04-13 20:38:35 +0200 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2018-05-16 07:24:30 +0200 |
commit | 3617d9496cd92dcca4d0893191d95554590d8d9f (patch) | |
tree | 3054a4c965a42aa4375b08f92b111e1943cd41c5 /fs/proc | |
parent | c3506372277779fccbffee2475400fcd689d5738 (diff) | |
download | linux-3617d9496cd92dcca4d0893191d95554590d8d9f.tar.bz2 |
proc: introduce proc_create_net_single
Variant of proc_create_data that directly take a seq_file show
callback and deals with network namespaces in ->open and ->release.
All callers of proc_create + single_open_net converted over, and
single_{open,release}_net are removed entirely.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/proc_net.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index c99fd183f034..7d94fa005b0d 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -93,37 +93,50 @@ struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode, } EXPORT_SYMBOL_GPL(proc_create_net_data); -int single_open_net(struct inode *inode, struct file *file, - int (*show)(struct seq_file *, void *)) +static int single_open_net(struct inode *inode, struct file *file) { - int err; + struct proc_dir_entry *de = PDE(inode); struct net *net; + int err; - 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; + if (!net) + return -ENXIO; -err_open: - put_net(net); -err_net: + err = single_open(file, de->single_show, net); + if (err) + put_net(net); return err; } -EXPORT_SYMBOL_GPL(single_open_net); -int single_release_net(struct inode *ino, struct file *f) +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) { |