aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-10-21 12:21:41 -0400
committerMarcel Holtmann <marcel@holtmann.org>2013-10-21 15:58:17 -0400
commit8ffb929098a56939ac71509302eeab5b207bf262 (patch)
treede225f0dd51cafce59f2d0f3f60c460699f88271 /net
parentf93fa2732313ca31ebdc68fd2d5b67fd1d363b42 (diff)
Bluetooth: Remove parent socket usage from l2cap_core.c
The parent socket is not used inside the L2CAP core anymore. We only lock it to indirect access through the new_connection() callback. The hold of the socket lock was moved to the new_connection() callback. Inside L2CAP core the channel lock is now used in l2cap_le_conn_ready() and l2cap_conn_ready() to protect the execution of these two functions during the handling of new incoming connections. This change remove the socket lock usage from L2CAP core while keeping the code safe against race conditions. Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/l2cap_core.c14
-rw-r--r--net/bluetooth/l2cap_sock.c4
2 files changed, 8 insertions, 10 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index c65ddc8e7689..bb6d35e6b832 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1362,7 +1362,6 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
1362static void l2cap_le_conn_ready(struct l2cap_conn *conn) 1362static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1363{ 1363{
1364 struct hci_conn *hcon = conn->hcon; 1364 struct hci_conn *hcon = conn->hcon;
1365 struct sock *parent;
1366 struct l2cap_chan *chan, *pchan; 1365 struct l2cap_chan *chan, *pchan;
1367 u8 dst_type; 1366 u8 dst_type;
1368 1367
@@ -1384,9 +1383,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1384 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type)) 1383 if (hci_blacklist_lookup(hcon->hdev, &hcon->dst, dst_type))
1385 return; 1384 return;
1386 1385
1387 parent = pchan->sk; 1386 l2cap_chan_lock(pchan);
1388
1389 lock_sock(parent);
1390 1387
1391 chan = pchan->ops->new_connection(pchan); 1388 chan = pchan->ops->new_connection(pchan);
1392 if (!chan) 1389 if (!chan)
@@ -1402,7 +1399,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
1402 __l2cap_chan_add(conn, chan); 1399 __l2cap_chan_add(conn, chan);
1403 1400
1404clean: 1401clean:
1405 release_sock(parent); 1402 l2cap_chan_unlock(pchan);
1406} 1403}
1407 1404
1408static void l2cap_conn_ready(struct l2cap_conn *conn) 1405static void l2cap_conn_ready(struct l2cap_conn *conn)
@@ -3705,7 +3702,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3705 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; 3702 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
3706 struct l2cap_conn_rsp rsp; 3703 struct l2cap_conn_rsp rsp;
3707 struct l2cap_chan *chan = NULL, *pchan; 3704 struct l2cap_chan *chan = NULL, *pchan;
3708 struct sock *parent;
3709 int result, status = L2CAP_CS_NO_INFO; 3705 int result, status = L2CAP_CS_NO_INFO;
3710 3706
3711 u16 dcid = 0, scid = __le16_to_cpu(req->scid); 3707 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3721,10 +3717,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3721 goto sendresp; 3717 goto sendresp;
3722 } 3718 }
3723 3719
3724 parent = pchan->sk;
3725
3726 mutex_lock(&conn->chan_lock); 3720 mutex_lock(&conn->chan_lock);
3727 lock_sock(parent); 3721 l2cap_chan_lock(pchan);
3728 3722
3729 /* Check if the ACL is secure enough (if not SDP) */ 3723 /* Check if the ACL is secure enough (if not SDP) */
3730 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) && 3724 if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
@@ -3800,7 +3794,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
3800 } 3794 }
3801 3795
3802response: 3796response:
3803 release_sock(parent); 3797 l2cap_chan_unlock(pchan);
3804 mutex_unlock(&conn->chan_lock); 3798 mutex_unlock(&conn->chan_lock);
3805 3799
3806sendresp: 3800sendresp:
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index e55999228c8a..a159b0e05202 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1042,6 +1042,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
1042{ 1042{
1043 struct sock *sk, *parent = chan->data; 1043 struct sock *sk, *parent = chan->data;
1044 1044
1045 lock_sock(parent);
1046
1045 /* Check for backlog size */ 1047 /* Check for backlog size */
1046 if (sk_acceptq_is_full(parent)) { 1048 if (sk_acceptq_is_full(parent)) {
1047 BT_DBG("backlog full %d", parent->sk_ack_backlog); 1049 BT_DBG("backlog full %d", parent->sk_ack_backlog);
@@ -1059,6 +1061,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
1059 1061
1060 bt_accept_enqueue(parent, sk); 1062 bt_accept_enqueue(parent, sk);
1061 1063
1064 release_sock(parent);
1065
1062 return l2cap_pi(sk)->chan; 1066 return l2cap_pi(sk)->chan;
1063} 1067}
1064 1068