[RFC,v3,6/7] NFS: Add API to fail client
diff mbox

Message ID 20171114230631.14682-7-JPEWhacker@gmail.com
State New
Headers show

Commit Message

Joshua Watt Nov. 14, 2017, 11:06 p.m. UTC
Failing a client will cause all current and future RPCs sent to it to
fail with -EIO

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
---
 fs/nfs/client.c           | 25 +++++++++++++++++++++++++
 fs/nfs/internal.h         |  1 +
 include/linux/nfs_fs_sb.h |  2 ++
 3 files changed, 28 insertions(+)

Patch
diff mbox

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 9d88dea4bc59..0e41b8d5904a 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -758,6 +758,31 @@  static int nfs_init_server(struct nfs_server *server,
 	return error;
 }
 
+static void
+fail_rpc_client(struct rpc_clnt *client, bool failed)
+{
+	if (IS_ERR(client))
+		return;
+
+	client->cl_kill_new_tasks = failed;
+	if (failed)
+		rpc_killall_tasks(client);
+}
+
+void
+nfs_client_failed(struct nfs_client *client, bool failed)
+{
+	struct nfs_server *server;
+
+	client->cl_failed = failed;
+	fail_rpc_client(client->cl_rpcclient, failed);
+
+	list_for_each_entry_rcu(server, &client->cl_superblocks, client_link) {
+		fail_rpc_client(server->client, failed);
+		fail_rpc_client(server->client_acl, failed);
+	}
+}
+
 /*
  * Load up the server record from information gained in an fsinfo record
  */
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 75da8185ceb8..b713f9f38d6d 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -159,6 +159,7 @@  extern void nfs_clients_init(struct net *net);
 void nfs_cleanup_client_ids(void);
 extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
 int nfs_create_rpc_client(struct nfs_client *, const struct nfs_client_initdata *, rpc_authflavor_t);
+void nfs_client_failed(struct nfs_client *client, bool failed);
 struct nfs_client *nfs_get_client(const struct nfs_client_initdata *);
 int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *, struct nfs_fattr *);
 void nfs_server_insert_lists(struct nfs_server *);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 0eb7093faea7..6d182da286a2 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -58,6 +58,8 @@  struct nfs_client {
 	int			cl_proto;	/* Network transport protocol */
 	struct nfs_subversion *	cl_nfs_mod;	/* pointer to nfs version module */
 
+	bool			cl_failed;	/* Client has failed */
+
 	u32			cl_minorversion;/* NFSv4 minorversion */
 	struct rpc_cred		*cl_machine_cred;