diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2013-10-21 12:21:40 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2013-10-21 15:58:17 -0400 |
commit | f93fa2732313ca31ebdc68fd2d5b67fd1d363b42 (patch) | |
tree | aa378097cdf605ca07e040dd7aa4f7e351705128 /net | |
parent | acdcabf532908fbefbea294fcad2e3989d1dc036 (diff) |
Bluetooth: Remove socket lock from l2cap_state_change()
This simplify and make safer the state change handling inside l2cap_core.c.
we got rid of __l2cap_state_change(). And l2cap_state_change() doesn't lock
the socket anymore, instead the socket is locked inside the ops callback for
state change in l2cap_sock.c.
It makes the code safer because in some we were using a unlocked version,
and now we are calls to l2cap_state_change(), when dealing with sockets, use
the locked version.
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.c | 31 |
1 files changed, 7 insertions, 24 deletions
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 049e1c81d771..c65ddc8e7689 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -223,7 +223,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | static void __l2cap_state_change(struct l2cap_chan *chan, int state) | 226 | static void l2cap_state_change(struct l2cap_chan *chan, int state) |
227 | { | 227 | { |
228 | BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), | 228 | BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state), |
229 | state_to_string(state)); | 229 | state_to_string(state)); |
@@ -232,33 +232,16 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state) | |||
232 | chan->ops->state_change(chan, state, 0); | 232 | chan->ops->state_change(chan, state, 0); |
233 | } | 233 | } |
234 | 234 | ||
235 | static void l2cap_state_change(struct l2cap_chan *chan, int state) | ||
236 | { | ||
237 | struct sock *sk = chan->sk; | ||
238 | |||
239 | lock_sock(sk); | ||
240 | __l2cap_state_change(chan, state); | ||
241 | release_sock(sk); | ||
242 | } | ||
243 | |||
244 | static inline void l2cap_state_change_and_error(struct l2cap_chan *chan, | 235 | static inline void l2cap_state_change_and_error(struct l2cap_chan *chan, |
245 | int state, int err) | 236 | int state, int err) |
246 | { | 237 | { |
247 | struct sock *sk = chan->sk; | ||
248 | |||
249 | lock_sock(sk); | ||
250 | chan->state = state; | 238 | chan->state = state; |
251 | chan->ops->state_change(chan, chan->state, err); | 239 | chan->ops->state_change(chan, chan->state, err); |
252 | release_sock(sk); | ||
253 | } | 240 | } |
254 | 241 | ||
255 | static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err) | 242 | static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err) |
256 | { | 243 | { |
257 | struct sock *sk = chan->sk; | ||
258 | |||
259 | lock_sock(sk); | ||
260 | chan->ops->state_change(chan, chan->state, err); | 244 | chan->ops->state_change(chan, chan->state, err); |
261 | release_sock(sk); | ||
262 | } | 245 | } |
263 | 246 | ||
264 | static void __set_retrans_timer(struct l2cap_chan *chan) | 247 | static void __set_retrans_timer(struct l2cap_chan *chan) |
@@ -3787,7 +3770,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3787 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { | 3770 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) { |
3788 | if (l2cap_chan_check_security(chan)) { | 3771 | if (l2cap_chan_check_security(chan)) { |
3789 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { | 3772 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { |
3790 | __l2cap_state_change(chan, BT_CONNECT2); | 3773 | l2cap_state_change(chan, BT_CONNECT2); |
3791 | result = L2CAP_CR_PEND; | 3774 | result = L2CAP_CR_PEND; |
3792 | status = L2CAP_CS_AUTHOR_PEND; | 3775 | status = L2CAP_CS_AUTHOR_PEND; |
3793 | chan->ops->defer(chan); | 3776 | chan->ops->defer(chan); |
@@ -3797,21 +3780,21 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3797 | * physical link is up. | 3780 | * physical link is up. |
3798 | */ | 3781 | */ |
3799 | if (amp_id == AMP_ID_BREDR) { | 3782 | if (amp_id == AMP_ID_BREDR) { |
3800 | __l2cap_state_change(chan, BT_CONFIG); | 3783 | l2cap_state_change(chan, BT_CONFIG); |
3801 | result = L2CAP_CR_SUCCESS; | 3784 | result = L2CAP_CR_SUCCESS; |
3802 | } else { | 3785 | } else { |
3803 | __l2cap_state_change(chan, BT_CONNECT2); | 3786 | l2cap_state_change(chan, BT_CONNECT2); |
3804 | result = L2CAP_CR_PEND; | 3787 | result = L2CAP_CR_PEND; |
3805 | } | 3788 | } |
3806 | status = L2CAP_CS_NO_INFO; | 3789 | status = L2CAP_CS_NO_INFO; |
3807 | } | 3790 | } |
3808 | } else { | 3791 | } else { |
3809 | __l2cap_state_change(chan, BT_CONNECT2); | 3792 | l2cap_state_change(chan, BT_CONNECT2); |
3810 | result = L2CAP_CR_PEND; | 3793 | result = L2CAP_CR_PEND; |
3811 | status = L2CAP_CS_AUTHEN_PEND; | 3794 | status = L2CAP_CS_AUTHEN_PEND; |
3812 | } | 3795 | } |
3813 | } else { | 3796 | } else { |
3814 | __l2cap_state_change(chan, BT_CONNECT2); | 3797 | l2cap_state_change(chan, BT_CONNECT2); |
3815 | result = L2CAP_CR_PEND; | 3798 | result = L2CAP_CR_PEND; |
3816 | status = L2CAP_CS_NO_INFO; | 3799 | status = L2CAP_CS_NO_INFO; |
3817 | } | 3800 | } |
@@ -4738,7 +4721,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result, | |||
4738 | sizeof(rsp), &rsp); | 4721 | sizeof(rsp), &rsp); |
4739 | 4722 | ||
4740 | if (result == L2CAP_CR_SUCCESS) { | 4723 | if (result == L2CAP_CR_SUCCESS) { |
4741 | __l2cap_state_change(chan, BT_CONFIG); | 4724 | l2cap_state_change(chan, BT_CONFIG); |
4742 | set_bit(CONF_REQ_SENT, &chan->conf_state); | 4725 | set_bit(CONF_REQ_SENT, &chan->conf_state); |
4743 | l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), | 4726 | l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), |
4744 | L2CAP_CONF_REQ, | 4727 | L2CAP_CONF_REQ, |