|
@@ -344,13 +344,16 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
|
|
/* This is the error handling routine for processes that are allowed
|
|
/* This is the error handling routine for processes that are allowed
|
|
* to sleep.
|
|
* to sleep.
|
|
*/
|
|
*/
|
|
-int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
|
|
|
|
|
|
+static int nfs4_do_handle_exception(struct nfs_server *server,
|
|
|
|
+ int errorcode, struct nfs4_exception *exception)
|
|
{
|
|
{
|
|
struct nfs_client *clp = server->nfs_client;
|
|
struct nfs_client *clp = server->nfs_client;
|
|
struct nfs4_state *state = exception->state;
|
|
struct nfs4_state *state = exception->state;
|
|
struct inode *inode = exception->inode;
|
|
struct inode *inode = exception->inode;
|
|
int ret = errorcode;
|
|
int ret = errorcode;
|
|
|
|
|
|
|
|
+ exception->delay = 0;
|
|
|
|
+ exception->recovering = 0;
|
|
exception->retry = 0;
|
|
exception->retry = 0;
|
|
switch(errorcode) {
|
|
switch(errorcode) {
|
|
case 0:
|
|
case 0:
|
|
@@ -411,9 +414,9 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_
|
|
}
|
|
}
|
|
case -NFS4ERR_GRACE:
|
|
case -NFS4ERR_GRACE:
|
|
case -NFS4ERR_DELAY:
|
|
case -NFS4ERR_DELAY:
|
|
- ret = nfs4_delay(server->client, &exception->timeout);
|
|
|
|
- if (ret != 0)
|
|
|
|
- break;
|
|
|
|
|
|
+ exception->delay = 1;
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
case -NFS4ERR_RETRY_UNCACHED_REP:
|
|
case -NFS4ERR_RETRY_UNCACHED_REP:
|
|
case -NFS4ERR_OLD_STATEID:
|
|
case -NFS4ERR_OLD_STATEID:
|
|
exception->retry = 1;
|
|
exception->retry = 1;
|
|
@@ -434,9 +437,31 @@ int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_
|
|
/* We failed to handle the error */
|
|
/* We failed to handle the error */
|
|
return nfs4_map_errors(ret);
|
|
return nfs4_map_errors(ret);
|
|
wait_on_recovery:
|
|
wait_on_recovery:
|
|
- ret = nfs4_wait_clnt_recover(clp);
|
|
|
|
- if (test_bit(NFS_MIG_FAILED, &server->mig_status))
|
|
|
|
- return -EIO;
|
|
|
|
|
|
+ exception->recovering = 1;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* This is the error handling routine for processes that are allowed
|
|
|
|
+ * to sleep.
|
|
|
|
+ */
|
|
|
|
+int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
|
|
|
|
+{
|
|
|
|
+ struct nfs_client *clp = server->nfs_client;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ ret = nfs4_do_handle_exception(server, errorcode, exception);
|
|
|
|
+ if (exception->delay) {
|
|
|
|
+ ret = nfs4_delay(server->client, &exception->timeout);
|
|
|
|
+ goto out_retry;
|
|
|
|
+ }
|
|
|
|
+ if (exception->recovering) {
|
|
|
|
+ ret = nfs4_wait_clnt_recover(clp);
|
|
|
|
+ if (test_bit(NFS_MIG_FAILED, &server->mig_status))
|
|
|
|
+ return -EIO;
|
|
|
|
+ goto out_retry;
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+out_retry:
|
|
if (ret == 0)
|
|
if (ret == 0)
|
|
exception->retry = 1;
|
|
exception->retry = 1;
|
|
return ret;
|
|
return ret;
|