Commit 83494407 authored by Guillaume Nault's avatar Guillaume Nault Committed by David S. Miller

l2tp: consistent reference counting in procfs and debufs

The 'pppol2tp' procfs and 'l2tp/tunnels' debugfs files handle reference
counting of sessions differently than for tunnels.

For consistency, use the same mechanism for handling both sessions and
tunnels. That is, drop the reference on the previous session just
before looking up the next one (rather than in .show()). If necessary
(if dump stops before *_next_session() returns NULL), drop the last
reference in .stop().
Signed-off-by: default avatarGuillaume Nault <g.nault@alphalink.fr>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3e5cf362
...@@ -57,6 +57,10 @@ static void l2tp_dfs_next_tunnel(struct l2tp_dfs_seq_data *pd) ...@@ -57,6 +57,10 @@ static void l2tp_dfs_next_tunnel(struct l2tp_dfs_seq_data *pd)
static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd) static void l2tp_dfs_next_session(struct l2tp_dfs_seq_data *pd)
{ {
/* Drop reference taken during previous invocation */
if (pd->session)
l2tp_session_dec_refcount(pd->session);
pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx); pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx);
pd->session_idx++; pd->session_idx++;
...@@ -105,11 +109,16 @@ static void l2tp_dfs_seq_stop(struct seq_file *p, void *v) ...@@ -105,11 +109,16 @@ static void l2tp_dfs_seq_stop(struct seq_file *p, void *v)
if (!pd || pd == SEQ_START_TOKEN) if (!pd || pd == SEQ_START_TOKEN)
return; return;
/* Drop reference taken by last invocation of l2tp_dfs_next_tunnel() */ /* Drop reference taken by last invocation of l2tp_dfs_next_session()
* or l2tp_dfs_next_tunnel().
*/
if (pd->session) {
l2tp_session_dec_refcount(pd->session);
pd->session = NULL;
}
if (pd->tunnel) { if (pd->tunnel) {
l2tp_tunnel_dec_refcount(pd->tunnel); l2tp_tunnel_dec_refcount(pd->tunnel);
pd->tunnel = NULL; pd->tunnel = NULL;
pd->session = NULL;
} }
} }
...@@ -250,13 +259,10 @@ static int l2tp_dfs_seq_show(struct seq_file *m, void *v) ...@@ -250,13 +259,10 @@ static int l2tp_dfs_seq_show(struct seq_file *m, void *v)
goto out; goto out;
} }
/* Show the tunnel or session context */ if (!pd->session)
if (!pd->session) {
l2tp_dfs_seq_tunnel_show(m, pd->tunnel); l2tp_dfs_seq_tunnel_show(m, pd->tunnel);
} else { else
l2tp_dfs_seq_session_show(m, pd->session); l2tp_dfs_seq_session_show(m, pd->session);
l2tp_session_dec_refcount(pd->session);
}
out: out:
return 0; return 0;
......
...@@ -1576,6 +1576,10 @@ static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd) ...@@ -1576,6 +1576,10 @@ static void pppol2tp_next_tunnel(struct net *net, struct pppol2tp_seq_data *pd)
static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd) static void pppol2tp_next_session(struct net *net, struct pppol2tp_seq_data *pd)
{ {
/* Drop reference taken during previous invocation */
if (pd->session)
l2tp_session_dec_refcount(pd->session);
pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx); pd->session = l2tp_session_get_nth(pd->tunnel, pd->session_idx);
pd->session_idx++; pd->session_idx++;
...@@ -1624,11 +1628,16 @@ static void pppol2tp_seq_stop(struct seq_file *p, void *v) ...@@ -1624,11 +1628,16 @@ static void pppol2tp_seq_stop(struct seq_file *p, void *v)
if (!pd || pd == SEQ_START_TOKEN) if (!pd || pd == SEQ_START_TOKEN)
return; return;
/* Drop reference taken by last invocation of pppol2tp_next_tunnel() */ /* Drop reference taken by last invocation of pppol2tp_next_session()
* or pppol2tp_next_tunnel().
*/
if (pd->session) {
l2tp_session_dec_refcount(pd->session);
pd->session = NULL;
}
if (pd->tunnel) { if (pd->tunnel) {
l2tp_tunnel_dec_refcount(pd->tunnel); l2tp_tunnel_dec_refcount(pd->tunnel);
pd->tunnel = NULL; pd->tunnel = NULL;
pd->session = NULL;
} }
} }
...@@ -1723,14 +1732,10 @@ static int pppol2tp_seq_show(struct seq_file *m, void *v) ...@@ -1723,14 +1732,10 @@ static int pppol2tp_seq_show(struct seq_file *m, void *v)
goto out; goto out;
} }
/* Show the tunnel or session context. if (!pd->session)
*/
if (!pd->session) {
pppol2tp_seq_tunnel_show(m, pd->tunnel); pppol2tp_seq_tunnel_show(m, pd->tunnel);
} else { else
pppol2tp_seq_session_show(m, pd->session); pppol2tp_seq_session_show(m, pd->session);
l2tp_session_dec_refcount(pd->session);
}
out: out:
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment