mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
NFC: Purge LLCP socket Tx queues when being disconnected
The Tx queues are no longer valid when we receive a disconnection or when the LLCP link goes down. In the later case we also purge the entire local Tx queue. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
f152218840
commit
f31652a58b
@ -45,12 +45,38 @@ void nfc_llcp_sock_unlink(struct llcp_sock_list *l, struct sock *sk)
|
|||||||
write_unlock(&l->lock);
|
write_unlock(&l->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock)
|
||||||
|
{
|
||||||
|
struct nfc_llcp_local *local = sock->local;
|
||||||
|
struct sk_buff *s, *tmp;
|
||||||
|
|
||||||
|
pr_debug("%p\n", &sock->sk);
|
||||||
|
|
||||||
|
skb_queue_purge(&sock->tx_queue);
|
||||||
|
skb_queue_purge(&sock->tx_pending_queue);
|
||||||
|
skb_queue_purge(&sock->tx_backlog_queue);
|
||||||
|
|
||||||
|
if (local == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Search for local pending SKBs that are related to this socket */
|
||||||
|
skb_queue_walk_safe(&local->tx_queue, s, tmp) {
|
||||||
|
if (s->sk != &sock->sk)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
skb_unlink(s, &local->tx_queue);
|
||||||
|
kfree_skb(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
||||||
{
|
{
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct hlist_node *node, *tmp;
|
struct hlist_node *node, *tmp;
|
||||||
struct nfc_llcp_sock *llcp_sock;
|
struct nfc_llcp_sock *llcp_sock;
|
||||||
|
|
||||||
|
skb_queue_purge(&local->tx_queue);
|
||||||
|
|
||||||
write_lock(&local->sockets.lock);
|
write_lock(&local->sockets.lock);
|
||||||
|
|
||||||
sk_for_each_safe(sk, node, tmp, &local->sockets.head) {
|
sk_for_each_safe(sk, node, tmp, &local->sockets.head) {
|
||||||
@ -58,6 +84,8 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
|||||||
|
|
||||||
bh_lock_sock(sk);
|
bh_lock_sock(sk);
|
||||||
|
|
||||||
|
nfc_llcp_socket_purge(llcp_sock);
|
||||||
|
|
||||||
if (sk->sk_state == LLCP_CONNECTED)
|
if (sk->sk_state == LLCP_CONNECTED)
|
||||||
nfc_put_device(llcp_sock->dev);
|
nfc_put_device(llcp_sock->dev);
|
||||||
|
|
||||||
@ -1002,6 +1030,9 @@ static void nfc_llcp_recv_disc(struct nfc_llcp_local *local,
|
|||||||
|
|
||||||
sk = &llcp_sock->sk;
|
sk = &llcp_sock->sk;
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
|
|
||||||
|
nfc_llcp_socket_purge(llcp_sock);
|
||||||
|
|
||||||
if (sk->sk_state == LLCP_CLOSED) {
|
if (sk->sk_state == LLCP_CLOSED) {
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
nfc_llcp_sock_put(llcp_sock);
|
nfc_llcp_sock_put(llcp_sock);
|
||||||
|
Loading…
Reference in New Issue
Block a user