diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netlink/af_netlink.c | 29 |
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 | ||
141 | static void netlink_sock_destruct(struct sock *sk) | 141 | static 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); |