aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-17 16:22:59 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-06-17 16:22:59 -0400
commit965b5d679146c9f69bc0325388bb9ed357863c4f (patch)
treed70fe13004404f1d3a203c8b9b90aa5f61150115 /fs/nfs/nfs4state.c
parentd5122201a7f90b2aa73092f158b84d1d74f1134d (diff)
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_
854 if (nfs_file_open_context(fl->fl_file)->state != state) 854 if (nfs_file_open_context(fl->fl_file)->state != state)
855 continue; 855 continue;
856 status = ops->recover_lock(state, fl); 856 status = ops->recover_lock(state, fl);
857 if (status >= 0)
858 continue;
859 switch (status) { 857 switch (status) {
858 case 0:
859 break;
860 case -ESTALE:
861 case -NFS4ERR_ADMIN_REVOKED:
862 case -NFS4ERR_STALE_STATEID:
863 case -NFS4ERR_BAD_STATEID:
864 case -NFS4ERR_EXPIRED:
865 case -NFS4ERR_NO_GRACE:
866 case -NFS4ERR_STALE_CLIENTID:
867 goto out;
860 default: 868 default:
861 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n", 869 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
862 __func__, status); 870 __func__, status);
863 case -NFS4ERR_EXPIRED: 871 case -ENOMEM:
864 case -NFS4ERR_NO_GRACE: 872 case -NFS4ERR_DENIED:
865 case -NFS4ERR_RECLAIM_BAD: 873 case -NFS4ERR_RECLAIM_BAD:
866 case -NFS4ERR_RECLAIM_CONFLICT: 874 case -NFS4ERR_RECLAIM_CONFLICT:
867 /* kill_proc(fl->fl_pid, SIGLOST, 1); */ 875 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
868 break; 876 status = 0;
869 case -NFS4ERR_STALE_CLIENTID:
870 goto out_err;
871 } 877 }
872 } 878 }
873 up_write(&nfsi->rwsem); 879out:
874 return 0;
875out_err:
876 up_write(&nfsi->rwsem); 880 up_write(&nfsi->rwsem);
877 return status; 881 return status;
878} 882}
@@ -918,6 +922,7 @@ restart:
918 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n", 922 printk(KERN_ERR "%s: unhandled error %d. Zeroing state\n",
919 __func__, status); 923 __func__, status);
920 case -ENOENT: 924 case -ENOENT:
925 case -ENOMEM:
921 case -ESTALE: 926 case -ESTALE:
922 /* 927 /*
923 * Open state on this file cannot be recovered 928 * Open state on this file cannot be recovered
@@ -928,6 +933,9 @@ restart:
928 /* Mark the file as being 'closed' */ 933 /* Mark the file as being 'closed' */
929 state->state = 0; 934 state->state = 0;
930 break; 935 break;
936 case -NFS4ERR_ADMIN_REVOKED:
937 case -NFS4ERR_STALE_STATEID:
938 case -NFS4ERR_BAD_STATEID:
931 case -NFS4ERR_RECLAIM_BAD: 939 case -NFS4ERR_RECLAIM_BAD:
932 case -NFS4ERR_RECLAIM_CONFLICT: 940 case -NFS4ERR_RECLAIM_CONFLICT:
933 nfs4_state_mark_reclaim_nograce(sp->so_client, state); 941 nfs4_state_mark_reclaim_nograce(sp->so_client, state);