if (!sk)
return 0;
+ if (sk->sk_shutdown)
+ goto shutdown_already;
+
+ BT_DBG("Handling sock shutdown");
+
/* prevent sk structure from being freed whilst unlocked */
sock_hold(sk);
l2cap_chan_lock(chan);
lock_sock(sk);
- if (!sk->sk_shutdown) {
- if (chan->mode == L2CAP_MODE_ERTM &&
- chan->unacked_frames > 0 &&
- chan->state == BT_CONNECTED)
- err = __l2cap_wait_ack(sk, chan);
+ if (chan->mode == L2CAP_MODE_ERTM &&
+ chan->unacked_frames > 0 &&
+ chan->state == BT_CONNECTED)
+ err = __l2cap_wait_ack(sk, chan);
- sk->sk_shutdown = SHUTDOWN_MASK;
+ sk->sk_shutdown = SHUTDOWN_MASK;
- release_sock(sk);
- l2cap_chan_close(chan, 0);
- lock_sock(sk);
+ release_sock(sk);
+ l2cap_chan_close(chan, 0);
+ lock_sock(sk);
- if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
- !(current->flags & PF_EXITING))
- err = bt_sock_wait_state(sk, BT_CLOSED,
- sk->sk_lingertime);
- }
+ if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
+ !(current->flags & PF_EXITING))
+ err = bt_sock_wait_state(sk, BT_CLOSED,
+ sk->sk_lingertime);
if (!err && sk->sk_err)
err = -sk->sk_err;
l2cap_chan_put(chan);
sock_put(sk);
+shutdown_already:
BT_DBG("err: %d", err);
return err;