diff options
author | sjur.brandeland@stericsson.com <sjur.brandeland@stericsson.com> | 2011-05-22 07:18:51 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-05-22 20:11:47 -0400 |
commit | 54e90fb5ca8050156d3e748ddc690ed6ea9d71ac (patch) | |
tree | 63a4d1a736a7c44cc88b69e41dec9c4885ef2f74 /net/caif/caif_socket.c | |
parent | 0e5a117441ce245b87949cc7713627a293f37227 (diff) |
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>
Diffstat (limited to 'net/caif/caif_socket.c')
-rw-r--r-- | net/caif/caif_socket.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index b840395ced1d..a98628086452 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
20 | #include <linux/debugfs.h> | 20 | #include <linux/debugfs.h> |
21 | #include <linux/caif/caif_socket.h> | 21 | #include <linux/caif/caif_socket.h> |
22 | #include <asm/atomic.h> | 22 | #include <linux/atomic.h> |
23 | #include <net/sock.h> | 23 | #include <net/sock.h> |
24 | #include <net/tcp_states.h> | 24 | #include <net/tcp_states.h> |
25 | #include <net/caif/caif_layer.h> | 25 | #include <net/caif/caif_layer.h> |
@@ -816,6 +816,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
816 | if (sk->sk_shutdown & SHUTDOWN_MASK) { | 816 | if (sk->sk_shutdown & SHUTDOWN_MASK) { |
817 | /* Allow re-connect after SHUTDOWN_IND */ | 817 | /* Allow re-connect after SHUTDOWN_IND */ |
818 | caif_disconnect_client(sock_net(sk), &cf_sk->layer); | 818 | caif_disconnect_client(sock_net(sk), &cf_sk->layer); |
819 | caif_free_client(&cf_sk->layer); | ||
819 | break; | 820 | break; |
820 | } | 821 | } |
821 | /* No reconnect on a seqpacket socket */ | 822 | /* No reconnect on a seqpacket socket */ |
@@ -926,7 +927,6 @@ static int caif_release(struct socket *sock) | |||
926 | { | 927 | { |
927 | struct sock *sk = sock->sk; | 928 | struct sock *sk = sock->sk; |
928 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | 929 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); |
929 | int res = 0; | ||
930 | 930 | ||
931 | if (!sk) | 931 | if (!sk) |
932 | return 0; | 932 | return 0; |
@@ -953,10 +953,7 @@ static int caif_release(struct socket *sock) | |||
953 | sk->sk_state = CAIF_DISCONNECTED; | 953 | sk->sk_state = CAIF_DISCONNECTED; |
954 | sk->sk_shutdown = SHUTDOWN_MASK; | 954 | sk->sk_shutdown = SHUTDOWN_MASK; |
955 | 955 | ||
956 | if (cf_sk->sk.sk_socket->state == SS_CONNECTED || | 956 | caif_disconnect_client(sock_net(sk), &cf_sk->layer); |
957 | cf_sk->sk.sk_socket->state == SS_CONNECTING) | ||
958 | res = caif_disconnect_client(sock_net(sk), &cf_sk->layer); | ||
959 | |||
960 | cf_sk->sk.sk_socket->state = SS_DISCONNECTING; | 957 | cf_sk->sk.sk_socket->state = SS_DISCONNECTING; |
961 | wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP); | 958 | wake_up_interruptible_poll(sk_sleep(sk), POLLERR|POLLHUP); |
962 | 959 | ||
@@ -964,7 +961,7 @@ static int caif_release(struct socket *sock) | |||
964 | sk_stream_kill_queues(&cf_sk->sk); | 961 | sk_stream_kill_queues(&cf_sk->sk); |
965 | release_sock(sk); | 962 | release_sock(sk); |
966 | sock_put(sk); | 963 | sock_put(sk); |
967 | return res; | 964 | return 0; |
968 | } | 965 | } |
969 | 966 | ||
970 | /* Copied from af_unix.c:unix_poll(), added CAIF tx_flow handling */ | 967 | /* 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, | |||
1120 | set_rx_flow_on(cf_sk); | 1117 | set_rx_flow_on(cf_sk); |
1121 | 1118 | ||
1122 | /* Set default options on configuration */ | 1119 | /* Set default options on configuration */ |
1123 | cf_sk->sk.sk_priority= CAIF_PRIO_NORMAL; | 1120 | cf_sk->sk.sk_priority = CAIF_PRIO_NORMAL; |
1124 | cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; | 1121 | cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; |
1125 | cf_sk->conn_req.protocol = protocol; | 1122 | cf_sk->conn_req.protocol = protocol; |
1126 | /* Increase the number of sockets created. */ | 1123 | /* Increase the number of sockets created. */ |