summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorTrond Myklebust2009-06-17 22:22:59 +0200
committerTrond Myklebust2009-06-17 22:22:59 +0200
commit965b5d679146c9f69bc0325388bb9ed357863c4f (patch)
treed70fe13004404f1d3a203c8b9b90aa5f61150115 /fs/nfs/nfs4state.c
parentNFSv4: Move error handling out of the delegation generic code (diff)
downloadkernel-qcow2-linux-965b5d679146c9f69bc0325388bb9ed357863c4f.tar.gz
kernel-qcow2-linux-965b5d679146c9f69bc0325388bb9ed357863c4f.tar.xz
kernel-qcow2-linux-965b5d679146c9f69bc0325388bb9ed357863c4f.zip
NFSv4: Handle more errors when recovering open file and locking state
It is possible for servers to return NFS4ERR_BAD_STATEID when the state management code is recovering locks or is reclaiming state when returning a delegation. Ensure that we handle that case. While we're at it, add in handlers for NFS4ERR_STALE, NFS4ERR_ADMIN_REVOKED, NFS4ERR_OPENMODE, NFS4ERR_DENIED and NFS4ERR_STALE_STATEID, since the protocol appears to allow for them too. Also handle ENOMEM... Finally, rather than add new NFSv4.0-specific errors and error handling into the generic delegation code, move that open file and locking state error handling into the NFSv4 layer. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 0298e909559f..6e094e95cf0f 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -854,25 +854,29 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
if (nfs_file_open_context(fl->fl_file)->state != state)
continue;
status = ops->recover_lock(state, fl);
- if (status >= 0)
- continue;
switch (status) {
+ case 0:
+ break;
+ case -ESTALE:
+ case -NFS4ERR_ADMIN_REVOKED:
+ case -NFS4ERR_STALE_STATEID:
+ case -NFS4ERR_BAD_STATEID:
+ case -NFS4ERR_EXPIRED:
+ case -NFS4ERR_NO_GRACE:
+ case -NFS4ERR_STALE_CLIENTID:
+ goto out;
default:
printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
__func__, status);
- case -NFS4ERR_EXPIRED:
- case -NFS4ERR_NO_GRACE:
+ case -ENOMEM:
+ case -NFS4ERR_DENIED:
case -NFS4ERR_RECLAIM_BAD:
case -NFS4ERR_RECLAIM_CONFLICT:
/* kill_proc(fl->fl_pid, SIGLOST, 1); */
- break;
- case -NFS4ERR_STALE_CLIENTID:
- goto out_err;
+ status = 0;
}
}
- up_write(&nfsi->rwsem);
- return 0;
-out_err:
+out:
up_write(&nfsi->rwsem);
return status;
}
@@ -918,6 +922,7 @@ restart:
printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
__func__, status);
case -ENOENT:
+ case -ENOMEM:
case -ESTALE:
/*
* Open state on this file cannot be recovered
@@ -928,6 +933,9 @@ restart:
/* Mark the file as being 'closed' */
state->state = 0;
break;
+ case -NFS4ERR_ADMIN_REVOKED:
+ case -NFS4ERR_STALE_STATEID:
+ case -NFS4ERR_BAD_STATEID:
case -NFS4ERR_RECLAIM_BAD:
case -NFS4ERR_RECLAIM_CONFLICT:
nfs4_state_mark_reclaim_nograce(sp->so_client, state);