mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 04:06:26 +00:00
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>
This commit is contained in:
parent
f4057ffd0e
commit
d9615d166c
@ -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);
|
||||
|
||||
|
@ -154,6 +154,7 @@ struct nfs_server {
|
||||
#define NFS_MOUNT_WRITE_EAGER 0x01000000
|
||||
#define NFS_MOUNT_WRITE_WAIT 0x02000000
|
||||
#define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000
|
||||
#define NFS_MOUNT_SHUTDOWN 0x08000000
|
||||
|
||||
unsigned int fattr_valid; /* Valid attributes */
|
||||
unsigned int caps; /* server capabilities */
|
||||
|
@ -63,7 +63,8 @@ struct rpc_clnt {
|
||||
cl_discrtry : 1,/* disconnect before retry */
|
||||
cl_noretranstimeo: 1,/* No retransmit timeouts */
|
||||
cl_autobind : 1,/* use getport() */
|
||||
cl_chatty : 1;/* be verbose */
|
||||
cl_chatty : 1,/* be verbose */
|
||||
cl_shutdown : 1;/* rpc immediate -EIO */
|
||||
struct xprtsec_parms cl_xprtsec; /* transport security policy */
|
||||
|
||||
struct rpc_rtt * cl_rtt; /* RTO estimator data */
|
||||
|
@ -1724,6 +1724,11 @@ call_start(struct rpc_task *task)
|
||||
|
||||
trace_rpc_request(task);
|
||||
|
||||
if (task->tk_client->cl_shutdown) {
|
||||
rpc_call_rpcerror(task, -EIO);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Increment call count (version might not be valid for ping) */
|
||||
if (clnt->cl_program->version[clnt->cl_vers])
|
||||
clnt->cl_program->version[clnt->cl_vers]->counts[idx]++;
|
||||
|
Loading…
Reference in New Issue
Block a user