diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-01-26 15:42:47 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-01-26 15:42:47 -0500 |
commit | a2c0b9e291208f65221a0ad8a0c80a377707d480 (patch) | |
tree | 31bec606e1d33f97c160448e03bace4a63a2d2fb /fs/nfs/nfs4proc.c | |
parent | 03391693a95900875b0973569d2d73ff3aa8972e (diff) |
NFS: Ensure that we handle NFS4ERR_STALE_STATEID correctly
Even if the server is crazy, we should be able to mark the stateid as being
bad, to ensure it gets recovered.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index afbfe673489b..375f0fae2c6a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -249,14 +249,14 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
249 | if (state == NULL) | 249 | if (state == NULL) |
250 | break; | 250 | break; |
251 | nfs4_state_mark_reclaim_nograce(clp, state); | 251 | nfs4_state_mark_reclaim_nograce(clp, state); |
252 | case -NFS4ERR_STALE_CLIENTID: | 252 | goto do_state_recovery; |
253 | case -NFS4ERR_STALE_STATEID: | 253 | case -NFS4ERR_STALE_STATEID: |
254 | if (state == NULL) | ||
255 | break; | ||
256 | nfs4_state_mark_reclaim_reboot(clp, state); | ||
257 | case -NFS4ERR_STALE_CLIENTID: | ||
254 | case -NFS4ERR_EXPIRED: | 258 | case -NFS4ERR_EXPIRED: |
255 | nfs4_schedule_state_recovery(clp); | 259 | goto do_state_recovery; |
256 | ret = nfs4_wait_clnt_recover(clp); | ||
257 | if (ret == 0) | ||
258 | exception->retry = 1; | ||
259 | break; | ||
260 | #if defined(CONFIG_NFS_V4_1) | 260 | #if defined(CONFIG_NFS_V4_1) |
261 | case -NFS4ERR_BADSESSION: | 261 | case -NFS4ERR_BADSESSION: |
262 | case -NFS4ERR_BADSLOT: | 262 | case -NFS4ERR_BADSLOT: |
@@ -289,6 +289,12 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
289 | } | 289 | } |
290 | /* We failed to handle the error */ | 290 | /* We failed to handle the error */ |
291 | return nfs4_map_errors(ret); | 291 | return nfs4_map_errors(ret); |
292 | do_state_recovery: | ||
293 | nfs4_schedule_state_recovery(clp); | ||
294 | ret = nfs4_wait_clnt_recover(clp); | ||
295 | if (ret == 0) | ||
296 | exception->retry = 1; | ||
297 | return ret; | ||
292 | } | 298 | } |
293 | 299 | ||
294 | 300 | ||
@@ -3420,15 +3426,14 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
3420 | if (state == NULL) | 3426 | if (state == NULL) |
3421 | break; | 3427 | break; |
3422 | nfs4_state_mark_reclaim_nograce(clp, state); | 3428 | nfs4_state_mark_reclaim_nograce(clp, state); |
3423 | case -NFS4ERR_STALE_CLIENTID: | 3429 | goto do_state_recovery; |
3424 | case -NFS4ERR_STALE_STATEID: | 3430 | case -NFS4ERR_STALE_STATEID: |
3431 | if (state == NULL) | ||
3432 | break; | ||
3433 | nfs4_state_mark_reclaim_reboot(clp, state); | ||
3434 | case -NFS4ERR_STALE_CLIENTID: | ||
3425 | case -NFS4ERR_EXPIRED: | 3435 | case -NFS4ERR_EXPIRED: |
3426 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); | 3436 | goto do_state_recovery; |
3427 | nfs4_schedule_state_recovery(clp); | ||
3428 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) | ||
3429 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); | ||
3430 | task->tk_status = 0; | ||
3431 | return -EAGAIN; | ||
3432 | #if defined(CONFIG_NFS_V4_1) | 3437 | #if defined(CONFIG_NFS_V4_1) |
3433 | case -NFS4ERR_BADSESSION: | 3438 | case -NFS4ERR_BADSESSION: |
3434 | case -NFS4ERR_BADSLOT: | 3439 | case -NFS4ERR_BADSLOT: |
@@ -3456,6 +3461,13 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
3456 | } | 3461 | } |
3457 | task->tk_status = nfs4_map_errors(task->tk_status); | 3462 | task->tk_status = nfs4_map_errors(task->tk_status); |
3458 | return 0; | 3463 | return 0; |
3464 | do_state_recovery: | ||
3465 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); | ||
3466 | nfs4_schedule_state_recovery(clp); | ||
3467 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) | ||
3468 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); | ||
3469 | task->tk_status = 0; | ||
3470 | return -EAGAIN; | ||
3459 | } | 3471 | } |
3460 | 3472 | ||
3461 | static int | 3473 | static int |
@@ -4099,6 +4111,12 @@ static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_ | |||
4099 | (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) | 4111 | (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) |
4100 | nfs4_state_mark_reclaim_nograce(clp, state); | 4112 | nfs4_state_mark_reclaim_nograce(clp, state); |
4101 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; | 4113 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; |
4114 | break; | ||
4115 | case -NFS4ERR_STALE_STATEID: | ||
4116 | if (new_lock_owner != 0 || | ||
4117 | (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) | ||
4118 | nfs4_state_mark_reclaim_reboot(clp, state); | ||
4119 | lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED; | ||
4102 | }; | 4120 | }; |
4103 | } | 4121 | } |
4104 | 4122 | ||