@@ -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
*/
@@ -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 *);
@@ -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;
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(+)