Skip to content

Commit

Permalink
proc: introduce proc_create_net_single
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
Christoph Hellwig committed May 16, 2018
1 parent c350637 commit 3617d94
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 307 deletions.
49 changes: 31 additions & 18 deletions fs/proc/proc_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
4 changes: 4 additions & 0 deletions include/linux/proc_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode,
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)
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);

#else /* CONFIG_PROC_FS */

Expand Down Expand Up @@ -97,6 +100,7 @@ static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *p

#define proc_create_net_data(name, mode, parent, ops, state_size, data) ({NULL;})
#define proc_create_net(name, mode, parent, state_size, ops) ({NULL;})
#define proc_create_net_single(name, mode, parent, show, data) ({NULL;})

#endif /* CONFIG_PROC_FS */

Expand Down
7 changes: 2 additions & 5 deletions include/linux/seq_file_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ struct seq_net_private {
#endif
};

int single_open_net(struct inode *, struct file *file,
int (*show)(struct seq_file *, void *));
int single_release_net(struct inode *, struct file *);
static inline struct net *seq_file_net(struct seq_file *seq)
{
#ifdef CONFIG_NET_NS
Expand All @@ -26,8 +23,8 @@ static inline struct net *seq_file_net(struct seq_file *seq)
}

/*
* This one is needed for single_open_net since net is stored directly in
* private not as a struct i.e. seq_file_net can't be used.
* This one is needed for proc_create_net_single since net is stored directly
* in private not as a struct i.e. seq_file_net can't be used.
*/
static inline struct net *seq_file_single_net(struct seq_file *seq)
{
Expand Down
16 changes: 2 additions & 14 deletions net/can/bcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,18 +239,6 @@ static int bcm_proc_show(struct seq_file *m, void *v)
seq_putc(m, '\n');
return 0;
}

static int bcm_proc_open(struct inode *inode, struct file *file)
{
return single_open_net(inode, file, bcm_proc_show);
}

static const struct file_operations bcm_proc_fops = {
.open = bcm_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release_net,
};
#endif /* CONFIG_PROC_FS */

/*
Expand Down Expand Up @@ -1606,9 +1594,9 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
if (net->can.bcmproc_dir) {
/* unique socket address as filename */
sprintf(bo->procname, "%lu", sock_i_ino(sk));
bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
bo->bcm_proc_read = proc_create_net_single(bo->procname, 0644,
net->can.bcmproc_dir,
&bcm_proc_fops, sk);
bcm_proc_show, sk);
if (!bo->bcm_proc_read) {
ret = -ENOMEM;
goto fail;
Expand Down
127 changes: 23 additions & 104 deletions net/can/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,18 +270,6 @@ static int can_stats_proc_show(struct seq_file *m, void *v)
return 0;
}

static int can_stats_proc_open(struct inode *inode, struct file *file)
{
return single_open_net(inode, file, can_stats_proc_show);
}

static const struct file_operations can_stats_proc_fops = {
.open = can_stats_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release_net,
};

static int can_reset_stats_proc_show(struct seq_file *m, void *v)
{
struct net *net = m->private;
Expand All @@ -303,36 +291,12 @@ static int can_reset_stats_proc_show(struct seq_file *m, void *v)
return 0;
}

static int can_reset_stats_proc_open(struct inode *inode, struct file *file)
{
return single_open_net(inode, file, can_reset_stats_proc_show);
}

static const struct file_operations can_reset_stats_proc_fops = {
.open = can_reset_stats_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

static int can_version_proc_show(struct seq_file *m, void *v)
{
seq_printf(m, "%s\n", CAN_VERSION_STRING);
return 0;
}

static int can_version_proc_open(struct inode *inode, struct file *file)
{
return single_open_net(inode, file, can_version_proc_show);
}

static const struct file_operations can_version_proc_fops = {
.open = can_version_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

static inline void can_rcvlist_proc_show_one(struct seq_file *m, int idx,
struct net_device *dev,
struct can_dev_rcv_lists *d)
Expand Down Expand Up @@ -373,18 +337,6 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v)
return 0;
}

static int can_rcvlist_proc_open(struct inode *inode, struct file *file)
{
return single_open_net(inode, file, can_rcvlist_proc_show);
}

static const struct file_operations can_rcvlist_proc_fops = {
.open = can_rcvlist_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};

static inline void can_rcvlist_proc_show_array(struct seq_file *m,
struct net_device *dev,
struct hlist_head *rcv_array,
Expand Down Expand Up @@ -440,19 +392,6 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
return 0;
}

static int can_rcvlist_sff_proc_open(struct inode *inode, struct file *file)
{
return single_open_net(inode, file, can_rcvlist_sff_proc_show);
}

static const struct file_operations can_rcvlist_sff_proc_fops = {
.open = can_rcvlist_sff_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release_net,
};


static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
{
struct net_device *dev;
Expand Down Expand Up @@ -483,18 +422,6 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
return 0;
}

static int can_rcvlist_eff_proc_open(struct inode *inode, struct file *file)
{
return single_open_net(inode, file, can_rcvlist_eff_proc_show);
}

