summaryrefslogtreecommitdiff
path: root/fs/afs/rxrpc.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-24 16:21:27 +0200
commit8f9aa2c90530ab92301a82231ae44f3722becd93 (patch)
treefb282e955b0a880b07131a135257fe3ec764e928 /fs/afs/rxrpc.c
parent93467b31bec6da512b51544e5e4584f2745e995e (diff)
parent155b42bec9cbb6b8cdc47dd9bd09503a81fbe493 (diff)
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/afs/rxrpc.c')
-rw-r--r--fs/afs/rxrpc.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index 588f8de51167..d82916657a3d 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -127,8 +127,15 @@ void afs_close_socket(struct afs_net *net)
{
_enter("");
+ cancel_work_sync(&net->charge_preallocation_work);
+ cancel_work_sync(&net->rx_oob_work);
+ /* Future work items should now see ->live is false. */
+
kernel_listen(net->socket, 0);
+
+ /* Make sure work items are no longer running. */
flush_workqueue(afs_async_calls);
+ cancel_work_sync(&net->charge_preallocation_work);
if (net->spare_incoming_call) {
afs_put_call(net->spare_incoming_call);
@@ -142,6 +149,7 @@ void afs_close_socket(struct afs_net *net)
kernel_sock_shutdown(net->socket, SHUT_RDWR);
flush_workqueue(afs_async_calls);
+ cancel_work_sync(&net->rx_oob_work);
net->socket->sk->sk_user_data = NULL;
sock_release(net->socket);
key_put(net->fs_cm_token_key);
@@ -742,7 +750,7 @@ void afs_charge_preallocation(struct work_struct *work)
container_of(work, struct afs_net, charge_preallocation_work);
struct afs_call *call = net->spare_incoming_call;
- for (;;) {
+ while (READ_ONCE(net->live)) {
if (!call) {
call = afs_alloc_call(net, &afs_RXCMxxxx, GFP_KERNEL);
if (!call)
@@ -792,7 +800,8 @@ static void afs_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall,
if (!call->server)
trace_afs_cm_no_server(call, rxrpc_kernel_remote_srx(call->peer));
- queue_work(afs_wq, &net->charge_preallocation_work);
+ if (net->live)
+ queue_work(afs_wq, &net->charge_preallocation_work);
}
/*
@@ -982,5 +991,6 @@ static void afs_rx_notify_oob(struct sock *sk, struct sk_buff *oob)
{
struct afs_net *net = sk->sk_user_data;
- schedule_work(&net->rx_oob_work);
+ if (READ_ONCE(net->live))
+ queue_work(afs_wq, &net->rx_oob_work);
}