Commit 2a6ee6aa authored by Trond Myklebust's avatar Trond Myklebust

NFSv4: Clean up the error handling for nfs4_reclaim_lease

Try to consolidate the error handling for nfs4_reclaim_lease into
a single function instead of doing a bit here, and a bit there...

Also ensure that NFS4CLNT_PURGE_STATE handles errors correctly.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent bbafffd2
...@@ -1574,26 +1574,57 @@ static int nfs4_check_lease(struct nfs_client *clp) ...@@ -1574,26 +1574,57 @@ static int nfs4_check_lease(struct nfs_client *clp)
return nfs4_recovery_handle_error(clp, status); return nfs4_recovery_handle_error(clp, status);
} }
/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
* on EXCHANGE_ID for v4.1
*/
static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
{
switch (status) {
case -NFS4ERR_CLID_INUSE:
case -NFS4ERR_STALE_CLIENTID:
clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
break;
case -EACCES:
if (clp->cl_machine_cred == NULL)
return -EACCES;
/* Handle case where the user hasn't set up machine creds */
nfs4_clear_machine_cred(clp);
case -NFS4ERR_DELAY:
case -ETIMEDOUT:
case -EAGAIN:
ssleep(1);
break;
case -NFS4ERR_MINOR_VERS_MISMATCH:
if (clp->cl_cons_state == NFS_CS_SESSION_INITING)
nfs_mark_client_ready(clp, -EPROTONOSUPPORT);
return -EPROTONOSUPPORT;
case -EKEYEXPIRED:
nfs4_warn_keyexpired(clp->cl_hostname);
case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
* in nfs4_exchange_id */
default:
return status;
}
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
return 0;
}
static int nfs4_reclaim_lease(struct nfs_client *clp) static int nfs4_reclaim_lease(struct nfs_client *clp)
{ {
struct rpc_cred *cred; struct rpc_cred *cred;
const struct nfs4_state_recovery_ops *ops = const struct nfs4_state_recovery_ops *ops =
clp->cl_mvops->reboot_recovery_ops; clp->cl_mvops->reboot_recovery_ops;
int status = -ENOENT; int status;
cred = ops->get_clid_cred(clp); cred = ops->get_clid_cred(clp);
if (cred != NULL) { if (cred == NULL)
return -ENOENT;
status = ops->establish_clid(clp, cred); status = ops->establish_clid(clp, cred);
put_rpccred(cred); put_rpccred(cred);
/* Handle case where the user hasn't set up machine creds */ if (status != 0)
if (status == -EACCES && cred == clp->cl_machine_cred) { return nfs4_handle_reclaim_lease_error(clp, status);
nfs4_clear_machine_cred(clp); return 0;
status = -EAGAIN;
}
if (status == -NFS4ERR_MINOR_VERS_MISMATCH)
status = -EPROTONOSUPPORT;
}
return status;
} }
#ifdef CONFIG_NFS_V4_1 #ifdef CONFIG_NFS_V4_1
...@@ -1751,32 +1782,6 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp) ...@@ -1751,32 +1782,6 @@ static int nfs4_bind_conn_to_session(struct nfs_client *clp)
} }
#endif /* CONFIG_NFS_V4_1 */ #endif /* CONFIG_NFS_V4_1 */
/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
* on EXCHANGE_ID for v4.1
*/
static void nfs4_set_lease_expired(struct nfs_client *clp, int status)
{
switch (status) {
case -NFS4ERR_CLID_INUSE:
case -NFS4ERR_STALE_CLIENTID:
clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
break;
case -NFS4ERR_DELAY:
case -ETIMEDOUT:
case -EAGAIN:
ssleep(1);
break;
case -EKEYEXPIRED:
nfs4_warn_keyexpired(clp->cl_hostname);
case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
* in nfs4_exchange_id */
default:
return;
}
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
}
static void nfs4_state_manager(struct nfs_client *clp) static void nfs4_state_manager(struct nfs_client *clp)
{ {
int status = 0; int status = 0;
...@@ -1784,7 +1789,9 @@ static void nfs4_state_manager(struct nfs_client *clp) ...@@ -1784,7 +1789,9 @@ static void nfs4_state_manager(struct nfs_client *clp)
/* Ensure exclusive access to NFSv4 state */ /* Ensure exclusive access to NFSv4 state */
do { do {
if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) { if (test_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state)) {
nfs4_reclaim_lease(clp); status = nfs4_reclaim_lease(clp);
if (status < 0)
goto out_error;
clear_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state); clear_bit(NFS4CLNT_PURGE_STATE, &clp->cl_state);
set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
} }
...@@ -1792,16 +1799,10 @@ static void nfs4_state_manager(struct nfs_client *clp) ...@@ -1792,16 +1799,10 @@ static void nfs4_state_manager(struct nfs_client *clp)
if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
/* We're going to have to re-establish a clientid */ /* We're going to have to re-establish a clientid */
status = nfs4_reclaim_lease(clp); status = nfs4_reclaim_lease(clp);
if (status) { if (status < 0)
nfs4_set_lease_expired(clp, status);
if (test_bit(NFS4CLNT_LEASE_EXPIRED,
&clp->cl_state))
continue;
if (clp->cl_cons_state ==
NFS_CS_SESSION_INITING)
nfs_mark_client_ready(clp, status);
goto out_error; goto out_error;
} if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
continue;
clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
if (test_and_clear_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, if (test_and_clear_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment