From: Jeff Layton <jlayton@kernel.org>
To: Chuck Lever <cel@kernel.org>, NeilBrown <neil@brown.name>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>
Cc: Scott Mayhew <smayhew@redhat.com>,
linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org,
Jeff Layton <jlayton@kernel.org>
Subject: [PATCH 2/2] nfsd: remove CONFIG_NFSD_LEGACY_CLIENT_TRACKING
Date: Wed, 23 Sep 2026 12:14:22 -0400 [thread overview]
Message-ID: <20260923-nfsd-legacy-v1-2-8490c0c12ea5@kernel.org> (raw)
In-Reply-To: <20260923-nfsd-legacy-v1-0-8490c0c12ea5@kernel.org>
Remove the deprecated Kconfig option and the last legacy client
tracking backend, the on-disk recoverydir, along with the
nfsv4recoverydir file, the nfsd_ctl_recoverydir tracepoint, and the
MD5-based hashed recdir names. nfsdcld is now the only client tracking
method.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
arch/s390/configs/debug_defconfig | 1 -
arch/s390/configs/defconfig | 1 -
fs/nfsd/Kconfig | 17 -
fs/nfsd/netns.h | 1 -
fs/nfsd/nfs4ctl.h | 8 +-
fs/nfsd/nfs4recover.c | 653 +-------------------------------------
fs/nfsd/nfsctl.c | 79 -----
fs/nfsd/state.h | 4 -
fs/nfsd/trace.h | 19 --
9 files changed, 3 insertions(+), 780 deletions(-)
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 3dae71474333..9f8d3b31bbc3 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -726,7 +726,6 @@ CONFIG_NFSD=m
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_V4_SECURITY_LABEL=y
-# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set
CONFIG_CIFS=m
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index 6f5722634b4d..579ad7dcfd4b 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -712,7 +712,6 @@ CONFIG_NFSD=m
CONFIG_NFSD_V3_ACL=y
CONFIG_NFSD_V4=y
CONFIG_NFSD_V4_SECURITY_LABEL=y
-# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set
CONFIG_CIFS=m
CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index ffb76761d6a8..3e4030b70194 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -5,7 +5,6 @@ config NFSD
depends on FILE_LOCKING
depends on FSNOTIFY
select CRC32
- select CRYPTO_LIB_MD5 if NFSD_LEGACY_CLIENT_TRACKING
select CRYPTO_LIB_SHA256 if NFSD_V4
select CRYPTO # required by RPCSEC_GSS_KRB5 and signed filehandles
select LOCKD
@@ -161,22 +160,6 @@ config NFSD_V4_SECURITY_LABEL
If you do not wish to enable fine-grained security labels SELinux or
Smack policies on NFSv4 files, say N.
-config NFSD_LEGACY_CLIENT_TRACKING
- bool "Support legacy NFSv4 client tracking methods (DEPRECATED)"
- depends on NFSD_V4
- default n
- help
- The NFSv4 server needs to store a small amount of information on
- stable storage in order to handle state recovery after reboot. Most
- modern deployments upcall to a userland daemon for this (nfsdcld),
- but older NFS servers may store information directly in a
- recoverydir, or spawn a process directly using a usermodehelper
- upcall.
-
- These legacy client tracking methods have proven to be problematic
- and will be removed in the future. Say Y here if you need support
- for them in the interim.
-
config NFSD_V4_POSIX_ACLS
bool "Support NFSv4 POSIX draft ACLs"
depends on NFSD_V4
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index c1b068b63edd..1d32846b1836 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -135,7 +135,6 @@ struct nfsd_net {
/* protects blocked_locks_lru */
spinlock_t blocked_locks_lock;
- struct file *rec_file;
const struct nfsd4_client_tracking_ops *client_tracking_ops;
time64_t nfsd4_lease;
diff --git a/fs/nfsd/nfs4ctl.h b/fs/nfsd/nfs4ctl.h
index bcec4c4ef1d5..e0d1246ca337 100644
--- a/fs/nfsd/nfs4ctl.h
+++ b/fs/nfsd/nfs4ctl.h
@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Entry points by which the knfsd core drives the optional NFSv4
- * subsystem: state lifecycle, the laundromat workqueue, the recovery
- * directory, junctions, the CLD notifier, and leases-net setup.
+ * subsystem: state lifecycle, the laundromat workqueue, junctions,
+ * the CLD notifier, and leases-net setup.
*
* Separated from nfsd.h so that the many translation units that
* include nfsd.h but call none of these -- among them the NFSv2 and
@@ -31,8 +31,6 @@ int nfs4_state_start(void);
int nfs4_state_start_net(struct net *net);
void nfs4_state_shutdown(void);
void nfs4_state_shutdown_net(struct net *net);
-int nfs4_reset_recoverydir(char *recdir);
-char * nfs4_recoverydir(void);
bool nfsd4_spo_must_allow(struct svc_rqst *rqstp);
int nfsd4_create_laundry_wq(void);
void nfsd4_destroy_laundry_wq(void);
@@ -54,8 +52,6 @@ static inline int nfs4_state_start(void) { return 0; }
static inline int nfs4_state_start_net(struct net *net) { return 0; }
static inline void nfs4_state_shutdown(void) { }
static inline void nfs4_state_shutdown_net(struct net *net) { }
-static inline int nfs4_reset_recoverydir(char *recdir) { return 0; }
-static inline char * nfs4_recoverydir(void) {return NULL; }
static inline bool nfsd4_spo_must_allow(struct svc_rqst *rqstp)
{
return false;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ecf8ced8074a..4df7940a2d59 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -32,7 +32,6 @@
*
*/
-#include <crypto/md5.h>
#include <crypto/sha2.h>
#include <linux/file.h>
#include <linux/slab.h>
@@ -69,566 +68,6 @@ struct nfsd4_client_tracking_ops {
static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops;
static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops_v2;
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
-/* Globals */
-static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
-
-static int
-nfs4_save_creds(const struct cred **original_creds)
-{
- struct cred *new;
-
- new = prepare_creds();
- if (!new)
- return -ENOMEM;
-
- new->fsuid = GLOBAL_ROOT_UID;
- new->fsgid = GLOBAL_ROOT_GID;
- *original_creds = override_creds(new);
- return 0;
-}
-
-static void
-nfs4_reset_creds(const struct cred *original)
-{
- put_cred(revert_creds(original));
-}
-
-static void
-nfs4_make_rec_clidname(char dname[HEXDIR_LEN], const struct xdr_netobj *clname)
-{
- u8 digest[MD5_DIGEST_SIZE];
-
- dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
- clname->len, clname->data);
-
- md5(clname->data, clname->len, digest);
-
- static_assert(HEXDIR_LEN == 2 * MD5_DIGEST_SIZE + 1);
- sprintf(dname, "%*phN", MD5_DIGEST_SIZE, digest);
-}
-
-static void
-__nfsd4_create_reclaim_record_grace(struct nfs4_client *clp,
- char *dname, struct nfsd_net *nn)
-{
- struct xdr_netobj name = { .len = strlen(dname), .data = dname };
- struct xdr_netobj princhash = { .len = 0, .data = NULL };
- struct nfs4_client_reclaim *crp;
-
- crp = nfs4_client_to_reclaim(name, princhash, nn);
- crp->cr_clp = clp;
-}
-
-static void
-nfsd4_create_clid_dir(struct nfs4_client *clp)
-{
- const struct cred *original_cred;
- char dname[HEXDIR_LEN];
- struct dentry *dir, *dentry;
- int status;
- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
-
- if (test_and_set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
- return;
- if (!nn->rec_file)
- return;
-
- nfs4_make_rec_clidname(dname, &clp->cl_name);
-
- status = nfs4_save_creds(&original_cred);
- if (status < 0)
- return;
-
- status = mnt_want_write_file(nn->rec_file);
- if (status)
- goto out_creds;
-
- dir = nn->rec_file->f_path.dentry;
-
- dentry = start_creating(&nop_mnt_idmap, dir, &QSTR(dname));
- if (IS_ERR(dentry)) {
- status = PTR_ERR(dentry);
- goto out;
- }
- if (d_really_is_positive(dentry))
- /*
- * In the 4.1 case, where we're called from
- * reclaim_complete(), records from the previous reboot
- * may still be left, so this is OK.
- *
- * In the 4.0 case, we should never get here; but we may
- * as well be forgiving and just succeed silently.
- */
- goto out_end;
- dentry = vfs_mkdir(&nop_mnt_idmap, d_inode(dir), dentry, 0700, NULL);
- if (IS_ERR(dentry))
- status = PTR_ERR(dentry);
-out_end:
- end_creating(dentry);
-out:
- if (status == 0) {
- if (test_bit(NFSD_NET_IN_GRACE, &nn->flags))
- __nfsd4_create_reclaim_record_grace(clp, dname, nn);
- vfs_fsync(nn->rec_file, 0);
- } else {
- printk(KERN_ERR "NFSD: failed to write recovery record"
- " (err %d); please check that %s exists"
- " and is writeable", status,
- user_recovery_dirname);
- }
- mnt_drop_write_file(nn->rec_file);
-out_creds:
- nfs4_reset_creds(original_cred);
-}
-
-typedef int (recdir_func)(struct dentry *, char *, struct nfsd_net *);
-
-struct name_list {
- char name[HEXDIR_LEN];
- struct list_head list;
-};
-
-struct nfs4_dir_ctx {
- struct dir_context ctx;
- struct list_head names;
-};
-
-static bool
-nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen,
- loff_t offset, u64 ino, unsigned int d_type)
-{
- struct nfs4_dir_ctx *ctx =
- container_of(__ctx, struct nfs4_dir_ctx, ctx);
- struct name_list *entry;
-
- if (namlen != HEXDIR_LEN - 1)
- return true;
- entry = kmalloc_obj(struct name_list);
- if (entry == NULL)
- return false;
- memcpy(entry->name, name, HEXDIR_LEN - 1);
- entry->name[HEXDIR_LEN - 1] = '\0';
- list_add(&entry->list, &ctx->names);
- return true;
-}
-
-static int
-nfsd4_list_rec_dir(recdir_func *f, struct nfsd_net *nn)
-{
- const struct cred *original_cred;
- struct dentry *dir = nn->rec_file->f_path.dentry;
- struct nfs4_dir_ctx ctx = {
- .ctx.actor = nfsd4_build_namelist,
- .names = LIST_HEAD_INIT(ctx.names)
- };
- struct name_list *entry, *tmp;
- int status;
-
- status = nfs4_save_creds(&original_cred);
- if (status < 0)
- return status;
-
- status = vfs_llseek(nn->rec_file, 0, SEEK_SET);
- if (status < 0) {
- nfs4_reset_creds(original_cred);
- return status;
- }
-
- status = iterate_dir(nn->rec_file, &ctx.ctx);
-
- list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
- if (!status)
- status = f(dir, entry->name, nn);
-
- list_del(&entry->list);
- kfree(entry);
- }
- nfs4_reset_creds(original_cred);
-
- list_for_each_entry_safe(entry, tmp, &ctx.names, list) {
- dprintk("NFSD: %s. Left entry %s\n", __func__, entry->name);
- list_del(&entry->list);
- kfree(entry);
- }
- return status;
-}
-
-static int
-nfsd4_unlink_clid_dir(char *name, struct nfsd_net *nn)
-{
- struct dentry *dir, *dentry;
- int status;
-
- dprintk("NFSD: nfsd4_unlink_clid_dir. name %s\n", name);
-
- dir = nn->rec_file->f_path.dentry;
- dentry = start_removing(&nop_mnt_idmap, dir, &QSTR(name));
- if (IS_ERR(dentry))
- return PTR_ERR(dentry);
-
- status = vfs_rmdir(&nop_mnt_idmap, d_inode(dir), dentry, NULL);
- end_removing(dentry);
- return status;
-}
-
-static void
-__nfsd4_remove_reclaim_record_grace(const char *dname, int len,
- struct nfsd_net *nn)
-{
- struct xdr_netobj name;
- struct nfs4_client_reclaim *crp;
-
- name.data = kmemdup(dname, len, GFP_KERNEL);
- if (!name.data) {
- dprintk("%s: failed to allocate memory for name.data!\n",
- __func__);
- return;
- }
- name.len = len;
- down_write(&nn->reclaim_str_hashtbl_lock);
- crp = nfsd4_find_reclaim_client(name, nn);
- if (crp)
- nfs4_remove_reclaim_record(crp, nn);
- up_write(&nn->reclaim_str_hashtbl_lock);
- kfree(name.data);
-}
-
-static void
-nfsd4_remove_clid_dir(struct nfs4_client *clp)
-{
- const struct cred *original_cred;
- char dname[HEXDIR_LEN];
- int status;
- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
-
- if (!nn->rec_file || !test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
- return;
-
- nfs4_make_rec_clidname(dname, &clp->cl_name);
-
- status = mnt_want_write_file(nn->rec_file);
- if (status)
- goto out;
- clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
-
- status = nfs4_save_creds(&original_cred);
- if (status < 0)
- goto out_drop_write;
-
- status = nfsd4_unlink_clid_dir(dname, nn);
- nfs4_reset_creds(original_cred);
- if (status == 0) {
- vfs_fsync(nn->rec_file, 0);
- if (test_bit(NFSD_NET_IN_GRACE, &nn->flags))
- __nfsd4_remove_reclaim_record_grace(dname,
- HEXDIR_LEN, nn);
- }
-out_drop_write:
- mnt_drop_write_file(nn->rec_file);
-out:
- if (status)
- printk("NFSD: Failed to remove expired client state directory"
- " %.*s\n", HEXDIR_LEN, dname);
-}
-
-static int
-purge_old(struct dentry *parent, char *cname, struct nfsd_net *nn)
-{
- int status;
- struct dentry *child;
- struct xdr_netobj name;
-
- if (strlen(cname) != HEXDIR_LEN - 1) {
- printk("%s: illegal name %s in recovery directory\n",
- __func__, cname);
- /* Keep trying; maybe the others are OK: */
- return 0;
- }
- name.data = kstrdup(cname, GFP_KERNEL);
- if (!name.data) {
- dprintk("%s: failed to allocate memory for name.data!\n",
- __func__);
- goto out;
- }
- name.len = HEXDIR_LEN;
- if (nfs4_has_reclaimed_state(name, nn))
- goto out_free;
-
- child = start_removing_noperm(parent, &QSTR(cname));
- if (!IS_ERR(child)) {
- status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child, NULL);
- if (status)
- printk("failed to remove client recovery directory %pd\n",
- child);
- }
- end_removing(child);
-
-out_free:
- kfree(name.data);
-out:
- /* Keep trying, success or failure: */
- return 0;
-}
-
-static void
-nfsd4_recdir_purge_old(struct nfsd_net *nn)
-{
- int status;
-
- clear_bit(NFSD_NET_IN_GRACE, &nn->flags);
- if (!nn->rec_file)
- return;
- status = mnt_want_write_file(nn->rec_file);
- if (status)
- goto out;
- status = nfsd4_list_rec_dir(purge_old, nn);
- if (status == 0)
- vfs_fsync(nn->rec_file, 0);
- mnt_drop_write_file(nn->rec_file);
-out:
- nfs4_release_reclaim(nn);
- if (status)
- printk("nfsd4: failed to purge old clients from recovery"
- " directory %pD\n", nn->rec_file);
-}
-
-static int
-load_recdir(struct dentry *parent, char *cname, struct nfsd_net *nn)
-{
- struct xdr_netobj name = { .len = HEXDIR_LEN, .data = cname };
- struct xdr_netobj princhash = { .len = 0, .data = NULL };
-
- if (strlen(cname) != HEXDIR_LEN - 1) {
- printk("%s: illegal name %s in recovery directory\n",
- __func__, cname);
- /* Keep trying; maybe the others are OK: */
- return 0;
- }
- nfs4_client_to_reclaim(name, princhash, nn);
- return 0;
-}
-
-static int
-nfsd4_recdir_load(struct net *net) {
- int status;
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
-
- if (!nn->rec_file)
- return 0;
-
- status = nfsd4_list_rec_dir(load_recdir, nn);
- if (status)
- printk("nfsd4: failed loading clients from recovery"
- " directory %pD\n", nn->rec_file);
- return status;
-}
-
-/*
- * Hold reference to the recovery directory.
- */
-
-static int
-nfsd4_init_recdir(struct net *net)
-{
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
- const struct cred *original_cred;
- int status;
-
- printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
- user_recovery_dirname);
-
- BUG_ON(nn->rec_file);
-
- status = nfs4_save_creds(&original_cred);
- if (status < 0) {
- printk("NFSD: Unable to change credentials to find recovery"
- " directory: error %d\n",
- status);
- return status;
- }
-
- nn->rec_file = filp_open(user_recovery_dirname, O_RDONLY | O_DIRECTORY, 0);
- if (IS_ERR(nn->rec_file)) {
- printk("NFSD: unable to find recovery directory %s\n",
- user_recovery_dirname);
- status = PTR_ERR(nn->rec_file);
- nn->rec_file = NULL;
- }
-
- nfs4_reset_creds(original_cred);
- if (!status)
- set_bit(NFSD_NET_IN_GRACE, &nn->flags);
- return status;
-}
-
-static void
-nfsd4_shutdown_recdir(struct net *net)
-{
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
-
- if (!nn->rec_file)
- return;
- fput(nn->rec_file);
- nn->rec_file = NULL;
-}
-
-static int
-nfs4_legacy_state_init(struct net *net)
-{
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
- int i;
-
- nn->reclaim_str_hashtbl = kmalloc_objs(struct list_head,
- CLIENT_HASH_SIZE);
- if (!nn->reclaim_str_hashtbl)
- return -ENOMEM;
-
- for (i = 0; i < CLIENT_HASH_SIZE; i++)
- INIT_LIST_HEAD(&nn->reclaim_str_hashtbl[i]);
- nn->reclaim_str_hashtbl_size = 0;
- init_rwsem(&nn->reclaim_str_hashtbl_lock);
-
- return 0;
-}
-
-static void
-nfs4_legacy_state_shutdown(struct net *net)
-{
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
-
- kfree(nn->reclaim_str_hashtbl);
-}
-
-static int
-nfsd4_load_reboot_recovery_data(struct net *net)
-{
- int status;
-
- status = nfsd4_init_recdir(net);
- if (status)
- return status;
-
- status = nfsd4_recdir_load(net);
- if (status)
- nfsd4_shutdown_recdir(net);
-
- return status;
-}
-
-static int
-nfsd4_legacy_tracking_init(struct net *net)
-{
- int status;
-
- /* XXX: The legacy code won't work in a container */
- if (net != &init_net) {
- pr_warn("NFSD: attempt to initialize legacy client tracking in a container ignored.\n");
- return -EINVAL;
- }
-
- status = nfs4_legacy_state_init(net);
- if (status)
- return status;
-
- status = nfsd4_load_reboot_recovery_data(net);
- if (status)
- goto err;
- pr_info("NFSD: Using legacy client tracking operations.\n");
- return 0;
-
-err:
- nfs4_legacy_state_shutdown(net);
- return status;
-}
-
-static void
-nfsd4_legacy_tracking_exit(struct net *net)
-{
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
-
- nfs4_release_reclaim(nn);
- nfsd4_shutdown_recdir(net);
- nfs4_legacy_state_shutdown(net);
-}
-
-/*
- * Change the NFSv4 recovery directory to recdir.
- */
-int
-nfs4_reset_recoverydir(char *recdir)
-{
- int status;
- struct path path;
-
- status = kern_path(recdir, LOOKUP_FOLLOW, &path);
- if (status)
- return status;
- status = -ENOTDIR;
- if (d_is_dir(path.dentry)) {
- strscpy(user_recovery_dirname, recdir,
- sizeof(user_recovery_dirname));
- status = 0;
- }
- path_put(&path);
- return status;
-}
-
-char *
-nfs4_recoverydir(void)
-{
- return user_recovery_dirname;
-}
-
-static int
-nfsd4_check_legacy_client(struct nfs4_client *clp)
-{
- char dname[HEXDIR_LEN];
- struct nfs4_client_reclaim *crp;
- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
- struct xdr_netobj name;
-
- /* did we already find that this client is stable? */
- if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
- return 0;
-
- nfs4_make_rec_clidname(dname, &clp->cl_name);
-
- /* look for it in the reclaim hashtable otherwise */
- name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
- if (!name.data) {
- dprintk("%s: failed to allocate memory for name.data!\n",
- __func__);
- goto out_enoent;
- }
- name.len = HEXDIR_LEN;
- down_read(&nn->reclaim_str_hashtbl_lock);
- crp = nfsd4_find_reclaim_client(name, nn);
- if (crp) {
- set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
- crp->cr_clp = clp;
- }
- up_read(&nn->reclaim_str_hashtbl_lock);
- kfree(name.data);
- if (crp)
- return 0;
-
-out_enoent:
- return -ENOENT;
-}
-
-static const struct nfsd4_client_tracking_ops nfsd4_legacy_tracking_ops = {
- .init = nfsd4_legacy_tracking_init,
- .exit = nfsd4_legacy_tracking_exit,
- .create = nfsd4_create_clid_dir,
- .remove = nfsd4_remove_clid_dir,
- .check = nfsd4_check_legacy_client,
- .grace_done = nfsd4_recdir_purge_old,
- .version = 1,
- .msglen = 0,
-};
-#endif /* CONFIG_NFSD_LEGACY_CLIENT_TRACKING */
-
/* Globals */
#define NFSD_PIPE_DIR "nfsd"
#define NFSD_CLD_PIPE "cld"
@@ -639,9 +78,6 @@ struct cld_net {
spinlock_t cn_lock;
struct list_head cn_list;
unsigned int cn_xid;
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
- bool cn_has_legacy;
-#endif
};
struct cld_upcall {
@@ -761,15 +197,6 @@ __cld_pipe_inprogress_downcall(const struct cld_msg_v2 __user *cmsg,
name.data = namecopy;
name.len = namelen;
}
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
- if (name.len > 5 && memcmp(name.data, "hash:", 5) == 0) {
- struct cld_net *cn = nn->cld_net;
-
- name.len = name.len - 5;
- name.data = name.data + 5;
- cn->cn_has_legacy = true;
- }
-#endif
if (!nfs4_client_to_reclaim(name, princhash, nn))
return -EFAULT;
return nn->client_tracking_ops->msglen;
@@ -965,9 +392,6 @@ __nfsd4_init_cld_pipe(struct net *net)
}
spin_lock_init(&cn->cn_lock);
INIT_LIST_HEAD(&cn->cn_list);
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
- cn->cn_has_legacy = false;
-#endif
/*
* The pipe's methods reach @cn through nn->cld_net, so set
@@ -1243,28 +667,6 @@ nfsd4_cld_check(struct nfs4_client *clp)
if (crp)
goto found;
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
- if (nn->cld_net->cn_has_legacy) {
- char dname[HEXDIR_LEN];
- struct xdr_netobj name;
-
- nfs4_make_rec_clidname(dname, &clp->cl_name);
-
- name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
- if (!name.data) {
- dprintk("%s: failed to allocate memory for name.data!\n",
- __func__);
- up_read(&nn->reclaim_str_hashtbl_lock);
- return -ENOENT;
- }
- name.len = HEXDIR_LEN;
- crp = nfsd4_find_reclaim_client(name, nn);
- kfree(name.data);
- if (crp)
- goto found;
-
- }
-#endif
up_read(&nn->reclaim_str_hashtbl_lock);
return -ENOENT;
found:
@@ -1277,9 +679,6 @@ static int
nfsd4_cld_check_v2(struct nfs4_client *clp)
{
struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
- struct cld_net *cn = nn->cld_net;
-#endif
struct nfs4_client_reclaim *crp;
unsigned int princhashlen;
char *principal = NULL;
@@ -1294,28 +693,6 @@ nfsd4_cld_check_v2(struct nfs4_client *clp)
if (crp)
goto found;
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
- if (cn->cn_has_legacy) {
- struct xdr_netobj name;
- char dname[HEXDIR_LEN];
-
- nfs4_make_rec_clidname(dname, &clp->cl_name);
-
- name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
- if (!name.data) {
- dprintk("%s: failed to allocate memory for name.data\n",
- __func__);
- up_read(&nn->reclaim_str_hashtbl_lock);
- return -ENOENT;
- }
- name.len = HEXDIR_LEN;
- crp = nfsd4_find_reclaim_client(name, nn);
- kfree(name.data);
- if (crp)
- goto found;
-
- }
-#endif
up_read(&nn->reclaim_str_hashtbl_lock);
return -ENOENT;
found:
@@ -1610,33 +987,6 @@ static const struct nfsd4_client_tracking_ops nfsd4_cld_tracking_ops_v2 = {
.msglen = sizeof(struct cld_msg_v2),
};
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
-static inline int check_for_legacy_methods(int status, struct net *net)
-{
- struct nfsd_net *nn = net_generic(net, nfsd_net_id);
- struct path path;
-
- /*
- * See if the recoverydir exists and is a directory.
- * If it is, then use the legacy ops.
- */
- nn->client_tracking_ops = &nfsd4_legacy_tracking_ops;
- status = kern_path(nfs4_recoverydir(), LOOKUP_FOLLOW, &path);
- if (!status) {
- status = !d_is_dir(path.dentry);
- path_put(&path);
- if (status)
- return -ENOTDIR;
- }
- return status;
-}
-#else
-static inline int check_for_legacy_methods(int status, struct net *net)
-{
- return status;
-}
-#endif /* CONFIG_LEGACY_NFSD_CLIENT_TRACKING */
-
int
nfsd4_client_tracking_init(struct net *net)
{
@@ -1659,7 +1009,6 @@ nfsd4_client_tracking_init(struct net *net)
return status;
}
- status = check_for_legacy_methods(status, net);
if (status)
goto out;
do_init:
@@ -1667,7 +1016,7 @@ nfsd4_client_tracking_init(struct net *net)
out:
if (status) {
pr_warn("NFSD: Unable to initialize client recovery tracking! (%d)\n", status);
- pr_warn("NFSD: Is nfsdcld running? If not, enable CONFIG_NFSD_LEGACY_CLIENT_TRACKING.\n");
+ pr_warn("NFSD: Is nfsdcld running?\n");
nn->client_tracking_ops = NULL;
}
return status;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index e2455a549e25..2ea9c43eb206 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -57,7 +57,6 @@ enum {
NFSD_Filecache,
NFSD_Leasetime,
NFSD_Gracetime,
- NFSD_RecoveryDir,
NFSD_V4EndGrace,
NFSD_MaxReserved
};
@@ -76,9 +75,6 @@ static ssize_t write_maxblksize(struct file *file, char *buf, size_t size);
#ifdef CONFIG_NFSD_V4
static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
static ssize_t write_gracetime(struct file *file, char *buf, size_t size);
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
-static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
-#endif
static ssize_t write_v4_end_grace(struct file *file, char *buf, size_t size);
#endif
@@ -94,9 +90,6 @@ static ssize_t (*const write_op[])(struct file *, char *, size_t) = {
#ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = write_leasetime,
[NFSD_Gracetime] = write_gracetime,
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
- [NFSD_RecoveryDir] = write_recoverydir,
-#endif
[NFSD_V4EndGrace] = write_v4_end_grace,
#endif
};
@@ -1031,75 +1024,6 @@ static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
}
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
-static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
- struct nfsd_net *nn)
-{
- char *mesg = buf;
- char *recdir;
- int len, status;
-
- if (size > 0) {
- if (nn->nfsd_serv)
- return -EBUSY;
- if (size > PATH_MAX || buf[size-1] != '\n')
- return -EINVAL;
- buf[size-1] = 0;
-
- recdir = mesg;
- len = qword_get(&mesg, recdir, size);
- if (len <= 0)
- return -EINVAL;
- trace_nfsd_ctl_recoverydir(netns(file), recdir);
-
- status = nfs4_reset_recoverydir(recdir);
- if (status)
- return status;
- }
-
- return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%s\n",
- nfs4_recoverydir());
-}
-
-/*
- * write_recoverydir - Set or report the pathname of the recovery directory
- *
- * Input:
- * buf: ignored
- * size: zero
- *
- * OR
- *
- * Input:
- * buf: C string containing the pathname
- * of the directory on a local file
- * system containing permanent NFSv4
- * recovery data
- * size: non-zero length of C string in @buf
- * Output:
- * On success: passed-in buffer filled with '\n'-terminated C string
- * containing the current recovery pathname setting;
- * return code is the size in bytes of the string
- * On error: return code is zero or a negative errno value
- */
-static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
-{
- ssize_t rv;
- struct nfsd_net *nn = net_generic(netns(file), nfsd_net_id);
-
- /*
- * nn->nfsd_mutex guards the nn->nfsd_serv check; the recovery
- * dirname itself is still shared between namespaces.
- */
- mutex_lock(&nn->nfsd_mutex);
- mutex_lock(&nfsd_global_mutex);
- rv = __write_recoverydir(file, buf, size, nn);
- mutex_unlock(&nfsd_global_mutex);
- mutex_unlock(&nn->nfsd_mutex);
- return rv;
-}
-#endif
-
/*
* write_v4_end_grace - release grace period for nfsd's v4.x lock manager
*
@@ -1342,9 +1266,6 @@ static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc)
#ifdef CONFIG_NFSD_V4
[NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
[NFSD_Gracetime] = {"nfsv4gracetime", &transaction_ops, S_IWUSR|S_IRUSR},
-#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
- [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
-#endif
[NFSD_V4EndGrace] = {"v4_end_grace", &transaction_ops, S_IWUSR|S_IRUGO},
#endif
/* last one */ {""}
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index cd9294f024bb..7803945708d6 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -35,7 +35,6 @@
#ifndef _NFSD4_STATE_H
#define _NFSD4_STATE_H
-#include <crypto/md5.h>
#include <linux/filelock.h>
#include <linux/idr.h>
@@ -500,9 +499,6 @@ struct nfsd4_sessionid {
u32 reserved;
};
-/* Length of MD5 digest as hex, plus terminating '\0' */
-#define HEXDIR_LEN (2 * MD5_DIGEST_SIZE + 1)
-
/*
* State Meaning Where set
* --------------------------------------------------------------------------
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 1febb42a008f..ad106d627fe7 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -2310,25 +2310,6 @@ TRACE_EVENT(nfsd_ctl_time,
)
);
-TRACE_EVENT(nfsd_ctl_recoverydir,
- TP_PROTO(
- const struct net *net,
- const char *recdir
- ),
- TP_ARGS(net, recdir),
- TP_STRUCT__entry(
- __field(unsigned int, netns_ino)
- __string(recdir, recdir)
- ),
- TP_fast_assign(
- __entry->netns_ino = net->ns.inum;
- __assign_str(recdir);
- ),
- TP_printk("recdir=%s",
- __get_str(recdir)
- )
-);
-
TRACE_EVENT(nfsd_end_grace,
TP_PROTO(
const struct net *net
--
2.55.0
next prev parent reply other threads:[~2026-09-23 16:14 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-23 16:14 [PATCH 0/2] nfsd: remove legacy tracking methods Jeff Layton
2026-09-23 16:14 ` [PATCH 1/2] nfsd: remove the nfsdcltrack usermodehelper tracking backend Jeff Layton
2026-09-23 16:14 ` Jeff Layton [this message]
2026-09-23 18:25 ` [PATCH 0/2] nfsd: remove legacy tracking methods 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=20260923-nfsd-legacy-v1-2-8490c0c12ea5@kernel.org \
--to=jlayton@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=cel@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neil@brown.name \
--cc=okorniev@redhat.com \
--cc=smayhew@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
all inboxes | Powered by JetHome®