aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/bluetooth/af_bluetooth.c17
-rw-r--r--net/bluetooth/l2cap_sock.c3
2 files changed, 12 insertions, 8 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index f7c36826f..ca514da7e 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -183,20 +183,25 @@ void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
}
EXPORT_SYMBOL(bt_sock_unlink);
+/* bt_accept_enqueue is used to hold sockets between L2CAP new connection and
+ * connect confirmation calls only .
+ */
void bt_accept_enqueue(struct sock *parent, struct sock *sk)
{
BT_DBG("parent %p, sk %p", parent, sk);
sock_hold(sk);
- list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
bt_sk(sk)->parent = parent;
parent->sk_ack_backlog++;
+ list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
}
EXPORT_SYMBOL(bt_accept_enqueue);
void bt_accept_unlink(struct sock *sk)
{
BT_DBG("sk %p state %d", sk, sk->sk_state);
+ if (!bt_sk(sk)->parent)
+ return;
list_del_init(&bt_sk(sk)->accept_q);
bt_sk(sk)->parent->sk_ack_backlog--;
@@ -205,6 +210,9 @@ void bt_accept_unlink(struct sock *sk)
}
EXPORT_SYMBOL(bt_accept_unlink);
+/* bt_accept_dequeue is called to only on accept ioctl and it returns
+ * sockets in BT_CONNECTED state
+ */
struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
{
struct list_head *p, *n;
@@ -217,13 +225,6 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
lock_sock(sk);
- /* FIXME: Is this check still needed */
- if (sk->sk_state == BT_CLOSED) {
- release_sock(sk);
- bt_accept_unlink(sk);
- continue;
- }
-
if (sk->sk_state == BT_CONNECTED || !newsock ||
test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
bt_accept_unlink(sk);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 4b966c6c0..14a9cad72 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1041,6 +1041,9 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
sk->sk_err = err;
+ /* parent can be valid only when L2CAP connection is confirmed
+ * and accept ioctl call was scheduled on a timeout
+ */
if (parent) {
bt_accept_unlink(sk);
parent->sk_data_ready(parent, 0);