From: Chuck Lever <cel@kernel.org>
To: NeilBrown <neil@brown.name>, Jeff Layton <jlayton@kernel.org>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
Chuck Lever <chuck.lever@oracle.com>
Subject: [PATCH v8 5/9] NFSD: Add NFSD_CMD_UNLOCK_FILESYSTEM netlink command
Date: Wed, 08 Apr 2026 08:29:55 -0400 [thread overview]
Message-ID: <20260408-umount-kills-nfsv4-state-v8-5-6e02a1d03d60@oracle.com> (raw)
In-Reply-To: <20260408-umount-kills-nfsv4-state-v8-0-6e02a1d03d60@oracle.com>
From: Chuck Lever <chuck.lever@oracle.com>
Add NFSD_CMD_UNLOCK_FILESYSTEM as a dedicated netlink command for
revoking NFS state under a filesystem path, providing a netlink
equivalent of /proc/fs/nfsd/unlock_fs.
The command requires a "path" string attribute containing the
filesystem path whose state should be released. The handler
resolves the path to its superblock, then cancels async copies,
releases NLM locks, and revokes NFSv4 state on that superblock.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
Documentation/netlink/specs/nfsd.yaml | 16 ++++++++++++++
fs/nfsd/netlink.c | 12 +++++++++++
fs/nfsd/netlink.h | 1 +
fs/nfsd/nfsctl.c | 40 +++++++++++++++++++++++++++++++++++
include/uapi/linux/nfsd_netlink.h | 8 +++++++
5 files changed, 77 insertions(+)
diff --git a/Documentation/netlink/specs/nfsd.yaml b/Documentation/netlink/specs/nfsd.yaml
index 2c4883cfd50a..f3b21d4ba660 100644
--- a/Documentation/netlink/specs/nfsd.yaml
+++ b/Documentation/netlink/specs/nfsd.yaml
@@ -310,6 +310,13 @@ attribute-sets:
doc: struct sockaddr_in or struct sockaddr_in6.
checks:
min-len: 16
+ -
+ name: unlock-filesystem
+ attributes:
+ -
+ name: path
+ type: string
+ doc: Filesystem path whose state should be released.
operations:
list:
@@ -473,6 +480,15 @@ operations:
request:
attributes:
- address
+ -
+ name: unlock-filesystem
+ doc: revoke NFS state under a filesystem path
+ attribute-set: unlock-filesystem
+ flags: [admin-perm]
+ do:
+ request:
+ attributes:
+ - path
mcast-groups:
list:
diff --git a/fs/nfsd/netlink.c b/fs/nfsd/netlink.c
index 96d326095768..dae7ad560bd8 100644
--- a/fs/nfsd/netlink.c
+++ b/fs/nfsd/netlink.c
@@ -118,6 +118,11 @@ static const struct nla_policy nfsd_unlock_ip_nl_policy[NFSD_A_UNLOCK_IP_ADDRESS
[NFSD_A_UNLOCK_IP_ADDRESS] = NLA_POLICY_MIN_LEN(16),
};
+/* NFSD_CMD_UNLOCK_FILESYSTEM - do */
+static const struct nla_policy nfsd_unlock_filesystem_nl_policy[NFSD_A_UNLOCK_FILESYSTEM_PATH + 1] = {
+ [NFSD_A_UNLOCK_FILESYSTEM_PATH] = { .type = NLA_NUL_STRING, },
+};
+
/* Ops table for nfsd */
static const struct genl_split_ops nfsd_nl_ops[] = {
{
@@ -215,6 +220,13 @@ static const struct genl_split_ops nfsd_nl_ops[] = {
.maxattr = NFSD_A_UNLOCK_IP_ADDRESS,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
+ {
+ .cmd = NFSD_CMD_UNLOCK_FILESYSTEM,
+ .doit = nfsd_nl_unlock_filesystem_doit,
+ .policy = nfsd_unlock_filesystem_nl_policy,
+ .maxattr = NFSD_A_UNLOCK_FILESYSTEM_PATH,
+ .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
+ },
};
static const struct genl_multicast_group nfsd_nl_mcgrps[] = {
diff --git a/fs/nfsd/netlink.h b/fs/nfsd/netlink.h
index 88edbbc68453..29bd5468d401 100644
--- a/fs/nfsd/netlink.h
+++ b/fs/nfsd/netlink.h
@@ -40,6 +40,7 @@ int nfsd_nl_expkey_get_reqs_dumpit(struct sk_buff *skb,
int nfsd_nl_expkey_set_reqs_doit(struct sk_buff *skb, struct genl_info *info);
int nfsd_nl_cache_flush_doit(struct sk_buff *skb, struct genl_info *info);
int nfsd_nl_unlock_ip_doit(struct sk_buff *skb, struct genl_info *info);
+int nfsd_nl_unlock_filesystem_doit(struct sk_buff *skb, struct genl_info *info);
enum {
NFSD_NLGRP_NONE,
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index c5ce4af28287..c35774786374 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -2317,6 +2317,46 @@ int nfsd_nl_unlock_ip_doit(struct sk_buff *skb, struct genl_info *info)
return nlmsvc_unlock_all_by_ip(sap);
}
+/**
+ * nfsd_nl_unlock_filesystem_doit - revoke NFS state under a filesystem path
+ * @skb: reply buffer
+ * @info: netlink metadata and command arguments
+ *
+ * Return: 0 on success or a negative errno.
+ */
+int nfsd_nl_unlock_filesystem_doit(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct net *net = genl_info_net(info);
+ struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+ struct path path;
+ int error;
+
+ if (GENL_REQ_ATTR_CHECK(info, NFSD_A_UNLOCK_FILESYSTEM_PATH))
+ return -EINVAL;
+
+ trace_nfsd_ctl_unlock_fs(net,
+ nla_data(info->attrs[NFSD_A_UNLOCK_FILESYSTEM_PATH]));
+ error = kern_path(
+ nla_data(info->attrs[NFSD_A_UNLOCK_FILESYSTEM_PATH]),
+ 0, &path);
+ if (error)
+ return error;
+
+ nfsd4_cancel_copy_by_sb(net, path.dentry->d_sb);
+ error = nlmsvc_unlock_all_by_sb(path.dentry->d_sb);
+
+ mutex_lock(&nfsd_mutex);
+ if (nn->nfsd_serv)
+ nfsd4_revoke_states(nn, path.dentry->d_sb);
+ else
+ error = -EINVAL;
+ mutex_unlock(&nfsd_mutex);
+
+ path_put(&path);
+ return error;
+}
+
/**
* nfsd_net_init - Prepare the nfsd_net portion of a new net namespace
* @net: a freshly-created network namespace
diff --git a/include/uapi/linux/nfsd_netlink.h b/include/uapi/linux/nfsd_netlink.h
index 90ef1e686769..d01096c06d72 100644
--- a/include/uapi/linux/nfsd_netlink.h
+++ b/include/uapi/linux/nfsd_netlink.h
@@ -211,6 +211,13 @@ enum {
NFSD_A_UNLOCK_IP_MAX = (__NFSD_A_UNLOCK_IP_MAX - 1)
};
+enum {
+ NFSD_A_UNLOCK_FILESYSTEM_PATH = 1,
+
+ __NFSD_A_UNLOCK_FILESYSTEM_MAX,
+ NFSD_A_UNLOCK_FILESYSTEM_MAX = (__NFSD_A_UNLOCK_FILESYSTEM_MAX - 1)
+};
+
enum {
NFSD_CMD_RPC_STATUS_GET = 1,
NFSD_CMD_THREADS_SET,
@@ -228,6 +235,7 @@ enum {
NFSD_CMD_EXPKEY_SET_REQS,
NFSD_CMD_CACHE_FLUSH,
NFSD_CMD_UNLOCK_IP,
+ NFSD_CMD_UNLOCK_FILESYSTEM,
__NFSD_CMD_MAX,
NFSD_CMD_MAX = (__NFSD_CMD_MAX - 1)
--
2.53.0
next prev parent reply other threads:[~2026-04-08 12:30 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-08 12:29 [PATCH v8 0/9] Automatic NFSv4 state revocation on filesystem unmount Chuck Lever
2026-04-08 12:29 ` [PATCH v8 1/9] NFSD: Fix infinite loop in layout state revocation Chuck Lever
2026-04-08 13:58 ` Jeff Layton
2026-04-08 12:29 ` [PATCH v8 2/9] NFSD: Handle layout stid in nfsd4_drop_revoked_stid() Chuck Lever
2026-04-08 13:59 ` Jeff Layton
2026-04-08 12:29 ` [PATCH v8 3/9] NFSD: Extract revoke_one_stid() utility function Chuck Lever
2026-04-08 12:29 ` [PATCH v8 4/9] NFSD: Add NFSD_CMD_UNLOCK_IP netlink command Chuck Lever
2026-04-08 12:29 ` Chuck Lever [this message]
2026-04-08 12:29 ` [PATCH v8 6/9] NFSD: Replace idr_for_each_entry_ul in find_one_sb_stid() Chuck Lever
2026-04-08 12:29 ` [PATCH v8 7/9] NFSD: Track svc_export in nfs4_stid Chuck Lever
2026-04-08 12:29 ` [PATCH v8 8/9] NFSD: Add NFSD_CMD_UNLOCK_EXPORT netlink command Chuck Lever
2026-04-08 12:29 ` [PATCH v8 9/9] NFSD: Close cached file handles when revoking export state Chuck Lever
2026-04-08 13:56 ` [PATCH v8 0/9] Automatic NFSv4 state revocation on filesystem unmount Jeff Layton
2026-04-08 13:57 ` Chuck Lever
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=20260408-umount-kills-nfsv4-state-v8-5-6e02a1d03d60@oracle.com \
--to=cel@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=chuck.lever@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neil@brown.name \
--cc=okorniev@redhat.com \
--cc=tom@talpey.com \
/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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).