diff options
Diffstat (limited to 'net/bluetooth/l2cap_sock.c')
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index d06fb54082aa..1bb551527044 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -1129,9 +1129,17 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) | |||
1129 | 1129 | ||
1130 | if (chan->mode == L2CAP_MODE_ERTM && | 1130 | if (chan->mode == L2CAP_MODE_ERTM && |
1131 | chan->unacked_frames > 0 && | 1131 | chan->unacked_frames > 0 && |
1132 | chan->state == BT_CONNECTED) | 1132 | chan->state == BT_CONNECTED) { |
1133 | err = __l2cap_wait_ack(sk, chan); | 1133 | err = __l2cap_wait_ack(sk, chan); |
1134 | 1134 | ||
1135 | /* After waiting for ACKs, check whether shutdown | ||
1136 | * has already been actioned to close the L2CAP | ||
1137 | * link such as by l2cap_disconnection_req(). | ||
1138 | */ | ||
1139 | if (sk->sk_shutdown) | ||
1140 | goto has_shutdown; | ||
1141 | } | ||
1142 | |||
1135 | sk->sk_shutdown = SHUTDOWN_MASK; | 1143 | sk->sk_shutdown = SHUTDOWN_MASK; |
1136 | release_sock(sk); | 1144 | release_sock(sk); |
1137 | 1145 | ||
@@ -1162,6 +1170,7 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) | |||
1162 | err = bt_sock_wait_state(sk, BT_CLOSED, | 1170 | err = bt_sock_wait_state(sk, BT_CLOSED, |
1163 | sk->sk_lingertime); | 1171 | sk->sk_lingertime); |
1164 | 1172 | ||
1173 | has_shutdown: | ||
1165 | l2cap_chan_put(chan); | 1174 | l2cap_chan_put(chan); |
1166 | sock_put(sk); | 1175 | sock_put(sk); |
1167 | 1176 | ||