forked from Minki/linux
NFSv4: Refactor NFSv4 error handling
Prepare for unification of the synchronous and asynchronous error handling. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
c6fa8e6de3
commit
b3c2aa0745
@ -183,10 +183,12 @@ struct nfs4_state {
|
|||||||
|
|
||||||
|
|
||||||
struct nfs4_exception {
|
struct nfs4_exception {
|
||||||
long timeout;
|
|
||||||
int retry;
|
|
||||||
struct nfs4_state *state;
|
struct nfs4_state *state;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
long timeout;
|
||||||
|
unsigned char delay : 1,
|
||||||
|
recovering : 1,
|
||||||
|
retry : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nfs4_state_recovery_ops {
|
struct nfs4_state_recovery_ops {
|
||||||
|
@ -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);
|
exception->delay = 1;
|
||||||
if (ret != 0)
|
return 0;
|
||||||
break;
|
|
||||||
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);
|
exception->recovering = 1;
|
||||||
if (test_bit(NFS_MIG_FAILED, &server->mig_status))
|
return 0;
|
||||||
return -EIO;
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
Loading…
Reference in New Issue
Block a user