From: Jeff Layton <jlayton@kernel.org>
To: Steve Dickson <steved@redhat.com>
Cc: Chuck Lever <chuck.lever@oracle.com>, NeilBrown <neil@brown.name>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>,
Trond Myklebust <trondmy@kernel.org>,
Anna Schumaker <anna@kernel.org>,
linux-nfs@vger.kernel.org, Jeff Layton <jlayton@kernel.org>
Subject: [PATCH nfs-utils v2 14/16] exportfs: add netlink support for cache flush with /proc fallback
Date: Mon, 30 Mar 2026 09:38:34 -0400 [thread overview]
Message-ID: <20260330-exportd-netlink-v2-14-cc9bd5db2408@kernel.org> (raw)
In-Reply-To: <20260330-exportd-netlink-v2-0-cc9bd5db2408@kernel.org>
Move cache_flush() from support/nfs/cacheio.c to a new file
support/export/cache_flush.c, which has access to libnl.
The new implementation tries netlink first:
- Sends SUNRPC_CMD_CACHE_FLUSH to flush auth.unix.ip and auth.unix.gid
- Sends NFSD_CMD_CACHE_FLUSH to flush nfsd.fh and nfsd.export
- Flushes sunrpc caches before nfsd caches to maintain dependency order
If the sunrpc genl family cannot be resolved (older kernel), falls back
to the original /proc/net/rpc/*/flush write path.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
support/export/Makefile.am | 2 +-
support/export/cache_flush.c | 164 +++++++++++++++++++++++++++++++++++++++++++
support/nfs/cacheio.c | 49 +------------
3 files changed, 166 insertions(+), 49 deletions(-)
diff --git a/support/export/Makefile.am b/support/export/Makefile.am
index ae7ace44112b889f1c461c5473fb1bd42a42f182..33416176c41eb6eadd1880f7c7432b4ca2d8c973 100644
--- a/support/export/Makefile.am
+++ b/support/export/Makefile.am
@@ -12,7 +12,7 @@ EXTRA_DIST = mount.x
noinst_LIBRARIES = libexport.a
libexport_a_SOURCES = client.c export.c hostname.c \
xtab.c mount_clnt.c mount_xdr.c \
- cache.c auth.c v4root.c fsloc.c \
+ cache.c cache_flush.c auth.c v4root.c fsloc.c \
v4clients.c
libexport_a_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) -I$(top_srcdir)/support/reexport \
$(LIBNL3_CFLAGS) $(LIBNLGENL3_CFLAGS)
diff --git a/support/export/cache_flush.c b/support/export/cache_flush.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d7f12b212967e5b3d1a2357de07bc3ba5f0b674
--- /dev/null
+++ b/support/export/cache_flush.c
@@ -0,0 +1,164 @@
+/*
+ * support/export/cache_flush.c
+ *
+ * Flush knfsd caches via netlink with /proc fallback.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "nfslib.h"
+#include "xlog.h"
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+
+#ifdef USE_SYSTEM_NFSD_NETLINK_H
+#include <linux/nfsd_netlink.h>
+#else
+#include "nfsd_netlink.h"
+#endif
+
+#ifdef USE_SYSTEM_SUNRPC_NETLINK_H
+#include <linux/sunrpc_netlink.h>
+#else
+#include "sunrpc_netlink.h"
+#endif
+
+static int nl_send_flush(struct nl_sock *sock, int family, int cmd)
+{
+ struct nl_msg *msg;
+ int ret;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ return -ENOMEM;
+
+ if (!genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family,
+ 0, 0, cmd, 0)) {
+ nlmsg_free(msg);
+ return -ENOMEM;
+ }
+
+ /* No mask attribute = flush all caches in this family */
+ ret = nl_send_auto(sock, msg);
+ if (ret >= 0)
+ ret = nl_wait_for_ack(sock);
+ nlmsg_free(msg);
+ return ret;
+}
+
+static int cache_nl_flush(void)
+{
+ struct nl_sock *sock;
+ int family, ret, val = 1;
+
+ sock = nl_socket_alloc();
+ if (!sock)
+ return -1;
+
+ if (genl_connect(sock)) {
+ nl_socket_free(sock);
+ return -1;
+ }
+
+ setsockopt(nl_socket_get_fd(sock), SOL_NETLINK, NETLINK_EXT_ACK,
+ &val, sizeof(val));
+
+ /* Flush sunrpc caches first (dependency order) */
+ family = genl_ctrl_resolve(sock, SUNRPC_FAMILY_NAME);
+ if (family < 0) {
+ xlog(D_NETLINK, "sunrpc genl family not found, "
+ "skipping netlink flush");
+ nl_socket_free(sock);
+ return -1;
+ }
+
+ ret = nl_send_flush(sock, family, SUNRPC_CMD_CACHE_FLUSH);
+ if (ret < 0) {
+ xlog(D_NETLINK, "sunrpc cache flush failed: %d", ret);
+ nl_socket_free(sock);
+ return -1;
+ }
+
+ /* Flush nfsd caches */
+ family = genl_ctrl_resolve(sock, NFSD_FAMILY_NAME);
+ if (family < 0) {
+ xlog(D_NETLINK, "nfsd genl family not found, "
+ "skipping nfsd cache flush");
+ nl_socket_free(sock);
+ return 0;
+ }
+
+ ret = nl_send_flush(sock, family, NFSD_CMD_CACHE_FLUSH);
+ nl_socket_free(sock);
+ if (ret < 0) {
+ xlog(D_NETLINK, "nfsd cache flush failed: %d", ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void cache_proc_flush(void)
+{
+ int c;
+ char stime[32];
+ char path[200];
+ time_t now;
+ /* Note: the order of these caches is important.
+ * They need to be flushed in dependency order. So
+ * a cache that references items in another cache,
+ * as nfsd.fh entries reference items in nfsd.export,
+ * must be flushed before the cache that it references.
+ */
+ static char *cachelist[] = {
+ "auth.unix.ip",
+ "auth.unix.gid",
+ "nfsd.fh",
+ "nfsd.export",
+ NULL
+ };
+ now = time(0);
+
+ /* Since v4.16-rc2-3-g3b68e6ee3cbd the timestamp written is ignored.
+ * It is safest always to flush caches if there is any doubt.
+ * For earlier kernels, writing the next second from now is
+ * the best we can do.
+ */
+ sprintf(stime, "%" PRId64 "\n", (int64_t)now+1);
+ for (c=0; cachelist[c]; c++) {
+ int fd;
+ sprintf(path, "/proc/net/rpc/%s/flush", cachelist[c]);
+ fd = open(path, O_RDWR);
+ if (fd >= 0) {
+ if (write(fd, stime, strlen(stime)) != (ssize_t)strlen(stime)) {
+ xlog_warn("Writing to '%s' failed: errno %d (%s)",
+ path, errno, strerror(errno));
+ }
+ close(fd);
+ }
+ }
+}
+
+void
+cache_flush(void)
+{
+ if (cache_nl_flush() == 0) {
+ xlog(D_NETLINK, "cache flush via netlink succeeded");
+ return;
+ }
+ /* Fallback: /proc path */
+ cache_proc_flush();
+}
diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c
index bd4da0e5ad93f963bf8090062541f34ededd1e03..95eeabbdb978cd227da9877b81e5ed2d65dedaf9 100644
--- a/support/nfs/cacheio.c
+++ b/support/nfs/cacheio.c
@@ -203,51 +203,4 @@ int qword_get_uint(char **bpp, unsigned int *anint)
return 0;
}
-/* flush the kNFSd caches.
- * Set the flush time to the mtime of the etab state file or
- * if force, to now.
- * the caches to flush are:
- * auth.unix.ip nfsd.export nfsd.fh
- */
-
-void
-cache_flush(void)
-{
- int c;
- char stime[32];
- char path[200];
- time_t now;
- /* Note: the order of these caches is important.
- * They need to be flushed in dependancy order. So
- * a cache that references items in another cache,
- * as nfsd.fh entries reference items in nfsd.export,
- * must be flushed before the cache that it references.
- */
- static char *cachelist[] = {
- "auth.unix.ip",
- "auth.unix.gid",
- "nfsd.fh",
- "nfsd.export",
- NULL
- };
- now = time(0);
-
- /* Since v4.16-rc2-3-g3b68e6ee3cbd the timestamp written is ignored.
- * It is safest always to flush caches if there is any doubt.
- * For earlier kernels, writing the next second from now is
- * the best we can do.
- */
- sprintf(stime, "%" PRId64 "\n", (int64_t)now+1);
- for (c=0; cachelist[c]; c++) {
- int fd;
- sprintf(path, "/proc/net/rpc/%s/flush", cachelist[c]);
- fd = open(path, O_RDWR);
- if (fd >= 0) {
- if (write(fd, stime, strlen(stime)) != (ssize_t)strlen(stime)) {
- xlog_warn("Writing to '%s' failed: errno %d (%s)",
- path, errno, strerror(errno));
- }
- close(fd);
- }
- }
-}
+/* cache_flush() has moved to support/export/cache.c for netlink support */
--
2.53.0
next prev parent reply other threads:[~2026-03-30 13:38 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-30 13:38 [PATCH nfs-utils v2 00/16] exportfs/exportd/mountd: allow them to use netlink for up/downcalls Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 01/16] nfsdctl: move *_netlink.h to support/include/ Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 02/16] support/export: remove unnecessary static variables in nfsd_fh expkey lookup Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 03/16] exportfs: remove obsolete legacy mode documentation from manpage Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 04/16] support/include: update netlink headers for all cache upcalls Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 05/16] build: add libnl3 and netlink header support for exportd and mountd Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 06/16] xlog: claim D_FAC3 as D_NETLINK Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 07/16] exportd/mountd: add netlink support for svc_export cache Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 08/16] exportd/mountd: add netlink support for the nfsd.fh cache Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 09/16] exportd/mountd: add netlink support for the auth.unix.ip cache Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 10/16] exportd/mountd: add netlink support for the auth.unix.gid cache Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 11/16] mountd/exportd: only use /proc interfaces if netlink setup fails Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 12/16] support/export: check for pending requests after opening netlink sockets Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 13/16] exportd/mountd: use cache type from notifications to target scanning Jeff Layton
2026-03-30 13:38 ` Jeff Layton [this message]
2026-03-30 13:38 ` [PATCH nfs-utils v2 15/16] exportfs: use netlink to probe kernel support, skip export_test Jeff Layton
2026-03-30 13:38 ` [PATCH nfs-utils v2 16/16] mountd/exportd/exportfs: add --no-netlink option to disable netlink Jeff Layton
2026-04-03 12:55 ` [PATCH nfs-utils v2 00/16] exportfs/exportd/mountd: allow them to use netlink for up/downcalls Steve Dickson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260330-exportd-netlink-v2-14-cc9bd5db2408@kernel.org \
--to=jlayton@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=anna@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=linux-nfs@vger.kernel.org \
--cc=neil@brown.name \
--cc=okorniev@redhat.com \
--cc=steved@redhat.com \
--cc=tom@talpey.com \
--cc=trondmy@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox