diff options
Diffstat (limited to 'net/bluetooth/rfcomm/sock.c')
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index aec505f934df..66cc1f0c3df8 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -45,7 +45,7 @@ | |||
45 | #include <net/sock.h> | 45 | #include <net/sock.h> |
46 | 46 | ||
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | #include <asm/uaccess.h> | 48 | #include <linux/uaccess.h> |
49 | 49 | ||
50 | #include <net/bluetooth/bluetooth.h> | 50 | #include <net/bluetooth/bluetooth.h> |
51 | #include <net/bluetooth/hci_core.h> | 51 | #include <net/bluetooth/hci_core.h> |
@@ -140,11 +140,13 @@ static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src) | |||
140 | /* Find socket with channel and source bdaddr. | 140 | /* Find socket with channel and source bdaddr. |
141 | * Returns closest match. | 141 | * Returns closest match. |
142 | */ | 142 | */ |
143 | static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src) | 143 | static struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src) |
144 | { | 144 | { |
145 | struct sock *sk = NULL, *sk1 = NULL; | 145 | struct sock *sk = NULL, *sk1 = NULL; |
146 | struct hlist_node *node; | 146 | struct hlist_node *node; |
147 | 147 | ||
148 | read_lock(&rfcomm_sk_list.lock); | ||
149 | |||
148 | sk_for_each(sk, node, &rfcomm_sk_list.head) { | 150 | sk_for_each(sk, node, &rfcomm_sk_list.head) { |
149 | if (state && sk->sk_state != state) | 151 | if (state && sk->sk_state != state) |
150 | continue; | 152 | continue; |
@@ -159,19 +161,10 @@ static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t | |||
159 | sk1 = sk; | 161 | sk1 = sk; |
160 | } | 162 | } |
161 | } | 163 | } |
162 | return node ? sk : sk1; | ||
163 | } | ||
164 | 164 | ||
165 | /* Find socket with given address (channel, src). | ||
166 | * Returns locked socket */ | ||
167 | static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src) | ||
168 | { | ||
169 | struct sock *s; | ||
170 | read_lock(&rfcomm_sk_list.lock); | ||
171 | s = __rfcomm_get_sock_by_channel(state, channel, src); | ||
172 | if (s) bh_lock_sock(s); | ||
173 | read_unlock(&rfcomm_sk_list.lock); | 165 | read_unlock(&rfcomm_sk_list.lock); |
174 | return s; | 166 | |
167 | return node ? sk : sk1; | ||
175 | } | 168 | } |
176 | 169 | ||
177 | static void rfcomm_sock_destruct(struct sock *sk) | 170 | static void rfcomm_sock_destruct(struct sock *sk) |
@@ -895,7 +888,8 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how) | |||
895 | 888 | ||
896 | BT_DBG("sock %p, sk %p", sock, sk); | 889 | BT_DBG("sock %p, sk %p", sock, sk); |
897 | 890 | ||
898 | if (!sk) return 0; | 891 | if (!sk) |
892 | return 0; | ||
899 | 893 | ||
900 | lock_sock(sk); | 894 | lock_sock(sk); |
901 | if (!sk->sk_shutdown) { | 895 | if (!sk->sk_shutdown) { |
@@ -945,6 +939,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * | |||
945 | if (!parent) | 939 | if (!parent) |
946 | return 0; | 940 | return 0; |
947 | 941 | ||
942 | bh_lock_sock(parent); | ||
943 | |||
948 | /* Check for backlog size */ | 944 | /* Check for backlog size */ |
949 | if (sk_acceptq_is_full(parent)) { | 945 | if (sk_acceptq_is_full(parent)) { |
950 | BT_DBG("backlog full %d", parent->sk_ack_backlog); | 946 | BT_DBG("backlog full %d", parent->sk_ack_backlog); |