diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-05-26 14:26:35 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2011-05-27 17:42:01 -0400 |
commit | 0ced63d1a245ac11241a5d37932e6d04d9c8040d (patch) | |
tree | d5a3150e7cfc34f4f9943f8a18f32164ea1c94ec /fs/nfs | |
parent | fe19a96b10032035a35779f42ad59e35d6dd8ffd (diff) |
NFSv4: Handle expired stateids when the lease is still valid
Currently, if the server returns NFS4ERR_EXPIRED in reply to a READ or
WRITE, but the RENEW test determines that the lease is still active, we
fail to recover and end up looping forever in a READ/WRITE + RENEW death
spiral.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index cf1b339c3937..d0e15dba7a5a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -267,9 +267,11 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc | |||
267 | break; | 267 | break; |
268 | nfs4_schedule_stateid_recovery(server, state); | 268 | nfs4_schedule_stateid_recovery(server, state); |
269 | goto wait_on_recovery; | 269 | goto wait_on_recovery; |
270 | case -NFS4ERR_EXPIRED: | ||
271 | if (state != NULL) | ||
272 | nfs4_schedule_stateid_recovery(server, state); | ||
270 | case -NFS4ERR_STALE_STATEID: | 273 | case -NFS4ERR_STALE_STATEID: |
271 | case -NFS4ERR_STALE_CLIENTID: | 274 | case -NFS4ERR_STALE_CLIENTID: |
272 | case -NFS4ERR_EXPIRED: | ||
273 | nfs4_schedule_lease_recovery(clp); | 275 | nfs4_schedule_lease_recovery(clp); |
274 | goto wait_on_recovery; | 276 | goto wait_on_recovery; |
275 | #if defined(CONFIG_NFS_V4_1) | 277 | #if defined(CONFIG_NFS_V4_1) |
@@ -3670,9 +3672,11 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
3670 | break; | 3672 | break; |
3671 | nfs4_schedule_stateid_recovery(server, state); | 3673 | nfs4_schedule_stateid_recovery(server, state); |
3672 | goto wait_on_recovery; | 3674 | goto wait_on_recovery; |
3675 | case -NFS4ERR_EXPIRED: | ||
3676 | if (state != NULL) | ||
3677 | nfs4_schedule_stateid_recovery(server, state); | ||
3673 | case -NFS4ERR_STALE_STATEID: | 3678 | case -NFS4ERR_STALE_STATEID: |
3674 | case -NFS4ERR_STALE_CLIENTID: | 3679 | case -NFS4ERR_STALE_CLIENTID: |
3675 | case -NFS4ERR_EXPIRED: | ||
3676 | nfs4_schedule_lease_recovery(clp); | 3680 | nfs4_schedule_lease_recovery(clp); |
3677 | goto wait_on_recovery; | 3681 | goto wait_on_recovery; |
3678 | #if defined(CONFIG_NFS_V4_1) | 3682 | #if defined(CONFIG_NFS_V4_1) |
@@ -4543,6 +4547,7 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) | |||
4543 | case -ESTALE: | 4547 | case -ESTALE: |
4544 | goto out; | 4548 | goto out; |
4545 | case -NFS4ERR_EXPIRED: | 4549 | case -NFS4ERR_EXPIRED: |
4550 | nfs4_schedule_stateid_recovery(server, state); | ||
4546 | case -NFS4ERR_STALE_CLIENTID: | 4551 | case -NFS4ERR_STALE_CLIENTID: |
4547 | case -NFS4ERR_STALE_STATEID: | 4552 | case -NFS4ERR_STALE_STATEID: |
4548 | nfs4_schedule_lease_recovery(server->nfs_client); | 4553 | nfs4_schedule_lease_recovery(server->nfs_client); |