Commit 3617d949 authored by Christoph Hellwig's avatar Christoph Hellwig
Browse files

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: default avatarChristoph Hellwig <hch@lst.de>
parent c3506372
Loading
Loading
Loading
Loading
+31 −18
Original line number Diff line number Diff line
@@ -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:
	err = single_open(file, de->single_show, net);
	if (err)
		put_net(net);
err_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)
{
+4 −0
Original line number Diff line number Diff line
@@ -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 */

@@ -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 */

+2 −5
Original line number Diff line number Diff line
@@ -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
@@ -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)
{
+2 −14
Original line number Diff line number Diff line
@@ -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 */

/*
@@ -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;
+23 −104
Original line number Diff line number Diff line
@@ -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;
@@ -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)
@@ -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,
@@ -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;
@@ -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
 */
@@ -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,
	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_data(CAN_PROC_RCVLIST_ALL, 0644,
						    net->can.proc_dir,
						    &can_rcvlist_proc_fops,
	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_data(CAN_PROC_RCVLIST_FIL, 0644,
						    net->can.proc_dir,
						    &can_rcvlist_proc_fops,
	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_data(CAN_PROC_RCVLIST_INV, 0644,
						    net->can.proc_dir,
						    &can_rcvlist_proc_fops,
	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(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_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);
}

/*
Loading