Skip to content

Commit d9615d1

Browse files
bcodding-rhTrond Myklebust
authored andcommitted
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 <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent f4057ff commit d9615d1

File tree

4 files changed

+61
-2
lines changed

4 files changed

+61
-2
lines changed

fs/nfs/sysfs.c

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/string.h>
1313
#include <linux/nfs_fs.h>
1414
#include <linux/rcupdate.h>
15+
#include <linux/lockd/lockd.h>
1516

1617
#include "nfs4_fs.h"
1718
#include "netns.h"
@@ -216,6 +217,50 @@ void nfs_netns_sysfs_destroy(struct nfs_net *netns)
216217
}
217218
}
218219

220+
static ssize_t
221+
shutdown_show(struct kobject *kobj, struct kobj_attribute *attr,
222+
char *buf)
223+
{
224+
struct nfs_server *server = container_of(kobj, struct nfs_server, kobj);
225+
bool shutdown = server->flags & NFS_MOUNT_SHUTDOWN;
226+
return sysfs_emit(buf, "%d\n", shutdown);
227+
}
228+
229+
static ssize_t
230+
shutdown_store(struct kobject *kobj, struct kobj_attribute *attr,
231+
const char *buf, size_t count)
232+
{
233+
struct nfs_server *server;
234+
int ret, val;
235+
236+
server = container_of(kobj, struct nfs_server, kobj);
237+
238+
ret = kstrtoint(buf, 0, &val);
239+
if (ret)
240+
return ret;
241+
242+
if (val != 1)
243+
return -EINVAL;
244+
245+
/* already shut down? */
246+
if (server->flags & NFS_MOUNT_SHUTDOWN)
247+
goto out;
248+
249+
server->flags |= NFS_MOUNT_SHUTDOWN;
250+
server->client->cl_shutdown = 1;
251+
server->nfs_client->cl_rpcclient->cl_shutdown = 1;
252+
253+
if (!IS_ERR(server->client_acl))
254+
server->client_acl->cl_shutdown = 1;
255+
256+
if (server->nlm_host)
257+
server->nlm_host->h_rpcclnt->cl_shutdown = 1;
258+
out:
259+
return count;
260+
}
261+
262+
static struct kobj_attribute nfs_sysfs_attr_shutdown = __ATTR_RW(shutdown);
263+
219264
#define RPC_CLIENT_NAME_SIZE 64
220265

221266
void nfs_sysfs_link_rpc_client(struct nfs_server *server,
@@ -259,9 +304,16 @@ void nfs_sysfs_add_server(struct nfs_server *server)
259304

260305
ret = kobject_init_and_add(&server->kobj, &nfs_sb_ktype,
261306
&nfs_kset->kobj, "server-%d", server->s_sysfs_id);
262-
if (ret < 0)
307+
if (ret < 0) {
263308
pr_warn("NFS: nfs sysfs add server-%d failed (%d)\n",
264309
server->s_sysfs_id, ret);
310+
return;
311+
}
312+
ret = sysfs_create_file_ns(&server->kobj, &nfs_sysfs_attr_shutdown.attr,
313+
nfs_netns_server_namespace(&server->kobj));
314+
if (ret < 0)
315+
pr_warn("NFS: sysfs_create_file_ns for server-%d failed (%d)\n",
316+
server->s_sysfs_id, ret);
265317
}
266318
EXPORT_SYMBOL_GPL(nfs_sysfs_add_server);
267319

include/linux/nfs_fs_sb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ struct nfs_server {
154154
#define NFS_MOUNT_WRITE_EAGER 0x01000000
155155
#define NFS_MOUNT_WRITE_WAIT 0x02000000
156156
#define NFS_MOUNT_TRUNK_DISCOVERY 0x04000000
157+
#define NFS_MOUNT_SHUTDOWN 0x08000000
157158

158159
unsigned int fattr_valid; /* Valid attributes */
159160
unsigned int caps; /* server capabilities */

include/linux/sunrpc/clnt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ struct rpc_clnt {
6363
cl_discrtry : 1,/* disconnect before retry */
6464
cl_noretranstimeo: 1,/* No retransmit timeouts */
6565
cl_autobind : 1,/* use getport() */
66-
cl_chatty : 1;/* be verbose */
66+
cl_chatty : 1,/* be verbose */
67+
cl_shutdown : 1;/* rpc immediate -EIO */
6768
struct xprtsec_parms cl_xprtsec; /* transport security policy */
6869

6970
struct rpc_rtt * cl_rtt; /* RTO estimator data */

net/sunrpc/clnt.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1724,6 +1724,11 @@ call_start(struct rpc_task *task)
17241724

17251725
trace_rpc_request(task);
17261726

1727+
if (task->tk_client->cl_shutdown) {
1728+
rpc_call_rpcerror(task, -EIO);
1729+
return;
1730+
}
1731+
17271732
/* Increment call count (version might not be valid for ping) */
17281733
if (clnt->cl_program->version[clnt->cl_vers])
17291734
clnt->cl_program->version[clnt->cl_vers]->counts[idx]++;

0 commit comments

Comments
 (0)