aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 42d2fb94eff1..7fc6b4da4f02 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -140,6 +140,15 @@ static struct hlist_head *nl_pid_hashfn(struct nl_pid_hash *hash, u32 pid)
140 140
141static void netlink_sock_destruct(struct sock *sk) 141static void netlink_sock_destruct(struct sock *sk)
142{ 142{
143 struct netlink_sock *nlk = nlk_sk(sk);
144
145 BUG_ON(mutex_is_locked(nlk_sk(sk)->cb_mutex));
146 if (nlk->cb) {
147 if (nlk->cb->done)
148 nlk->cb->done(nlk->cb);
149 netlink_destroy_callback(nlk->cb);
150 }
151
143 skb_queue_purge(&sk->sk_receive_queue); 152 skb_queue_purge(&sk->sk_receive_queue);
144 153
145 if (!sock_flag(sk, SOCK_DEAD)) { 154 if (!sock_flag(sk, SOCK_DEAD)) {
@@ -148,7 +157,6 @@ static void netlink_sock_destruct(struct sock *sk)
148 } 157 }
149 BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); 158 BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc));
150 BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc)); 159 BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc));
151 BUG_TRAP(!nlk_sk(sk)->cb);
152 BUG_TRAP(!nlk_sk(sk)->groups); 160 BUG_TRAP(!nlk_sk(sk)->groups);
153} 161}
154 162
@@ -456,17 +464,10 @@ static int netlink_release(struct socket *sock)
456 sock_orphan(sk); 464 sock_orphan(sk);
457 nlk = nlk_sk(sk); 465 nlk = nlk_sk(sk);
458 466
459 mutex_lock(nlk->cb_mutex); 467 /*
460 if (nlk->cb) { 468 * OK. Socket is unlinked, any packets that arrive now
461 if (nlk->cb->done) 469 * will be purged.
462 nlk->cb->done(nlk->cb); 470 */
463 netlink_destroy_callback(nlk->cb);
464 nlk->cb = NULL;
465 }
466 mutex_unlock(nlk->cb_mutex);
467
468 /* OK. Socket is unlinked, and, therefore,
469 no new packets will arrive */
470 471
471 sock->sk = NULL; 472 sock->sk = NULL;
472 wake_up_interruptible_all(&nlk->wait); 473 wake_up_interruptible_all(&nlk->wait);
@@ -1426,9 +1427,9 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1426 return -ECONNREFUSED; 1427 return -ECONNREFUSED;
1427 } 1428 }
1428 nlk = nlk_sk(sk); 1429 nlk = nlk_sk(sk);
1429 /* A dump or destruction is in progress... */ 1430 /* A dump is in progress... */
1430 mutex_lock(nlk->cb_mutex); 1431 mutex_lock(nlk->cb_mutex);
1431 if (nlk->cb || sock_flag(sk, SOCK_DEAD)) { 1432 if (nlk->cb) {
1432 mutex_unlock(nlk->cb_mutex); 1433 mutex_unlock(nlk->cb_mutex);
1433 netlink_destroy_callback(cb); 1434 netlink_destroy_callback(cb);
1434 sock_put(sk); 1435 sock_put(sk);