Bluetooth: ISO: Fix not handling shutdown condition
In order to properly handle shutdown syscall the code shall not assume
that the how argument is always SHUT_RDWR resulting in SHUTDOWN_MASK as
that would result in poll to immediately report EPOLLHUP instead of
properly waiting for disconnect_cfm (Disconnect Complete) which is
rather important for the likes of BAP as the CIG may need to be
reprogrammed.
Fixes: ccf74f2390
("Bluetooth: Add BTPROTO_ISO socket type")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
3cfbc6ac22
commit
c572909376
|
@ -1309,7 +1309,7 @@ static int iso_sock_shutdown(struct socket *sock, int how)
|
|||
struct sock *sk = sock->sk;
|
||||
int err = 0;
|
||||
|
||||
BT_DBG("sock %p, sk %p", sock, sk);
|
||||
BT_DBG("sock %p, sk %p, how %d", sock, sk, how);
|
||||
|
||||
if (!sk)
|
||||
return 0;
|
||||
|
@ -1317,17 +1317,32 @@ static int iso_sock_shutdown(struct socket *sock, int how)
|
|||
sock_hold(sk);
|
||||
lock_sock(sk);
|
||||
|
||||
if (!sk->sk_shutdown) {
|
||||
sk->sk_shutdown = SHUTDOWN_MASK;
|
||||
iso_sock_clear_timer(sk);
|
||||
__iso_sock_close(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);
|
||||
switch (how) {
|
||||
case SHUT_RD:
|
||||
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
||||
goto unlock;
|
||||
sk->sk_shutdown |= RCV_SHUTDOWN;
|
||||
break;
|
||||
case SHUT_WR:
|
||||
if (sk->sk_shutdown & SEND_SHUTDOWN)
|
||||
goto unlock;
|
||||
sk->sk_shutdown |= SEND_SHUTDOWN;
|
||||
break;
|
||||
case SHUT_RDWR:
|
||||
if (sk->sk_shutdown & SHUTDOWN_MASK)
|
||||
goto unlock;
|
||||
sk->sk_shutdown |= SHUTDOWN_MASK;
|
||||
break;
|
||||
}
|
||||
|
||||
iso_sock_clear_timer(sk);
|
||||
__iso_sock_close(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);
|
||||
|
||||
unlock:
|
||||
release_sock(sk);
|
||||
sock_put(sk);
|
||||
|
||||
|
|
Loading…
Reference in New Issue