Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+50 −49
Original line number Original line Diff line number Diff line
@@ -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)
}
}
#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)
	/* 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)
		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,