aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorBenjamin Coddington <bcodding@redhat.com>2023-06-15 14:07:30 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2023-06-19 15:08:12 -0400
commitd9615d166c7ede67bf16bdd0772e35e124f305f5 (patch)
tree7e527b93c0c0ab2e63f9455bbae7d8c6a8d3d9ae /fs/nfs
parentf4057ffd0e134e54a727e00c3c9b0d9a5051eadf (diff)
downloadlinux-d9615d166c7ede67bf16bdd0772e35e124f305f5.tar.gz
NFS: add sysfs shutdown knob
Within each nfs_server sysfs tree, add an entry named "shutdown". Writing 1 to this file will set the cl_shutdown bit on the rpc_clnt structs associated with that mount. If cl_shutdown is set, the task scheduler immediately returns -EIO for new tasks. Signed-off-by: Benjamin Coddington <bcodding@redhat.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/sysfs.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/fs/nfs/sysfs.c b/fs/nfs/sysfs.c
index 7009de149158a..1fedbaff10e99 100644
--- a/fs/nfs/sysfs.c
+++ b/fs/nfs/sysfs.c
@@ -12,6 +12,7 @@
#include <linux/string.h>
#include <linux/nfs_fs.h>
#include <linux/rcupdate.h>
+#include <linux/lockd/lockd.h>
#include "nfs4_fs.h"
#include "netns.h"
@@ -216,6 +217,50 @@ void nfs_netns_sysfs_destroy(struct nfs_net *netns)
}
}
+static ssize_t
+shutdown_show(struct kobject *kobj, struct kobj_attribute *attr,
+ char *buf)
+{
+ struct nfs_server *server = container_of(kobj, struct nfs_server, kobj);
+ bool shutdown = server->flags & NFS_MOUNT_SHUTDOWN;
+ return sysfs_emit(buf, "%d\n", shutdown);
+}
+
+static ssize_t
+shutdown_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct nfs_server *server;
+ int ret, val;
+
+ server = container_of(kobj, struct nfs_server, kobj);
+
+ ret = kstrtoint(buf, 0, &val);
+ if (ret)
+ return ret;
+
+ if (val != 1)
+ return -EINVAL;
+
+ /* already shut down? */
+ if (server->flags & NFS_MOUNT_SHUTDOWN)
+ goto out;
+
+ server->flags |= NFS_MOUNT_SHUTDOWN;
+ server->client->cl_shutdown = 1;
+ server->nfs_client->cl_rpcclient->cl_shutdown = 1;
+
+ if (!IS_ERR(server->client_acl))
+ server->client_acl->cl_shutdown = 1;
+
+ if (server->nlm_host)
+ server->nlm_host->h_rpcclnt->cl_shutdown = 1;
+out:
+ return count;
+}
+
+static struct kobj_attribute nfs_sysfs_attr_shutdown = __ATTR_RW(shutdown);
+
#define RPC_CLIENT_NAME_SIZE 64
void nfs_sysfs_link_rpc_client(struct nfs_server *server,
@@ -259,9 +304,16 @@ void nfs_sysfs_add_server(struct nfs_server *server)
ret = kobject_init_and_add(&server->kobj, &nfs_sb_ktype,
&nfs_kset->kobj, "server-%d", server->s_sysfs_id);
- if (ret < 0)
+ if (ret < 0) {
pr_warn("NFS: nfs sysfs add server-%d failed (%d)\n",
server->s_sysfs_id, ret);
+ return;
+ }
+ ret = sysfs_create_file_ns(&server->kobj, &nfs_sysfs_attr_shutdown.attr,
+ nfs_netns_server_namespace(&server->kobj));
+ if (ret < 0)
+ pr_warn("NFS: sysfs_create_file_ns for server-%d failed (%d)\n",
+ server->s_sysfs_id, ret);
}
EXPORT_SYMBOL_GPL(nfs_sysfs_add_server);