aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-09-20 15:51:00 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-10-08 10:45:53 -0400
commit037fc9808a777f6fb6a54c6510b9656716e0c8c8 (patch)
tree8301d284d71794be52b24b4e791a1f4360a8405d
parent4816fdadab9ff874ec1a4138dad43b636c7d220b (diff)
NFSv4: Unify synchronous and asynchronous error handling
They now only differ in the way we handle waiting, so let's unify. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/nfs4proc.c123
1 files changed, 49 insertions, 74 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 2a155ec05f6d..e32b7e93f253 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -78,7 +78,6 @@ struct nfs4_opendata;
78static int _nfs4_proc_open(struct nfs4_opendata *data); 78static int _nfs4_proc_open(struct nfs4_opendata *data);
79static int _nfs4_recover_proc_open(struct nfs4_opendata *data); 79static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
80static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); 80static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
81static int nfs4_async_handle_error(struct rpc_task *, struct nfs_server *, struct nfs4_state *, long *);
82static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr); 81static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
83static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label); 82static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label);
84static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label); 83static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label);
@@ -466,6 +465,55 @@ out_retry:
466 return ret; 465 return ret;
467} 466}
468 467
468static int
469nfs4_async_handle_exception(struct rpc_task *task, struct nfs_server *server,
470 int errorcode, struct nfs4_exception *exception)
471{
472 struct nfs_client *clp = server->nfs_client;
473 int ret;
474
475 ret = nfs4_do_handle_exception(server, errorcode, exception);
476 if (exception->delay) {
477 rpc_delay(task, nfs4_update_delay(&exception->timeout));
478 goto out_retry;
479 }
480 if (exception->recovering) {
481 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
482 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
483 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
484 goto out_retry;
485 }
486 if (test_bit(NFS_MIG_FAILED, &server->mig_status))
487 ret = -EIO;
488 return ret;
489out_retry:
490 if (ret == 0)
491 exception->retry = 1;
492 return ret;
493}
494
495static int
496nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server,
497 struct nfs4_state *state, long *timeout)
498{
499 struct nfs4_exception exception = {
500 .state = state,
501 };
502
503 if (task->tk_status >= 0)
504 return 0;
505 if (timeout)
506 exception.timeout = *timeout;
507 task->tk_status = nfs4_async_handle_exception(task, server,
508 task->tk_status,
509 &exception);
510 if (exception.delay && timeout)
511 *timeout = exception.timeout;
512 if (exception.retry)
513 return -EAGAIN;
514 return 0;
515}
516
469/* 517/*
470 * Return 'true' if 'clp' is using an rpc_client that is integrity protected 518 * Return 'true' if 'clp' is using an rpc_client that is integrity protected
471 * or 'false' otherwise. 519 * or 'false' otherwise.
@@ -4979,79 +5027,6 @@ out:
4979#endif /* CONFIG_NFS_V4_SECURITY_LABEL */ 5027#endif /* CONFIG_NFS_V4_SECURITY_LABEL */
4980 5028
4981 5029
4982static int
4983nfs4_async_handle_error(struct rpc_task *task, struct nfs_server *server,
4984 struct nfs4_state *state, long *timeout)
4985{
4986 struct nfs_client *clp = server->nfs_client;
4987
4988 if (task->tk_status >= 0)
4989 return 0;
4990 switch(task->tk_status) {
4991 case -NFS4ERR_DELEG_REVOKED:
4992 case -NFS4ERR_ADMIN_REVOKED:
4993 case -NFS4ERR_BAD_STATEID:
4994 case -NFS4ERR_OPENMODE:
4995 if (state == NULL)
4996 break;
4997 if (nfs4_schedule_stateid_recovery(server, state) < 0)
4998 goto recovery_failed;
4999 goto wait_on_recovery;
5000 case -NFS4ERR_EXPIRED:
5001 if (state != NULL) {
5002 if (nfs4_schedule_stateid_recovery(server, state) < 0)
5003 goto recovery_failed;
5004 }
5005 case -NFS4ERR_STALE_STATEID:
5006 case -NFS4ERR_STALE_CLIENTID:
5007 nfs4_schedule_lease_recovery(clp);
5008 goto wait_on_recovery;
5009 case -NFS4ERR_MOVED:
5010 if (nfs4_schedule_migration_recovery(server) < 0)
5011 goto recovery_failed;
5012 goto wait_on_recovery;
5013 case -NFS4ERR_LEASE_MOVED:
5014 nfs4_schedule_lease_moved_recovery(clp);
5015 goto wait_on_recovery;
5016#if defined(CONFIG_NFS_V4_1)
5017 case -NFS4ERR_BADSESSION:
5018 case -NFS4ERR_BADSLOT:
5019 case -NFS4ERR_BAD_HIGH_SLOT:
5020 case -NFS4ERR_DEADSESSION:
5021 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
5022 case -NFS4ERR_SEQ_FALSE_RETRY:
5023 case -NFS4ERR_SEQ_MISORDERED:
5024 dprintk("%s ERROR %d, Reset session\n", __func__,
5025 task->tk_status);
5026 nfs4_schedule_session_recovery(clp->cl_session, task->tk_status);
5027 goto wait_on_recovery;
5028#endif /* CONFIG_NFS_V4_1 */
5029 case -NFS4ERR_DELAY:
5030 nfs_inc_server_stats(server, NFSIOS_DELAY);
5031 rpc_delay(task, nfs4_update_delay(timeout));
5032 goto restart_call;
5033 case -NFS4ERR_GRACE:
5034 rpc_delay(task, NFS4_POLL_RETRY_MAX);
5035 case -NFS4ERR_RETRY_UNCACHED_REP:
5036 case -NFS4ERR_OLD_STATEID:
5037 goto restart_call;
5038 }
5039 task->tk_status = nfs4_map_errors(task->tk_status);
5040 return 0;
5041recovery_failed:
5042 task->tk_status = -EIO;
5043 return 0;
5044wait_on_recovery:
5045 rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
5046 if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
5047 rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
5048 if (test_bit(NFS_MIG_FAILED, &server->mig_status))
5049 goto recovery_failed;
5050restart_call:
5051 task->tk_status = 0;
5052 return -EAGAIN;
5053}
5054
5055static void nfs4_init_boot_verifier(const struct nfs_client *clp, 5030static void nfs4_init_boot_verifier(const struct nfs_client *clp,
5056 nfs4_verifier *bootverf) 5031 nfs4_verifier *bootverf)
5057{ 5032{