diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index eff5c38e2219..6ed8bc313db0 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -694,30 +694,9 @@ struct proc_dir_entry *proc_create(const char *name, umode_t mode,
}
EXPORT_SYMBOL(proc_create);
-static int proc_seq_open(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *de = PDE(inode);
-
- if (de->state_size)
- return seq_open_private(file, de->seq_ops, de->state_size);
- return seq_open(file, de->seq_ops);
-}
-
-static int proc_seq_release(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *de = PDE(inode);
-
- if (de->state_size)
- return seq_release_private(inode, file);
- return seq_release(inode, file);
-}
-
+/* procfs owns the seq_file of these, see pde_seq_ops */
static const struct proc_ops proc_seq_ops = {
/* not permanent -- can call into arbitrary seq_operations */
- .proc_open = proc_seq_open,
- .proc_read_iter = seq_read_iter,
- .proc_lseek = seq_lseek,
- .proc_release = proc_seq_release,
};
struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,@@ -732,25 +711,11 @@ struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
p->proc_ops = &proc_seq_ops;
p->seq_ops = ops;
p->state_size = state_size;
+ p->flags |= PROC_ENTRY_proc_seq_ops;
return proc_register(parent, p);
}
EXPORT_SYMBOL(proc_create_seq_private);
-static int proc_single_open(struct inode *inode, struct file *file)
-{
- struct proc_dir_entry *de = PDE(inode);
-
- return single_open(file, de->single_show, de->data);
-}
-
-static const struct proc_ops proc_single_ops = {
- /* not permanent -- can call into arbitrary ->single_show */
- .proc_open = proc_single_open,
- .proc_read_iter = seq_read_iter,
- .proc_lseek = seq_lseek,
- .proc_release = single_release,
-};
-
struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
struct proc_dir_entry *parent,
int (*show)(struct seq_file *, void *), void *data)@@ -760,8 +725,9 @@ struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
p = proc_create_reg(name, mode, &parent, data);
if (!p)
return NULL;
- p->proc_ops = &proc_single_ops;
+ p->proc_ops = &proc_seq_ops;
p->single_show = show;
+ p->flags |= PROC_ENTRY_proc_show;
return proc_register(parent, p);
}
EXPORT_SYMBOL(proc_create_single_data);
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index df5484813d5d..fa485581d05e 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -37,13 +37,13 @@ static struct net *get_proc_net(const struct inode *inode)
return maybe_get_net(PDE_NET(PDE(inode)));
}
+/* procfs opened the seq_file and allocated its state, see pde_seq_ops */
static int seq_open_net(struct inode *inode, struct file *file)
{
- unsigned int state_size = PDE(inode)->state_size;
- struct seq_net_private *p;
+ struct seq_net_private *p = ((struct seq_file *)file->private_data)->private;
struct net *net;
- WARN_ON_ONCE(state_size < sizeof(*p));
+ WARN_ON_ONCE(PDE(inode)->state_size < sizeof(*p));
if (file->f_mode & FMODE_WRITE && !PDE(inode)->write)
return -EACCES;@@ -51,12 +51,6 @@ static int seq_open_net(struct inode *inode, struct file *file)
net = get_proc_net(inode);
if (!net)
return -ENXIO;
-
- p = __seq_open_private(file, PDE(inode)->seq_ops, state_size);
- if (!p) {
- put_net(net);
- return -ENOMEM;
- }
#ifdef CONFIG_NET_NS
p->net = net;
netns_tracker_alloc(net, &p->ns_tracker, GFP_KERNEL);@@ -77,18 +71,13 @@ static void seq_file_net_put_net(struct seq_file *seq)
static int seq_release_net(struct inode *ino, struct file *f)
{
- struct seq_file *seq = f->private_data;
-
- seq_file_net_put_net(seq);
- seq_release_private(ino, f);
+ seq_file_net_put_net(f->private_data);
return 0;
}
static const struct proc_ops proc_net_seq_ops = {
.proc_open = seq_open_net,
- .proc_read = seq_read,
.proc_write = proc_simple_write,
- .proc_lseek = seq_lseek,
.proc_release = seq_release_net,
};
@@ -125,6 +114,7 @@ struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode,
p->proc_ops = &proc_net_seq_ops;
p->seq_ops = ops;
p->state_size = state_size;
+ p->flags |= PROC_ENTRY_proc_seq_ops;
return proc_register(parent, p);
}
EXPORT_SYMBOL_GPL(proc_create_net_data);
@@ -170,6 +160,7 @@ struct proc_dir_entry *proc_create_net_data_write(const char *name, umode_t mode
p->proc_ops = &proc_net_seq_ops;
p->seq_ops = ops;
p->state_size = state_size;
+ p->flags |= PROC_ENTRY_proc_seq_ops;
p->write = write;
return proc_register(parent, p);
}
@@ -177,32 +168,25 @@ EXPORT_SYMBOL_GPL(proc_create_net_data_write);
static int single_open_net(struct inode *inode, struct file *file)
{
- struct proc_dir_entry *de = PDE(inode);
- struct net *net;
- int err;
+ struct net *net = get_proc_net(inode);
- net = get_proc_net(inode);
if (!net)
return -ENXIO;
-
- err = single_open(file, de->single_show, net);
- if (err)
- put_net(net);
- return err;
+ ((struct seq_file *)file->private_data)->private = net;
+ return 0;
}
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);
+ return 0;
}
static const struct proc_ops proc_net_single_ops = {
.proc_open = single_open_net,
- .proc_read = seq_read,
.proc_write = proc_simple_write,
- .proc_lseek = seq_lseek,
.proc_release = single_release_net,
};
@@ -218,6 +202,7 @@ struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode,
pde_force_lookup(p);
p->proc_ops = &proc_net_single_ops;
p->single_show = show;
+ p->flags |= PROC_ENTRY_proc_show;
return proc_register(parent, p);
}
EXPORT_SYMBOL_GPL(proc_create_net_single);
@@ -261,6 +246,7 @@ struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mo
pde_force_lookup(p);
p->proc_ops = &proc_net_single_ops;
p->single_show = show;
+ p->flags |= PROC_ENTRY_proc_show;
p->write = write;
return proc_register(parent, p);
}
--
2.53.0