static const struct file_operations can_rcvlist_eff_proc_fops = {
.open = can_rcvlist_eff_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release_net,
};

/*
* can_init_proc - create main CAN proc directory and procfs entries
*/
Expand All @@ -510,37 +437,29 @@ void can_init_proc(struct net *net)
}

/* own procfs entries from the AF_CAN core */
net->can.pde_version = proc_create(CAN_PROC_VERSION, 0644,
net->can.proc_dir,
&can_version_proc_fops);
net->can.pde_stats = proc_create(CAN_PROC_STATS, 0644,
net->can.proc_dir,
&can_stats_proc_fops);
net->can.pde_reset_stats = proc_create(CAN_PROC_RESET_STATS, 0644,
net->can.proc_dir,
&can_reset_stats_proc_fops);
net->can.pde_rcvlist_err = proc_create_data(CAN_PROC_RCVLIST_ERR, 0644,
net->can.proc_dir,
&can_rcvlist_proc_fops,
(void *)RX_ERR);
net->can.pde_rcvlist_all = proc_create_data(CAN_PROC_RCVLIST_ALL, 0644,
net->can.proc_dir,
&can_rcvlist_proc_fops,
(void *)RX_ALL);
net->can.pde_rcvlist_fil = proc_create_data(CAN_PROC_RCVLIST_FIL, 0644,
net->can.proc_dir,
&can_rcvlist_proc_fops,
(void *)RX_FIL);
net->can.pde_rcvlist_inv = proc_create_data(CAN_PROC_RCVLIST_INV, 0644,
net->can.proc_dir,
&can_rcvlist_proc_fops,
(void *)RX_INV);
net->can.pde_rcvlist_eff = proc_create(CAN_PROC_RCVLIST_EFF, 0644,
net->can.proc_dir,
&can_rcvlist_eff_proc_fops);
net->can.pde_rcvlist_sff = proc_create(CAN_PROC_RCVLIST_SFF, 0644,
net->can.proc_dir,
&can_rcvlist_sff_proc_fops);
net->can.pde_version = proc_create_net_single(CAN_PROC_VERSION, 0644,
net->can.proc_dir, can_version_proc_show, NULL);
net->can.pde_stats = proc_create_net_single(CAN_PROC_STATS, 0644,
net->can.proc_dir, can_stats_proc_show, NULL);
net->can.pde_reset_stats = proc_create_net_single(CAN_PROC_RESET_STATS,
0644, net->can.proc_dir, can_reset_stats_proc_show,
NULL);
net->can.pde_rcvlist_err = proc_create_net_single(CAN_PROC_RCVLIST_ERR,
0644, net->can.proc_dir, can_rcvlist_proc_show,
(void *)RX_ERR);
net->can.pde_rcvlist_all = proc_create_net_single(CAN_PROC_RCVLIST_ALL,
0644, net->can.proc_dir, can_rcvlist_proc_show,
(void *)RX_ALL);
net->can.pde_rcvlist_fil = proc_create_net_single(CAN_PROC_RCVLIST_FIL,
0644, net->can.proc_dir, can_rcvlist_proc_show,
(void *)RX_FIL);
net->can.pde_rcvlist_inv = proc_create_net_single(CAN_PROC_RCVLIST_INV,
0644, net->can.proc_dir, can_rcvlist_proc_show,
(void *)RX_INV);
net->can.pde_rcvlist_eff = proc_create_net_single(CAN_PROC_RCVLIST_EFF,
0644, net->can.proc_dir, can_rcvlist_eff_proc_show, NULL);
net->can.pde_rcvlist_sff = proc_create_net_single(CAN_PROC_RCVLIST_SFF,
0644, net->can.proc_dir, can_rcvlist_sff_proc_show, NULL);
}

/*
Expand Down
16 changes: 2 additions & 14 deletions net/ipv4/fib_trie.c
Original file line number Diff line number Diff line change
Expand Up @@ -2348,18 +2348,6 @@ static int fib_triestat_seq_show(struct seq_file *seq, void *v)
return 0;
}

static int fib_triestat_seq_open(struct inode *inode, struct file *file)
{
return single_open_net(inode, file, fib_triestat_seq_show);
}

static const struct file_operations fib_triestat_fops = {
.open = fib_triestat_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release_net,
};

static struct key_vector *fib_trie_get_idx(struct seq_file *seq, loff_t pos)
{
struct fib_trie_iter *iter = seq->private;
Expand Down Expand Up @@ -2719,8 +2707,8 @@ int __net_init fib_proc_init(struct net *net)
sizeof(struct fib_trie_iter)))
goto out1;

if (!proc_create("fib_triestat", 0444, net->proc_net,
&fib_triestat_fops))
if (!proc_create_net_single("fib_triestat", 0444, net->proc_net,
fib_triestat_seq_show, NULL))
goto out2;

if (!proc_create_net("route", 0444, net->proc_net, &fib_route_seq_ops,
Expand Down
Loading

0 comments on commit 3617d94

Please sign in to comment.