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

Commit 519ae255 authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

NFS: Add migration recovery callouts in nfs4proc.c



When a server returns NFS4ERR_MOVED, trigger the new migration
recovery logic in the state manager.

Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 9f51a78e
Loading
Loading
Loading
Loading
+20 −2
Original line number Original line Diff line number Diff line
@@ -384,6 +384,11 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
		case -NFS4ERR_STALE_CLIENTID:
		case -NFS4ERR_STALE_CLIENTID:
			nfs4_schedule_lease_recovery(clp);
			nfs4_schedule_lease_recovery(clp);
			goto wait_on_recovery;
			goto wait_on_recovery;
		case -NFS4ERR_MOVED:
			ret = nfs4_schedule_migration_recovery(server);
			if (ret < 0)
				break;
			goto wait_on_recovery;
#if defined(CONFIG_NFS_V4_1)
#if defined(CONFIG_NFS_V4_1)
		case -NFS4ERR_BADSESSION:
		case -NFS4ERR_BADSESSION:
		case -NFS4ERR_BADSLOT:
		case -NFS4ERR_BADSLOT:
@@ -431,6 +436,8 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
	return nfs4_map_errors(ret);
	return nfs4_map_errors(ret);
wait_on_recovery:
wait_on_recovery:
	ret = nfs4_wait_clnt_recover(clp);
	ret = nfs4_wait_clnt_recover(clp);
	if (test_bit(NFS_MIG_FAILED, &server->mig_status))
		return -EIO;
	if (ret == 0)
	if (ret == 0)
		exception->retry = 1;
		exception->retry = 1;
	return ret;
	return ret;
@@ -2974,11 +2981,16 @@ static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir,
	status = nfs4_proc_fs_locations(client, dir, name, locations, page);
	status = nfs4_proc_fs_locations(client, dir, name, locations, page);
	if (status != 0)
	if (status != 0)
		goto out;
		goto out;
	/* Make sure server returned a different fsid for the referral */

	/*
	 * If the fsid didn't change, this is a migration event, not a
	 * referral.  Cause us to drop into the exception handler, which
	 * will kick off migration recovery.
	 */
	if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) {
	if (nfs_fsid_equal(&NFS_SERVER(dir)->fsid, &locations->fattr.fsid)) {
		dprintk("%s: server did not return a different fsid for"
		dprintk("%s: server did not return a different fsid for"
			" a referral at %s\n", __func__, name->name);
			" a referral at %s\n", __func__, name->name);
		status = -EIO;
		status = -NFS4ERR_MOVED;
		goto out;
		goto out;
	}
	}
	/* Fixup attributes for the nfs_lookup() call to nfs_fhget() */
	/* Fixup attributes for the nfs_lookup() call to nfs_fhget() */
@@ -4739,6 +4751,10 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
		case -NFS4ERR_STALE_CLIENTID:
		case -NFS4ERR_STALE_CLIENTID:
			nfs4_schedule_lease_recovery(clp);
			nfs4_schedule_lease_recovery(clp);
			goto wait_on_recovery;
			goto wait_on_recovery;
		case -NFS4ERR_MOVED:
			if (nfs4_schedule_migration_recovery(server) < 0)
				goto recovery_failed;
			goto wait_on_recovery;
#if defined(CONFIG_NFS_V4_1)
#if defined(CONFIG_NFS_V4_1)
		case -NFS4ERR_BADSESSION:
		case -NFS4ERR_BADSESSION:
		case -NFS4ERR_BADSLOT:
		case -NFS4ERR_BADSLOT:
@@ -4769,6 +4785,8 @@ wait_on_recovery:
	rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
	rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL);
	if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
	if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0)
		rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
		rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task);
	if (test_bit(NFS_MIG_FAILED, &server->mig_status))
		goto recovery_failed;
restart_call:
restart_call:
	task->tk_status = 0;
	task->tk_status = 0;
	return -EAGAIN;
	return -EAGAIN;