aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/l2cap.h5
-rw-r--r--net/bluetooth/l2cap_core.c24
2 files changed, 7 insertions, 22 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index ddf4bc56a5b5..d24b51c3ff8c 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -309,11 +309,6 @@ struct l2cap_conn {
309 rwlock_t chan_lock; 309 rwlock_t chan_lock;
310}; 310};
311 311
312struct sock_del_list {
313 struct sock *sk;
314 struct list_head list;
315};
316
317#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 312#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
318#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04 313#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x04
319#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08 314#define L2CAP_INFO_FEAT_MASK_REQ_DONE 0x08
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0dbbaf394c13..b0aaaa9cf00e 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -487,16 +487,13 @@ void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err)
487/* ---- L2CAP connections ---- */ 487/* ---- L2CAP connections ---- */
488static void l2cap_conn_start(struct l2cap_conn *conn) 488static void l2cap_conn_start(struct l2cap_conn *conn)
489{ 489{
490 struct sock_del_list del, *tmp1, *tmp2; 490 struct l2cap_chan *chan, *tmp;
491 struct l2cap_chan *chan;
492 491
493 BT_DBG("conn %p", conn); 492 BT_DBG("conn %p", conn);
494 493
495 INIT_LIST_HEAD(&del.list);
496
497 read_lock(&conn->chan_lock); 494 read_lock(&conn->chan_lock);
498 495
499 list_for_each_entry(chan, &conn->chan_l, list) { 496 list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
500 struct sock *sk = chan->sk; 497 struct sock *sk = chan->sk;
501 498
502 bh_lock_sock(sk); 499 bh_lock_sock(sk);
@@ -520,10 +517,11 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
520 conn->feat_mask) 517 conn->feat_mask)
521 && l2cap_pi(sk)->conf_state & 518 && l2cap_pi(sk)->conf_state &
522 L2CAP_CONF_STATE2_DEVICE) { 519 L2CAP_CONF_STATE2_DEVICE) {
523 tmp1 = kzalloc(sizeof(struct sock_del_list), 520 /* __l2cap_sock_close() calls list_del(chan)
524 GFP_ATOMIC); 521 * so release the lock */
525 tmp1->sk = sk; 522 read_unlock_bh(&conn->chan_lock);
526 list_add_tail(&tmp1->list, &del.list); 523 __l2cap_sock_close(sk, ECONNRESET);
524 read_lock_bh(&conn->chan_lock);
527 bh_unlock_sock(sk); 525 bh_unlock_sock(sk);
528 continue; 526 continue;
529 } 527 }
@@ -579,14 +577,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
579 } 577 }
580 578
581 read_unlock(&conn->chan_lock); 579 read_unlock(&conn->chan_lock);
582
583 list_for_each_entry_safe(tmp1, tmp2, &del.list, list) {
584 bh_lock_sock(tmp1->sk);
585 __l2cap_sock_close(tmp1->sk, ECONNRESET);
586 bh_unlock_sock(tmp1->sk);
587 list_del(&tmp1->list);
588 kfree(tmp1);
589 }
590} 580}
591 581
592/* Find socket with cid and source bdaddr. 582/* Find socket with cid and source bdaddr.