Prechádzať zdrojové kódy

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>
Johannes Berg 10 rokov pred
rodič
commit
b10dcb3b94
1 zmenil súbory, kde vykonal 5 pridanie a 5 odobranie
  1. 5 5
      net/netlink/af_netlink.c

+ 5 - 5
net/netlink/af_netlink.c

@@ -1091,8 +1091,10 @@ static void netlink_remove(struct sock *sk)
 	mutex_unlock(&nl_sk_hash_lock);
 	mutex_unlock(&nl_sk_hash_lock);
 
 
 	netlink_table_grab();
 	netlink_table_grab();
-	if (nlk_sk(sk)->subscriptions)
+	if (nlk_sk(sk)->subscriptions) {
 		__sk_del_bind_node(sk);
 		__sk_del_bind_node(sk);
+		netlink_update_listeners(sk);
+	}
 	netlink_table_ungrab();
 	netlink_table_ungrab();
 }
 }
 
 
@@ -1226,8 +1228,8 @@ static int netlink_release(struct socket *sock)
 
 
 	module_put(nlk->module);
 	module_put(nlk->module);
 
 
-	netlink_table_grab();
 	if (netlink_is_kernel(sk)) {
 	if (netlink_is_kernel(sk)) {
+		netlink_table_grab();
 		BUG_ON(nl_table[sk->sk_protocol].registered == 0);
 		BUG_ON(nl_table[sk->sk_protocol].registered == 0);
 		if (--nl_table[sk->sk_protocol].registered == 0) {
 		if (--nl_table[sk->sk_protocol].registered == 0) {
 			struct listeners *old;
 			struct listeners *old;
@@ -1241,10 +1243,8 @@ static int netlink_release(struct socket *sock)
 			nl_table[sk->sk_protocol].flags = 0;
 			nl_table[sk->sk_protocol].flags = 0;
 			nl_table[sk->sk_protocol].registered = 0;
 			nl_table[sk->sk_protocol].registered = 0;
 		}
 		}
-	} else if (nlk->subscriptions) {
-		netlink_update_listeners(sk);
+		netlink_table_ungrab();
 	}
 	}
-	netlink_table_ungrab();
 
 
 	kfree(nlk->groups);
 	kfree(nlk->groups);
 	nlk->groups = NULL;
 	nlk->groups = NULL;