From c3506372277779fccbffee2475400fcd689d5738 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 10 Apr 2018 19:42:55 +0200 Subject: proc: introduce proc_create_net{,_data} Variants of proc_create{,_data} that directly take a struct seq_operations and deal with network namespaces in ->open and ->release. All callers of proc_create + seq_open_net converted over, and seq_{open,release}_net are removed entirely. Signed-off-by: Christoph Hellwig --- fs/proc/proc_net.c | 61 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 21 deletions(-) (limited to 'fs/proc') diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c index 1763f370489d..c99fd183f034 100644 --- a/fs/proc/proc_net.c +++ b/fs/proc/proc_net.c @@ -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,7 +60,38 @@ int seq_open_net(struct inode *ino, struct file *f, #endif return 0; } -EXPORT_SYMBOL_GPL(seq_open_net); + +static int seq_release_net(struct inode *ino, struct file *f) +{ + struct seq_file *seq = f->private_data; + + put_net(seq_file_net(seq)); + seq_release_private(ino, f); + return 0; +} + +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); int single_open_net(struct inode *inode, struct file *file, int (*show)(struct seq_file *, void *)) @@ -86,18 +117,6 @@ err_net: } EXPORT_SYMBOL_GPL(single_open_net); -int seq_release_net(struct inode *ino, struct file *f) -{ - struct seq_file *seq; - - 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) { struct seq_file *seq = f->private_data; -- cgit v1.2.3