This is the first NFC pull request for 3.9 fixes
With this one we have: - A fix for properly decreasing socket ack log. - A timer and works cleanup upon NFC device removal. - A monitoroing socket cleanup round from llcp_socket_release. - A proper error report to pending sockets upon NFC device removal. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJRPRpxAAoJEIqAPN1PVmxK6lMP+wc4MRsxn5CKi9lEBtAjOql5 7S6x1b8/RqgWEY0MZM3YDrlMJ5+Xhe4eZeOpKc9+nDNH+g3Ad5SzYgUUPWLJVeBm awxzvqMc8BjRSgXdB6XxbBhzw0jKCngnBg1g8Zf8xvaumMAAmg/Wb+YLvfuC6hcx tv/jvKdkxiV+xdNi5NDl6HEwsaN7dQv5GmJQ0DVDJh16mX1ZFSlK7GJfaOlfVfLT jaYOF0nCejT2Qy6jRZm/5npTtvPSsimGR/i8ikEpaJ1eTF3hdoqaTmaw/hxJZMyZ 2T+wNoj/tuuDXWaSu+mg3wW6Ol/RWJ8EE/UYcTJV4CW8lmH5lpHjCd2ZvE1DHw59 Jp/NeaKICBJMklUbZSMEWnJ1lDkz58btzattslOgzJH1GkXRM6Czeb2tVhPU5Lqu zmq9JDa6TofF3AD8LZEhw8neylcXdcdo9OU6MAJYECfoDWI4EKd6cFeJAMV2Yt6o /ZGuAF2uVtGkw/QzwemvLynkvqOXKqP7lM418S0ZHN0DcXCv6lQ+x2LRhA7FbBuo XiAwV33MYxEUtNoPvGcT6maS37TUK9dJ1ZjT3ulntH/crqSB6Ksk5O/nkWgSZWkn rjVCK3j1YrFdV4kLLCO1LLdte56Eqep8foZUfDv6Q89A95Tek1uoYzOxRtT1SRHU CiriwiJHJ1X5vRUyNBJG =faE5 -----END PGP SIGNATURE----- Merge tag 'nfc-fixes-3.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-fixes Samuel Ortiz <sameo@linux.intel.com> says: This is the first NFC pull request for 3.9 fixes With this one we have: - A fix for properly decreasing socket ack log. - A timer and works cleanup upon NFC device removal. - A monitoroing socket cleanup round from llcp_socket_release. - A proper error report to pending sockets upon NFC device removal. Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
commit
de121989c8
2 changed files with 55 additions and 9 deletions
|
@ -68,7 +68,8 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
int err)
|
||||||
{
|
{
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct hlist_node *tmp;
|
struct hlist_node *tmp;
|
||||||
|
@ -100,7 +101,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
||||||
|
|
||||||
nfc_llcp_accept_unlink(accept_sk);
|
nfc_llcp_accept_unlink(accept_sk);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
accept_sk->sk_err = err;
|
||||||
accept_sk->sk_state = LLCP_CLOSED;
|
accept_sk->sk_state = LLCP_CLOSED;
|
||||||
|
accept_sk->sk_state_change(sk);
|
||||||
|
|
||||||
bh_unlock_sock(accept_sk);
|
bh_unlock_sock(accept_sk);
|
||||||
|
|
||||||
|
@ -123,7 +127,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
sk->sk_err = err;
|
||||||
sk->sk_state = LLCP_CLOSED;
|
sk->sk_state = LLCP_CLOSED;
|
||||||
|
sk->sk_state_change(sk);
|
||||||
|
|
||||||
bh_unlock_sock(sk);
|
bh_unlock_sock(sk);
|
||||||
|
|
||||||
|
@ -133,6 +140,36 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
|
||||||
}
|
}
|
||||||
|
|
||||||
write_unlock(&local->sockets.lock);
|
write_unlock(&local->sockets.lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we want to keep the listening sockets alive,
|
||||||
|
* we don't touch the RAW ones.
|
||||||
|
*/
|
||||||
|
if (listen == true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
write_lock(&local->raw_sockets.lock);
|
||||||
|
|
||||||
|
sk_for_each_safe(sk, tmp, &local->raw_sockets.head) {
|
||||||
|
llcp_sock = nfc_llcp_sock(sk);
|
||||||
|
|
||||||
|
bh_lock_sock(sk);
|
||||||
|
|
||||||
|
nfc_llcp_socket_purge(llcp_sock);
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
sk->sk_err = err;
|
||||||
|
sk->sk_state = LLCP_CLOSED;
|
||||||
|
sk->sk_state_change(sk);
|
||||||
|
|
||||||
|
bh_unlock_sock(sk);
|
||||||
|
|
||||||
|
sock_orphan(sk);
|
||||||
|
|
||||||
|
sk_del_node_init(sk);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_unlock(&local->raw_sockets.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
|
struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
|
||||||
|
@ -142,6 +179,17 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
|
||||||
return local;
|
return local;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void local_cleanup(struct nfc_llcp_local *local, bool listen)
|
||||||
|
{
|
||||||
|
nfc_llcp_socket_release(local, listen, ENXIO);
|
||||||
|
del_timer_sync(&local->link_timer);
|
||||||
|
skb_queue_purge(&local->tx_queue);
|
||||||
|
cancel_work_sync(&local->tx_work);
|
||||||
|
cancel_work_sync(&local->rx_work);
|
||||||
|
cancel_work_sync(&local->timeout_work);
|
||||||
|
kfree_skb(local->rx_pending);
|
||||||
|
}
|
||||||
|
|
||||||
static void local_release(struct kref *ref)
|
static void local_release(struct kref *ref)
|
||||||
{
|
{
|
||||||
struct nfc_llcp_local *local;
|
struct nfc_llcp_local *local;
|
||||||
|
@ -149,13 +197,7 @@ static void local_release(struct kref *ref)
|
||||||
local = container_of(ref, struct nfc_llcp_local, ref);
|
local = container_of(ref, struct nfc_llcp_local, ref);
|
||||||
|
|
||||||
list_del(&local->list);
|
list_del(&local->list);
|
||||||
nfc_llcp_socket_release(local, false);
|
local_cleanup(local, false);
|
||||||
del_timer_sync(&local->link_timer);
|
|
||||||
skb_queue_purge(&local->tx_queue);
|
|
||||||
cancel_work_sync(&local->tx_work);
|
|
||||||
cancel_work_sync(&local->rx_work);
|
|
||||||
cancel_work_sync(&local->timeout_work);
|
|
||||||
kfree_skb(local->rx_pending);
|
|
||||||
kfree(local);
|
kfree(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,7 +1390,7 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Close and purge all existing sockets */
|
/* Close and purge all existing sockets */
|
||||||
nfc_llcp_socket_release(local, true);
|
nfc_llcp_socket_release(local, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
|
void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
|
||||||
|
@ -1427,6 +1469,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local_cleanup(local, false);
|
||||||
|
|
||||||
nfc_llcp_local_put(local);
|
nfc_llcp_local_put(local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -278,6 +278,8 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
|
||||||
|
|
||||||
pr_debug("Returning sk state %d\n", sk->sk_state);
|
pr_debug("Returning sk state %d\n", sk->sk_state);
|
||||||
|
|
||||||
|
sk_acceptq_removed(parent);
|
||||||
|
|
||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue