diff options
author | Andy Adamson <andros@netapp.com> | 2012-03-07 10:49:41 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-03-07 10:53:55 -0500 |
commit | 9cb8196839ab4ec87710526e9c43ac7f5dba69d3 (patch) | |
tree | 97ea8225d7ea1b7ba45785f25d042a18263eaf8e /fs/nfs/nfs4filelayout.c | |
parent | 4f1abd226d80ef763c50e3930b369b63dffbb312 (diff) |
NFSv4.1 handle DS stateid errors
Handle DS READ and WRITE stateid errors by recovering the stateid on the MDS.
NFS4ERR_OLD_STATEID is ignored as the client always sends a
state sequenceid of zero for DS READ and WRITE stateids.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4filelayout.c')
-rw-r--r-- | fs/nfs/nfs4filelayout.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 47e8f3435d38..b2d3bb5971bb 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/sunrpc/metrics.h> | 36 | #include <linux/sunrpc/metrics.h> |
37 | 37 | ||
38 | #include "internal.h" | 38 | #include "internal.h" |
39 | #include "delegation.h" | ||
39 | #include "nfs4filelayout.h" | 40 | #include "nfs4filelayout.h" |
40 | 41 | ||
41 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD | 42 | #define NFSDBG_FACILITY NFSDBG_PNFS_LD |
@@ -86,12 +87,31 @@ static int filelayout_async_handle_error(struct rpc_task *task, | |||
86 | struct nfs_client *clp, | 87 | struct nfs_client *clp, |
87 | int *reset) | 88 | int *reset) |
88 | { | 89 | { |
90 | struct nfs_server *mds_server = NFS_SERVER(state->inode); | ||
91 | struct nfs_client *mds_client = mds_server->nfs_client; | ||
92 | |||
89 | if (task->tk_status >= 0) | 93 | if (task->tk_status >= 0) |
90 | return 0; | 94 | return 0; |
91 | |||
92 | *reset = 0; | 95 | *reset = 0; |
93 | 96 | ||
94 | switch (task->tk_status) { | 97 | switch (task->tk_status) { |
98 | /* MDS state errors */ | ||
99 | case -NFS4ERR_DELEG_REVOKED: | ||
100 | case -NFS4ERR_ADMIN_REVOKED: | ||
101 | case -NFS4ERR_BAD_STATEID: | ||
102 | if (state != NULL) | ||
103 | nfs_remove_bad_delegation(state->inode); | ||
104 | case -NFS4ERR_OPENMODE: | ||
105 | if (state == NULL) | ||
106 | break; | ||
107 | nfs4_schedule_stateid_recovery(mds_server, state); | ||
108 | goto wait_on_recovery; | ||
109 | case -NFS4ERR_EXPIRED: | ||
110 | if (state != NULL) | ||
111 | nfs4_schedule_stateid_recovery(mds_server, state); | ||
112 | nfs4_schedule_lease_recovery(mds_client); | ||
113 | goto wait_on_recovery; | ||
114 | /* DS session errors */ | ||
95 | case -NFS4ERR_BADSESSION: | 115 | case -NFS4ERR_BADSESSION: |
96 | case -NFS4ERR_BADSLOT: | 116 | case -NFS4ERR_BADSLOT: |
97 | case -NFS4ERR_BAD_HIGH_SLOT: | 117 | case -NFS4ERR_BAD_HIGH_SLOT: |
@@ -117,8 +137,15 @@ static int filelayout_async_handle_error(struct rpc_task *task, | |||
117 | *reset = 1; | 137 | *reset = 1; |
118 | break; | 138 | break; |
119 | } | 139 | } |
140 | out: | ||
120 | task->tk_status = 0; | 141 | task->tk_status = 0; |
121 | return -EAGAIN; | 142 | return -EAGAIN; |
143 | wait_on_recovery: | ||
144 | rpc_sleep_on(&mds_client->cl_rpcwaitq, task, NULL); | ||
145 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &mds_client->cl_state) == 0) | ||
146 | rpc_wake_up_queued_task(&mds_client->cl_rpcwaitq, task); | ||
147 | goto out; | ||
148 | |||
122 | } | 149 | } |
123 | 150 | ||
124 | /* NFS_PROTO call done callback routines */ | 151 | /* NFS_PROTO call done callback routines */ |