diff options
| author | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-09-27 17:41:51 -0400 |
|---|---|---|
| committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2014-09-28 16:03:04 -0400 |
| commit | df817ba35736db2d62b07de6f050a4db53492ad8 (patch) | |
| tree | 17ec04c7b55512954968f5873bb55d613eca3072 /fs/nfs | |
| parent | a4339b7b686b4acc8b6de2b07d7bacbe3ae44b83 (diff) | |
NFSv4: fix open/lock state recovery error handling
The current open/lock state recovery unfortunately does not handle errors
such as NFS4ERR_CONN_NOT_BOUND_TO_SESSION correctly. Instead of looping,
just proceeds as if the state manager is finished recovering.
This patch ensures that we loop back, handle higher priority errors
and complete the open/lock state recovery.
Cc: stable@vger.kernel.org
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
| -rw-r--r-- | fs/nfs/nfs4state.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 26d510d11efd..87b2d0e79797 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
| @@ -1705,7 +1705,8 @@ restart: | |||
| 1705 | if (status < 0) { | 1705 | if (status < 0) { |
| 1706 | set_bit(ops->owner_flag_bit, &sp->so_flags); | 1706 | set_bit(ops->owner_flag_bit, &sp->so_flags); |
| 1707 | nfs4_put_state_owner(sp); | 1707 | nfs4_put_state_owner(sp); |
| 1708 | return nfs4_recovery_handle_error(clp, status); | 1708 | status = nfs4_recovery_handle_error(clp, status); |
| 1709 | return (status != 0) ? status : -EAGAIN; | ||
| 1709 | } | 1710 | } |
| 1710 | 1711 | ||
| 1711 | nfs4_put_state_owner(sp); | 1712 | nfs4_put_state_owner(sp); |
| @@ -1714,7 +1715,7 @@ restart: | |||
| 1714 | spin_unlock(&clp->cl_lock); | 1715 | spin_unlock(&clp->cl_lock); |
| 1715 | } | 1716 | } |
| 1716 | rcu_read_unlock(); | 1717 | rcu_read_unlock(); |
| 1717 | return status; | 1718 | return 0; |
| 1718 | } | 1719 | } |
| 1719 | 1720 | ||
| 1720 | static int nfs4_check_lease(struct nfs_client *clp) | 1721 | static int nfs4_check_lease(struct nfs_client *clp) |
| @@ -2365,14 +2366,11 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
| 2365 | section = "reclaim reboot"; | 2366 | section = "reclaim reboot"; |
| 2366 | status = nfs4_do_reclaim(clp, | 2367 | status = nfs4_do_reclaim(clp, |
| 2367 | clp->cl_mvops->reboot_recovery_ops); | 2368 | clp->cl_mvops->reboot_recovery_ops); |
| 2368 | if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) || | 2369 | if (status == -EAGAIN) |
| 2369 | test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state)) | ||
| 2370 | continue; | ||
| 2371 | nfs4_state_end_reclaim_reboot(clp); | ||
| 2372 | if (test_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) | ||
| 2373 | continue; | 2370 | continue; |
| 2374 | if (status < 0) | 2371 | if (status < 0) |
| 2375 | goto out_error; | 2372 | goto out_error; |
| 2373 | nfs4_state_end_reclaim_reboot(clp); | ||
| 2376 | } | 2374 | } |
| 2377 | 2375 | ||
| 2378 | /* Now recover expired state... */ | 2376 | /* Now recover expired state... */ |
| @@ -2380,9 +2378,7 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
| 2380 | section = "reclaim nograce"; | 2378 | section = "reclaim nograce"; |
| 2381 | status = nfs4_do_reclaim(clp, | 2379 | status = nfs4_do_reclaim(clp, |
| 2382 | clp->cl_mvops->nograce_recovery_ops); | 2380 | clp->cl_mvops->nograce_recovery_ops); |
| 2383 | if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) || | 2381 | if (status == -EAGAIN) |
| 2384 | test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) || | ||
| 2385 | test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) | ||
| 2386 | continue; | 2382 | continue; |
| 2387 | if (status < 0) | 2383 | if (status < 0) |
| 2388 | goto out_error; | 2384 | goto out_error; |
