diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2013-10-17 14:13:19 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-10-28 15:25:23 -0400 |
commit | 519ae255d403219fd5375de13c95dea3ef1cfda0 (patch) | |
tree | 5357dbbdbc9bf9eb05bdc2d192ec1b7124e010df /fs/nfs | |
parent | 9f51a78e3a637a5923c661d2abe958c63441696f (diff) |
NFS: Add migration recovery callouts in nfs4proc.c
When a server returns NFS4ERR_MOVED, trigger the new migration
recovery logic in the state manager.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index fa87f81527b3..a1f620950f11 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -384,6 +384,11 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc | |||
384 | case -NFS4ERR_STALE_CLIENTID: | 384 | case -NFS4ERR_STALE_CLIENTID: |
385 | nfs4_schedule_lease_recovery(clp); | 385 | nfs4_schedule_lease_recovery(clp); |
386 | goto wait_on_recovery; | 386 | goto wait_on_recovery; |
387 | case -NFS4ERR_MOVED: | ||
388 | ret = nfs4_schedule_migration_recovery(server); | ||
389 | if (ret < 0) | ||
390 | break; | ||
391 | goto wait_on_recovery; | ||
387 | #if defined(CONFIG_NFS_V4_1) | 392 | #if defined(CONFIG_NFS_V4_1) |
388 | case -NFS4ERR_BADSESSION: | 393 | case -NFS4ERR_BADSESSION: |
389 | case -NFS4ERR_BADSLOT: | 394 | case -NFS4ERR_BADSLOT: |
@@ -431,6 +436,8 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc | |||
431 | return nfs4_map_errors(ret); | 436 | return nfs4_map_errors(ret); |
432 | wait_on_recovery: | 437 | wait_on_recovery: |
433 | ret = nfs4_wait_clnt_recover(clp); | 438 | ret = nfs4_wait_clnt_recover(clp); |
439 | if (test_bit(NFS_MIG_FAILED, &server->mig_status)) | ||
440 | return -EIO; | ||
434 | if (ret == 0) | 441 | if (ret == 0) |
435 | exception->retry = 1; | 442 | exception->retry = 1; |
436 | return ret; | 443 | return ret; |
@@ -2974,11 +2981,16 @@ static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir, | |||
2974 | status = nfs4_proc_fs_locations(client, dir, name, locations, page); | 2981 | status = nfs4_proc_fs_locations(client, dir, name, locations, page); |
2975 | if (status != 0) | 2982 | if (status != 0) |
2976 | goto out; | 2983 | goto out; |
2977 | /* Make sure server returned a different fsid for the referral */ | 2984 | |
2985 | /* | ||
2986 | * If the fsid didn't change, this is a migration event, not a | ||
2987 | * referral. Cause us to drop into the exception handler, which | ||
2988 | * will kick off migration recovery. | ||
2989 | */ | ||
2978 | if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { | 2990 | if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) { |
2979 | dprintk("%s: server did not return a different fsid for" | 2991 | dprintk("%s: server did not return a different fsid for" |
2980 | " a referral at %s\n", __func__, name->name); | 2992 | " a referral at %s\n", __func__, name->name); |
2981 | status = -EIO; | 2993 | status = -NFS4ERR_MOVED; |
2982 | goto out; | 2994 | goto out; |
2983 | } | 2995 | } |
2984 | /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */ | 2996 | /* Fixup attributes for the nfs_lookup() call to nfs_fhget() */ |
@@ -4739,6 +4751,10 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
4739 | case -NFS4ERR_STALE_CLIENTID: | 4751 | case -NFS4ERR_STALE_CLIENTID: |
4740 | nfs4_schedule_lease_recovery(clp); | 4752 | nfs4_schedule_lease_recovery(clp); |
4741 | goto wait_on_recovery; | 4753 | goto wait_on_recovery; |
4754 | case -NFS4ERR_MOVED: | ||
4755 | if (nfs4_schedule_migration_recovery(server) < 0) | ||
4756 | goto recovery_failed; | ||
4757 | goto wait_on_recovery; | ||
4742 | #if defined(CONFIG_NFS_V4_1) | 4758 | #if defined(CONFIG_NFS_V4_1) |
4743 | case -NFS4ERR_BADSESSION: | 4759 | case -NFS4ERR_BADSESSION: |
4744 | case -NFS4ERR_BADSLOT: | 4760 | case -NFS4ERR_BADSLOT: |
@@ -4769,6 +4785,8 @@ wait_on_recovery: | |||
4769 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); | 4785 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); |
4770 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) | 4786 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) |
4771 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); | 4787 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); |
4788 | if (test_bit(NFS_MIG_FAILED, &server->mig_status)) | ||
4789 | goto recovery_failed; | ||
4772 | restart_call: | 4790 | restart_call: |
4773 | task->tk_status = 0; | 4791 | task->tk_status = 0; |
4774 | return -EAGAIN; | 4792 | return -EAGAIN; |