[PATCH 6/6] NFSD: Convert nfsd_export_shutdown() to sunrpc_cache_destroy_net()
From: Chuck Lever
Date: Fri May 01 2026 - 10:52:47 EST
From: Chuck Lever <chuck.lever@xxxxxxxxxx>
The earlier conversion to the shared sunrpc cache workqueue left
nfsd_export_shutdown() open-coding the unregister + drain + destroy
sequence to amortize a single rcu_barrier()+flush across both
caches. That micro-optimization runs only on namespace teardown
and module unload, neither of which is performance-sensitive.
Switch both caches to sunrpc_cache_destroy_net() so that the
canonical teardown idiom is applied uniformly. A future change to
the per-cache release callback that requires the cache_detail to
remain valid through the drain remains correct without per-call-site
auditing.
With the last external caller of sunrpc_cache_drain() gone, drop
the symbol export and the public declaration, and mark the
function static so the compiler can inline it into
sunrpc_cache_destroy_net().
Assisted-by: Claude:claude-opus-4-7[1m]
Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
---
fs/nfsd/export.c | 8 ++------
include/linux/sunrpc/cache.h | 1 -
net/sunrpc/cache.c | 7 ++-----
3 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 3c4340e743fa..c19f8e8c4f9e 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -2250,12 +2250,8 @@ nfsd_export_shutdown(struct net *net)
dprintk("nfsd: shutting down export module (net: %x).\n", net->ns.inum);
- cache_unregister_net(nn->svc_expkey_cache, net);
- cache_unregister_net(nn->svc_export_cache, net);
- /* One drain covers both caches' deferred release work. */
- sunrpc_cache_drain();
- cache_destroy_net(nn->svc_expkey_cache, net);
- cache_destroy_net(nn->svc_export_cache, net);
+ sunrpc_cache_destroy_net(nn->svc_expkey_cache, net);
+ sunrpc_cache_destroy_net(nn->svc_export_cache, net);
svcauth_unix_purge(net);
dprintk("nfsd: export shutdown complete (net: %x).\n", net->ns.inum);
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 84802438a5fc..22c18eeb5a97 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -238,7 +238,6 @@ extern void cache_flush(void);
extern void cache_purge(struct cache_detail *detail);
#define NEVER (0x7FFFFFFF)
extern void sunrpc_cache_queue_release(struct rcu_work *rwork);
-extern void sunrpc_cache_drain(void);
extern int cache_register_net(struct cache_detail *cd, struct net *net);
extern void cache_unregister_net(struct cache_detail *cd, struct net *net);
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index be7a0c8c416e..62ce334104d9 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -1737,18 +1737,15 @@ void sunrpc_cache_queue_release(struct rcu_work *rwork)
}
EXPORT_SYMBOL_GPL(sunrpc_cache_queue_release);
-/**
- * sunrpc_cache_drain - drain pending cache release work
- *
+/*
* Wait for outstanding RCU callbacks to enqueue their release
* work, then flush that work to completion.
*/
-void sunrpc_cache_drain(void)
+static void sunrpc_cache_drain(void)
{
rcu_barrier();
flush_workqueue(sunrpc_cache_wq);
}
-EXPORT_SYMBOL_GPL(sunrpc_cache_drain);
/**
* sunrpc_cache_destroy_net - quiesce and tear down a per-net cache
--
2.53.0