Declare the seq_operations and the size of the iterator state and let procfs open and free the seq_file. ->proc_open() only takes the reference to the network namespace now and ->proc_release() drops that and the references the iterator holds. Reading the file then no longer holds up its removal.
Signed-off-by: Christian Brauner (Amutable) <[email protected]> --- net/l2tp/l2tp_ppp.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 4f311d473a64..499e37eb788a 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -1596,21 +1596,17 @@ static const struct seq_operations pppol2tp_seq_ops = { .show = pppol2tp_seq_show, }; +/* procfs opened the seq_file and allocated @pd */ static int pppol2tp_proc_open(struct inode *inode, struct file *file) { - struct net *net = pde_data(inode); - struct pppol2tp_seq_data *pd; + struct seq_file *seq = file->private_data; + struct pppol2tp_seq_data *pd __maybe_unused = seq->private; + struct net *net; - net = maybe_get_net(net); + net = maybe_get_net(pde_data(inode)); if (!net) return -ENXIO; - pd = __seq_open_private(file, &pppol2tp_seq_ops, sizeof(*pd)); - if (!pd) { - put_net(net); - return -ENOMEM; - } - #ifdef CONFIG_NET_NS pd->p.net = net; netns_tracker_alloc(net, &pd->p.ns_tracker, GFP_KERNEL); @@ -1633,13 +1629,13 @@ static int pppol2tp_proc_release(struct inode *inode, struct file *file) #else put_net(&init_net); #endif - return seq_release_private(inode, file); + return 0; } static const struct proc_ops pppol2tp_proc_ops = { + .proc_seq_ops = &pppol2tp_seq_ops, + .proc_state_size = sizeof(struct pppol2tp_seq_data), .proc_open = pppol2tp_proc_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, .proc_release = pppol2tp_proc_release, }; -- 2.53.0
