Commit c3506372 authored by Christoph Hellwig's avatar Christoph Hellwig
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
parent a2dcdee3
......@@ -1096,21 +1096,6 @@ static const struct seq_operations pppoe_seq_ops = {
.stop = pppoe_seq_stop,
.show = pppoe_seq_show,
};
static int pppoe_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &pppoe_seq_ops,
sizeof(struct seq_net_private));
}
static const struct file_operations pppoe_seq_fops = {
.owner = THIS_MODULE,
.open = pppoe_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
#endif /* CONFIG_PROC_FS */
static const struct proto_ops pppoe_ops = {
......@@ -1146,7 +1131,8 @@ static __net_init int pppoe_init_net(struct net *net)
rwlock_init(&pn->hash_lock);
pde = proc_create("pppoe", 0444, net->proc_net, &pppoe_seq_fops);
pde = proc_create_net("pppoe", 0444, net->proc_net,
&pppoe_seq_ops, sizeof(struct seq_net_private));
#ifdef CONFIG_PROC_FS
if (!pde)
return -ENOMEM;
......
......@@ -1067,7 +1067,6 @@ void nfs_clients_init(struct net *net)
}
#ifdef CONFIG_PROC_FS
static int nfs_server_list_open(struct inode *inode, struct file *file);
static void *nfs_server_list_start(struct seq_file *p, loff_t *pos);
static void *nfs_server_list_next(struct seq_file *p, void *v, loff_t *pos);
static void nfs_server_list_stop(struct seq_file *p, void *v);
......@@ -1080,14 +1079,6 @@ static const struct seq_operations nfs_server_list_ops = {
.show = nfs_server_list_show,
};
static const struct file_operations nfs_server_list_fops = {
.open = nfs_server_list_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
static int nfs_volume_list_open(struct inode *inode, struct file *file);
static void *nfs_volume_list_start(struct seq_file *p, loff_t *pos);
static void *nfs_volume_list_next(struct seq_file *p, void *v, loff_t *pos);
static void nfs_volume_list_stop(struct seq_file *p, void *v);
......@@ -1100,23 +1091,6 @@ static const struct seq_operations nfs_volume_list_ops = {
.show = nfs_volume_list_show,
};
static const struct file_operations nfs_volume_list_fops = {
.open = nfs_volume_list_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
/*
* open "/proc/fs/nfsfs/servers" which provides a summary of servers with which
* we're dealing
*/
static int nfs_server_list_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &nfs_server_list_ops,
sizeof(struct seq_net_private));
}
/*
* set up the iterator to start reading from the server list and return the first item
*/
......@@ -1184,15 +1158,6 @@ static int nfs_server_list_show(struct seq_file *m, void *v)
return 0;
}
/*
* open "/proc/fs/nfsfs/volumes" which provides a summary of extant volumes
*/
static int nfs_volume_list_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &nfs_volume_list_ops,
sizeof(struct seq_net_private));
}
/*
* set up the iterator to start reading from the volume list and return the first item
*/
......@@ -1278,14 +1243,14 @@ int nfs_fs_proc_net_init(struct net *net)
goto error_0;
/* a file of servers with which we're dealing */
p = proc_create("servers", S_IFREG|S_IRUGO,
nn->proc_nfsfs, &nfs_server_list_fops);
p = proc_create_net("servers", S_IFREG|S_IRUGO, nn->proc_nfsfs,
&nfs_server_list_ops, sizeof(struct seq_net_private));
if (!p)
goto error_1;
/* a file of volumes that we have mounted */
p = proc_create("volumes", S_IFREG|S_IRUGO,
nn->proc_nfsfs, &nfs_volume_list_fops);
p = proc_create_net("volumes", S_IFREG|S_IRUGO, nn->proc_nfsfs,
&nfs_volume_list_ops, sizeof(struct seq_net_private));
if (!p)
goto error_1;
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,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;
......
......@@ -53,6 +53,12 @@ extern void proc_remove(struct proc_dir_entry *);
extern void remove_proc_entry(const char *, struct proc_dir_entry *);
extern int remove_proc_subtree(const char *, struct proc_dir_entry *);
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);
#define proc_create_net(name, mode, parent, state_size, ops) \
proc_create_net_data(name, mode, parent, state_size, ops, NULL)
#else /* CONFIG_PROC_FS */
static inline void proc_root_init(void)
......@@ -89,6 +95,9 @@ static inline void proc_remove(struct proc_dir_entry *de) {}
#define remove_proc_entry(name, parent) do {} while (0)
static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) { return 0; }
#define proc_create_net_data(name, mode, parent, ops, state_size, data) ({NULL;})
#define proc_create_net(name, mode, parent, state_size, ops) ({NULL;})
#endif /* CONFIG_PROC_FS */
struct net;
......
......@@ -13,11 +13,8 @@ struct seq_net_private {
#endif
};
int seq_open_net(struct inode *, struct file *,
const struct seq_operations *, int);
int single_open_net(struct inode *, struct file *file,
int (*show)(struct seq_file *, void *));
int seq_release_net(struct inode *, struct file *);
int single_release_net(struct inode *, struct file *);
static inline struct net *seq_file_net(struct seq_file *seq)
{
......
......@@ -394,7 +394,15 @@ void fib6_gc_cleanup(void);
int fib6_init(void);
int ipv6_route_open(struct inode *inode, struct file *file);
struct ipv6_route_iter {
struct seq_net_private p;
struct fib6_walker w;
loff_t skip;
struct fib6_table *tbl;
int sernum;
};
extern const struct seq_operations ipv6_route_seq_ops;
int call_fib6_notifier(struct notifier_block *nb, struct net *net,
enum fib_event_type event_type,
......
......@@ -56,7 +56,7 @@ struct net_device *phonet_route_output(struct net *net, u8 daddr);
#define PN_NO_ADDR 0xff
extern const struct file_operations pn_sock_seq_fops;
extern const struct file_operations pn_res_seq_fops;
extern const struct seq_operations pn_sock_seq_ops;
extern const struct seq_operations pn_res_seq_ops;
#endif
......@@ -423,8 +423,8 @@ void *udp_seq_start(struct seq_file *seq, loff_t *pos);
void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos);
void udp_seq_stop(struct seq_file *seq, void *v);
extern const struct file_operations udp_afinfo_seq_fops;
extern const struct file_operations udp6_afinfo_seq_fops;
extern const struct seq_operations udp_seq_ops;
extern const struct seq_operations udp6_seq_ops;
int udp4_proc_init(void);
void udp4_proc_exit(void);
......
......@@ -73,19 +73,6 @@ static const struct seq_operations vlan_seq_ops = {
.show = vlan_seq_show,
};
static int vlan_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &vlan_seq_ops,
sizeof(struct seq_net_private));
}
static const struct file_operations vlan_fops = {
.open = vlan_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
/*
* Proc filesystem directory entries.
*/
......@@ -132,8 +119,9 @@ int __net_init vlan_proc_init(struct net *net)
if (!vn->proc_vlan_dir)
goto err;
vn->proc_vlan_conf = proc_create(name_conf, S_IFREG | 0600,
vn->proc_vlan_dir, &vlan_fops);
vn->proc_vlan_conf = proc_create_net(name_conf, S_IFREG | 0600,
vn->proc_vlan_dir, &vlan_seq_ops,
sizeof(struct seq_net_private));
if (!vn->proc_vlan_conf)
goto err;
return 0;
......
......@@ -863,20 +863,6 @@ static const struct seq_operations arp_seq_ops = {
.stop = neigh_seq_stop,
.show = clip_seq_show,
};
static int arp_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &arp_seq_ops,
sizeof(struct clip_seq_state));
}
static const struct file_operations arp_seq_fops = {
.open = arp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
.owner = THIS_MODULE
};
#endif
static void atm_clip_exit_noproc(void);
......@@ -893,7 +879,8 @@ static int __init atm_clip_init(void)
{
struct proc_dir_entry *p;
p = proc_create("arp", 0444, atm_proc_root, &arp_seq_fops);
p = proc_create_net("arp", 0444, atm_proc_root, &arp_seq_ops,
sizeof(struct clip_seq_state));
if (!p) {
pr_err("Unable to initialize /proc/net/atm/arp\n");
atm_clip_exit_noproc();
......
......@@ -175,19 +175,6 @@ static const struct seq_operations dev_seq_ops = {
.show = dev_seq_show,
};
static int dev_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &dev_seq_ops,
sizeof(struct seq_net_private));
}
static const struct file_operations dev_seq_fops = {
.open = dev_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
static const struct seq_operations softnet_seq_ops = {
.start = softnet_seq_start,
.next = softnet_seq_next,
......@@ -285,30 +272,18 @@ static const struct seq_operations ptype_seq_ops = {
.show = ptype_seq_show,
};
static int ptype_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &ptype_seq_ops,
sizeof(struct seq_net_private));
}
static const struct file_operations ptype_seq_fops = {
.open = ptype_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
static int __net_init dev_proc_net_init(struct net *net)
{
int rc = -ENOMEM;
if (!proc_create("dev", 0444, net->proc_net, &dev_seq_fops))
if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops,
sizeof(struct seq_net_private)))
goto out;
if (!proc_create_seq("softnet_stat", 0444, net->proc_net,
&softnet_seq_ops))
goto out_dev;
if (!proc_create("ptype", 0444, net->proc_net, &ptype_seq_fops))
if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
sizeof(struct seq_net_private)))
goto out_softnet;
if (wext_proc_init(net))
......@@ -365,22 +340,10 @@ static const struct seq_operations dev_mc_seq_ops = {
.show = dev_mc_seq_show,
};
static int dev_mc_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &dev_mc_seq_ops,
sizeof(struct seq_net_private));
}
static const struct file_operations dev_mc_seq_fops = {
.open = dev_mc_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
static int __net_init dev_mc_net_init(struct net *net)
{
if (!proc_create("dev_mcast", 0, net->proc_net, &dev_mc_seq_fops))
if (!proc_create_net("dev_mcast", 0, net->proc_net, &dev_mc_seq_ops,
sizeof(struct seq_net_private)))
return -ENOMEM;
return 0;
}
......
......@@ -3439,22 +3439,10 @@ static const struct seq_operations proto_seq_ops = {
.show = proto_seq_show,
};
static int proto_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &proto_seq_ops,
sizeof(struct seq_net_private));
}
static const struct file_operations proto_seq_fops = {
.open = proto_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
static __net_init int proto_init_net(struct net *net)
{
if (!proc_create("protocols", 0444, net->proc_net, &proto_seq_fops))
if (!proc_create_net("protocols", 0444, net->proc_net, &proto_seq_ops,
sizeof(struct seq_net_private)))
return -ENOMEM;
return 0;
......
......@@ -589,27 +589,13 @@ static const struct seq_operations dn_neigh_seq_ops = {
.stop = neigh_seq_stop,
.show = dn_neigh_seq_show,
};
static int dn_neigh_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &dn_neigh_seq_ops,
sizeof(struct neigh_seq_state));
}
static const struct file_operations dn_neigh_seq_fops = {
.open = dn_neigh_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
#endif
void __init dn_neigh_init(void)
{
neigh_table_init(NEIGH_DN_TABLE, &dn_neigh_table);
proc_create("decnet_neigh", 0444, init_net.proc_net,
&dn_neigh_seq_fops);
proc_create_net("decnet_neigh", 0444, init_net.proc_net,
&dn_neigh_seq_ops, sizeof(struct neigh_seq_state));
}
void __exit dn_neigh_cleanup(void)
......
......@@ -1418,23 +1418,12 @@ static const struct seq_operations arp_seq_ops = {
.show = arp_seq_show,
};
static int arp_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &arp_seq_ops,
sizeof(struct neigh_seq_state));
}
static const struct file_operations arp_seq_fops = {
.open = arp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
/* ------------------------------------------------------------------------ */
static int __net_init arp_net_init(struct net *net)
{
if (!proc_create("arp", 0444, net->proc_net, &arp_seq_fops))
if (!proc_create_net("arp", 0444, net->proc_net, &arp_seq_ops,
sizeof(struct neigh_seq_state)))
return -ENOMEM;
return 0;
}
......
......@@ -2533,19 +2533,6 @@ static const struct seq_operations fib_trie_seq_ops = {
.show = fib_trie_seq_show,
};
static int fib_trie_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &fib_trie_seq_ops,
sizeof(struct fib_trie_iter));
}
static const struct file_operations fib_trie_fops = {
.open = fib_trie_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
struct fib_route_iter {
struct seq_net_private p;
struct fib_table *main_tb;
......@@ -2726,29 +2713,18 @@ static const struct seq_operations fib_route_seq_ops = {
.show = fib_route_seq_show,
};
static int fib_route_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &fib_route_seq_ops,
sizeof(struct fib_route_iter));
}
static const struct file_operations fib_route_fops = {
.open = fib_route_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
int __net_init fib_proc_init(struct net *net)
{
if (!proc_create("fib_trie", 0444, net->proc_net, &fib_trie_fops))
if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
sizeof(struct fib_trie_iter)))
goto out1;
if (!proc_create("fib_triestat", 0444, net->proc_net,
&fib_triestat_fops))
goto out2;
if (!proc_create("route", 0444, net->proc_net, &fib_route_fops))
if (!proc_create_net("route", 0444, net->proc_net, &fib_route_seq_ops,
sizeof(struct fib_route_iter)))
goto out3;
return 0;
......
......@@ -2829,19 +2829,6 @@ static const struct seq_operations igmp_mc_seq_ops = {
.show = igmp_mc_seq_show,
};
static int igmp_mc_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &igmp_mc_seq_ops,
sizeof(struct igmp_mc_iter_state));
}
static const struct file_operations igmp_mc_seq_fops = {
.open = igmp_mc_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
struct igmp_mcf_iter_state {
struct seq_net_private p;
struct net_device *dev;
......@@ -2975,29 +2962,17 @@ static const struct seq_operations igmp_mcf_seq_ops = {
.show = igmp_mcf_seq_show,
};
static int igmp_mcf_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &igmp_mcf_seq_ops,
sizeof(struct igmp_mcf_iter_state));
}
static const struct file_operations igmp_mcf_seq_fops = {
.open = igmp_mcf_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
static int __net_init igmp_net_init(struct net *net)
{
struct proc_dir_entry *pde;
int err;
pde = proc_create("igmp", 0444, net->proc_net, &igmp_mc_seq_fops);
pde = proc_create_net("igmp", 0444, net->proc_net, &igmp_mc_seq_ops,
sizeof(struct igmp_mc_iter_state));
if (!pde)
goto out_igmp;
pde = proc_create("mcfilter", 0444, net->proc_net,
&igmp_mcf_seq_fops);
pde = proc_create_net("mcfilter", 0444, net->proc_net,
&igmp_mcf_seq_ops, sizeof(struct igmp_mcf_iter_state));