caif: Fixes freeze on Link layer removal.
CAIF Socket layer - caif_socket.c: - Plug mem-leak at reconnect. - Always call disconnect to cleanup CAIF stack. - Disconnect will always report success. CAIF configuration layer - cfcnfg.c - Disconnect must dismantle the caif stack correctly - Protect against faulty removals (check on id zero) CAIF mux layer - cfmuxl.c - When inserting new service layer in the MUX remove any old entries with the same ID. - When removing CAIF Link layer, remove the associated service layers before notifying service layers. Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
0e5a117441
commit
54e90fb5ca
@@ -19,7 +19,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/caif/caif_socket.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/tcp_states.h>
|
||||
#include <net/caif/caif_layer.h>
|
||||
@@ -816,6 +816,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
|
||||
if (sk->sk_shutdown & SHUTDOWN_MASK) {
|
||||
/* Allow re-connect after SHUTDOWN_IND */
|
||||
caif_disconnect_client(sock_net(sk), &cf_sk->layer);
|
||||
caif_free_client(&cf_sk->layer);
|
||||
break;
|
||||
}
|
||||
/* No reconnect on a seqpacket socket */
|
||||
@@ -926,7 +927,6 @@ static int caif_release(struct socket *sock)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
|
||||
int res = 0;
|
||||
|
||||
if (!sk)
|
||||
return 0;
|
||||
@@ -953,10 +953,7 @@ static int caif_release(struct socket *sock)
|
||||
sk->sk_state = CAIF_DISCONNECTED;
|
||||
sk->sk_shutdown = SHUTDOWN_MASK;
|
||||
|
||||
if (cf_sk->sk.sk_socket->state == SS_CONNECTED ||
|
||||
cf_sk->sk.sk_socket->state == SS_CONNECTING)
|
||||
res = caif_disconnect_client(sock_net(sk), &cf_sk->layer);
|
||||
|
||||
caif_disconnect_client(sock_net(sk), &cf_sk->layer);
|
||||
cf_sk->sk.sk_socket->state = SS_DISCONNECTING;
|
||||
wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP);
|
||||
|
||||
@@ -964,7 +961,7 @@ static int caif_release(struct socket *sock)
|
||||
sk_stream_kill_queues(&cf_sk->sk);
|
||||
release_sock(sk);
|
||||
sock_put(sk);
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copied from af_unix.c:unix_poll(), added CAIF tx_flow handling */
|
||||
@@ -1120,7 +1117,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
|
||||
set_rx_flow_on(cf_sk);
|
||||
|
||||
/* Set default options on configuration */
|
||||
cf_sk->sk.sk_priority= CAIF_PRIO_NORMAL;
|
||||
cf_sk->sk.sk_priority = CAIF_PRIO_NORMAL;
|
||||
cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY;
|
||||
cf_sk->conn_req.protocol = protocol;
|
||||
/* Increase the number of sockets created. */
|
||||
|
||||
Reference in New Issue
Block a user