diff options
author | Xin Long <lucien.xin@gmail.com> | 2016-04-14 15:35:35 +0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-04-15 17:29:37 -0400 |
commit | 53fa10369c45a51947f06e8b622d2fa2cc64fda1 (patch) | |
tree | d8a03375bdd9433670e8d16db957462a480c83fa /net/sctp/proc.c | |
parent | b5e2f4e6998a2b999da8fa0290b692f0bd85c8b7 (diff) |
sctp: fix some rhashtable functions using in sctp proc/diag
When rhashtable_walk_init return err, no release function should be
called, and when rhashtable_walk_start return err, we should only invoke
rhashtable_walk_exit to release the source.
But now when sctp_transport_walk_start return err, we just call
rhashtable_walk_stop/exit, and never care about if rhashtable_walk_init
or start return err, which is so bad.
We will fix it by calling rhashtable_walk_exit if rhashtable_walk_start
return err in sctp_transport_walk_start, and if sctp_transport_walk_start
return err, we do not need to call sctp_transport_walk_stop any more.
For sctp proc, we will use 'iter->start_fail' to decide if we will call
rhashtable_walk_stop/exit.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/proc.c')
-rw-r--r-- | net/sctp/proc.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 9fe139368ad7..4cb5aedfe3ee 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -280,6 +280,7 @@ void sctp_eps_proc_exit(struct net *net) struct sctp_ht_iter { struct seq_net_private p; struct rhashtable_iter hti; + int start_fail; }; static void *sctp_transport_seq_start(struct seq_file *seq, loff_t *pos) @@ -287,8 +288,10 @@ static void *sctp_transport_seq_start(struct seq_file *seq, loff_t *pos) struct sctp_ht_iter *iter = seq->private; int err = sctp_transport_walk_start(&iter->hti); - if (err) + if (err) { + iter->start_fail = 1; return ERR_PTR(err); + } return sctp_transport_get_idx(seq_file_net(seq), &iter->hti, *pos); } @@ -297,6 +300,8 @@ static void sctp_transport_seq_stop(struct seq_file *seq, void *v) { struct sctp_ht_iter *iter = seq->private; + if (iter->start_fail) + return; sctp_transport_walk_stop(&iter->hti); } |