aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
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
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')
-rw-r--r--fs/nfs/delegation.c1
-rw-r--r--fs/nfs/nfs4filelayout.c29
-rw-r--r--fs/nfs/nfs4state.c2
3 files changed, 31 insertions, 1 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 87f7544f3dce..97d53574bf53 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -474,6 +474,7 @@ void nfs_remove_bad_delegation(struct inode *inode)
474 nfs_free_delegation(delegation); 474 nfs_free_delegation(delegation);
475 } 475 }
476} 476}
477EXPORT_SYMBOL_GPL(nfs_remove_bad_delegation);
477 478
478/** 479/**
479 * nfs_expire_all_delegation_types 480 * nfs_expire_all_delegation_types
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 */
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 1dad5c53c7fa..a58d02a0c27d 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1072,6 +1072,7 @@ void nfs4_schedule_lease_recovery(struct nfs_client *clp)
1072 set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); 1072 set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
1073 nfs4_schedule_state_manager(clp); 1073 nfs4_schedule_state_manager(clp);
1074} 1074}
1075EXPORT_SYMBOL_GPL(nfs4_schedule_lease_recovery);
1075 1076
1076void nfs4_schedule_path_down_recovery(struct nfs_client *clp) 1077void nfs4_schedule_path_down_recovery(struct nfs_client *clp)
1077{ 1078{
@@ -1109,6 +1110,7 @@ void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4
1109 nfs4_state_mark_reclaim_nograce(clp, state); 1110 nfs4_state_mark_reclaim_nograce(clp, state);
1110 nfs4_schedule_state_manager(clp); 1111 nfs4_schedule_state_manager(clp);
1111} 1112}
1113EXPORT_SYMBOL_GPL(nfs4_schedule_stateid_recovery);
1112 1114
1113void nfs_inode_find_state_and_recover(struct inode *inode, 1115void nfs_inode_find_state_and_recover(struct inode *inode,
1114 const nfs4_stateid *stateid) 1116 const nfs4_stateid *stateid)