diff options
Diffstat (limited to 'net/tipc/topsrv.c')
| -rw-r--r-- | net/tipc/topsrv.c | 19 | 
1 files changed, 11 insertions, 8 deletions
diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c index 73dbed0c4b6b..1489cfb941d8 100644 --- a/net/tipc/topsrv.c +++ b/net/tipc/topsrv.c @@ -237,8 +237,8 @@ static void tipc_conn_delete_sub(struct tipc_conn *con, struct tipc_subscr *s)  		if (!s || !memcmp(s, &sub->evt.s, sizeof(*s))) {  			tipc_sub_unsubscribe(sub);  			atomic_dec(&tn->subscription_count); -		} else if (s) { -			break; +			if (s) +				break;  		}  	}  	spin_unlock_bh(&con->sub_lock); @@ -362,9 +362,10 @@ static int tipc_conn_rcv_sub(struct tipc_topsrv *srv,  {  	struct tipc_net *tn = tipc_net(srv->net);  	struct tipc_subscription *sub; +	u32 s_filter = tipc_sub_read(s, filter); -	if (tipc_sub_read(s, filter) & TIPC_SUB_CANCEL) { -		s->filter &= __constant_ntohl(~TIPC_SUB_CANCEL); +	if (s_filter & TIPC_SUB_CANCEL) { +		tipc_sub_write(s, filter, s_filter & ~TIPC_SUB_CANCEL);  		tipc_conn_delete_sub(con, s);  		return 0;  	} @@ -400,7 +401,9 @@ static int tipc_conn_rcv_from_sock(struct tipc_conn *con)  		return -EWOULDBLOCK;  	if (ret == sizeof(s)) {  		read_lock_bh(&sk->sk_callback_lock); -		ret = tipc_conn_rcv_sub(srv, con, &s); +		/* RACE: the connection can be closed in the meantime */ +		if (likely(connected(con))) +			ret = tipc_conn_rcv_sub(srv, con, &s);  		read_unlock_bh(&sk->sk_callback_lock);  		if (!ret)  			return 0; @@ -494,7 +497,6 @@ static void tipc_topsrv_listener_data_ready(struct sock *sk)  static int tipc_topsrv_create_listener(struct tipc_topsrv *srv)  { -	int imp = TIPC_CRITICAL_IMPORTANCE;  	struct socket *lsock = NULL;  	struct sockaddr_tipc saddr;  	struct sock *sk; @@ -511,8 +513,9 @@ static int tipc_topsrv_create_listener(struct tipc_topsrv *srv)  	sk->sk_user_data = srv;  	write_unlock_bh(&sk->sk_callback_lock); -	rc = kernel_setsockopt(lsock, SOL_TIPC, TIPC_IMPORTANCE, -			       (char *)&imp, sizeof(imp)); +	lock_sock(sk); +	rc = tsk_set_importance(sk, TIPC_CRITICAL_IMPORTANCE); +	release_sock(sk);  	if (rc < 0)  		goto err;  | 
