aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4filelayout.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2012-03-07 10:49:41 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-03-07 10:53:55 -0500
commit9cb8196839ab4ec87710526e9c43ac7f5dba69d3 (patch)
tree97ea8225d7ea1b7ba45785f25d042a18263eaf8e /fs/nfs/nfs4filelayout.c
parent4f1abd226d80ef763c50e3930b369b63dffbb312 (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.c29
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 }
140out:
120 task->tk_status = 0; 141 task->tk_status = 0;
121 return -EAGAIN; 142 return -EAGAIN;
143wait_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 */