diff options
author | Johannes Berg <johannes.berg@intel.com> | 2014-12-22 12:56:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-27 02:20:23 -0500 |
commit | b10dcb3b94010e3ac3951f68789400b1665effb1 (patch) | |
tree | 5ec269ffbedc0117a3246ad32691b78e03402abd /net | |
parent | f8403a2e47afb37bcd3b7e286996d138a116c39d (diff) |
netlink: update listeners directly when removing socket
The code is now confusing to read - first in one function down
(netlink_remove) any group subscriptions are implicitly removed
by calling __sk_del_bind_node(), but the subscriber database is
only updated far later by calling netlink_update_listeners().
Move the latter call to just after removal from the list so it
is easier to follow the code.
This also enables moving the locking inside the kernel-socket
conditional, which improves the normal socket destruction path.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/netlink/af_netlink.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index b4cf8ee0e1b8..6a9fb7c489a8 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1091,8 +1091,10 @@ static void netlink_remove(struct sock *sk) | |||
1091 | mutex_unlock(&nl_sk_hash_lock); | 1091 | mutex_unlock(&nl_sk_hash_lock); |
1092 | 1092 | ||
1093 | netlink_table_grab(); | 1093 | netlink_table_grab(); |
1094 | if (nlk_sk(sk)->subscriptions) | 1094 | if (nlk_sk(sk)->subscriptions) { |
1095 | __sk_del_bind_node(sk); | 1095 | __sk_del_bind_node(sk); |
1096 | netlink_update_listeners(sk); | ||
1097 | } | ||
1096 | netlink_table_ungrab(); | 1098 | netlink_table_ungrab(); |
1097 | } | 1099 | } |
1098 | 1100 | ||
@@ -1226,8 +1228,8 @@ static int netlink_release(struct socket *sock) | |||
1226 | 1228 | ||
1227 | module_put(nlk->module); | 1229 | module_put(nlk->module); |
1228 | 1230 | ||
1229 | netlink_table_grab(); | ||
1230 | if (netlink_is_kernel(sk)) { | 1231 | if (netlink_is_kernel(sk)) { |
1232 | netlink_table_grab(); | ||
1231 | BUG_ON(nl_table[sk->sk_protocol].registered == 0); | 1233 | BUG_ON(nl_table[sk->sk_protocol].registered == 0); |
1232 | if (--nl_table[sk->sk_protocol].registered == 0) { | 1234 | if (--nl_table[sk->sk_protocol].registered == 0) { |
1233 | struct listeners *old; | 1235 | struct listeners *old; |
@@ -1241,10 +1243,8 @@ static int netlink_release(struct socket *sock) | |||
1241 | nl_table[sk->sk_protocol].flags = 0; | 1243 | nl_table[sk->sk_protocol].flags = 0; |
1242 | nl_table[sk->sk_protocol].registered = 0; | 1244 | nl_table[sk->sk_protocol].registered = 0; |
1243 | } | 1245 | } |
1244 | } else if (nlk->subscriptions) { | 1246 | netlink_table_ungrab(); |
1245 | netlink_update_listeners(sk); | ||
1246 | } | 1247 | } |
1247 | netlink_table_ungrab(); | ||
1248 | 1248 | ||
1249 | kfree(nlk->groups); | 1249 | kfree(nlk->groups); |
1250 | nlk->groups = NULL; | 1250 | nlk->groups = NULL; |