|
@@ -7107,6 +7107,7 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp,
|
|
|
struct nfs41_exchange_id_data {
|
|
|
struct nfs41_exchange_id_res res;
|
|
|
struct nfs41_exchange_id_args args;
|
|
|
+ struct rpc_xprt *xprt;
|
|
|
int rpc_status;
|
|
|
};
|
|
|
|
|
@@ -7121,6 +7122,13 @@ static void nfs4_exchange_id_done(struct rpc_task *task, void *data)
|
|
|
|
|
|
if (status == 0)
|
|
|
status = nfs4_check_cl_exchange_flags(cdata->res.flags);
|
|
|
+
|
|
|
+ if (cdata->xprt && status == 0) {
|
|
|
+ status = nfs4_detect_session_trunking(clp, &cdata->res,
|
|
|
+ cdata->xprt);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
if (status == 0)
|
|
|
status = nfs4_sp4_select_mode(clp, &cdata->res.state_protect);
|
|
|
|
|
@@ -7157,8 +7165,13 @@ static void nfs4_exchange_id_done(struct rpc_task *task, void *data)
|
|
|
clp->cl_serverscope = cdata->res.server_scope;
|
|
|
cdata->res.server_scope = NULL;
|
|
|
}
|
|
|
+ /* Save the EXCHANGE_ID verifier session trunk tests */
|
|
|
+ memcpy(clp->cl_confirm.data, cdata->args.verifier->data,
|
|
|
+ sizeof(clp->cl_confirm.data));
|
|
|
}
|
|
|
+out:
|
|
|
cdata->rpc_status = status;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
static void nfs4_exchange_id_release(void *data)
|
|
@@ -7167,6 +7180,10 @@ static void nfs4_exchange_id_release(void *data)
|
|
|
(struct nfs41_exchange_id_data *)data;
|
|
|
|
|
|
nfs_put_client(cdata->args.client);
|
|
|
+ if (cdata->xprt) {
|
|
|
+ xprt_put(cdata->xprt);
|
|
|
+ rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient);
|
|
|
+ }
|
|
|
kfree(cdata->res.impl_id);
|
|
|
kfree(cdata->res.server_scope);
|
|
|
kfree(cdata->res.server_owner);
|
|
@@ -7184,7 +7201,7 @@ static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
|
|
|
* Wrapper for EXCHANGE_ID operation.
|
|
|
*/
|
|
|
static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
|
|
- u32 sp4_how)
|
|
|
+ u32 sp4_how, struct rpc_xprt *xprt)
|
|
|
{
|
|
|
nfs4_verifier verifier;
|
|
|
struct rpc_message msg = {
|
|
@@ -7209,7 +7226,8 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
|
|
if (!calldata)
|
|
|
goto out;
|
|
|
|
|
|
- nfs4_init_boot_verifier(clp, &verifier);
|
|
|
+ if (!xprt)
|
|
|
+ nfs4_init_boot_verifier(clp, &verifier);
|
|
|
|
|
|
status = nfs4_init_uniform_client_string(clp);
|
|
|
if (status)
|
|
@@ -7249,8 +7267,15 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
|
|
status = -EINVAL;
|
|
|
goto out_impl_id;
|
|
|
}
|
|
|
-
|
|
|
- calldata->args.verifier = &verifier;
|
|
|
+ if (xprt) {
|
|
|
+ calldata->xprt = xprt;
|
|
|
+ task_setup_data.rpc_xprt = xprt;
|
|
|
+ task_setup_data.flags =
|
|
|
+ RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC;
|
|
|
+ calldata->args.verifier = &clp->cl_confirm;
|
|
|
+ } else {
|
|
|
+ calldata->args.verifier = &verifier;
|
|
|
+ }
|
|
|
calldata->args.client = clp;
|
|
|
#ifdef CONFIG_NFS_V4_1_MIGRATION
|
|
|
calldata->args.flags = EXCHGID4_FLAG_SUPP_MOVED_REFER |
|
|
@@ -7270,9 +7295,13 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
|
|
goto out_impl_id;
|
|
|
}
|
|
|
|
|
|
- status = rpc_wait_for_completion_task(task);
|
|
|
- if (!status)
|
|
|
+ if (!xprt) {
|
|
|
+ status = rpc_wait_for_completion_task(task);
|
|
|
+ if (!status)
|
|
|
+ status = calldata->rpc_status;
|
|
|
+ } else /* session trunking test */
|
|
|
status = calldata->rpc_status;
|
|
|
+
|
|
|
rpc_put_task(task);
|
|
|
out:
|
|
|
if (clp->cl_implid != NULL)
|
|
@@ -7315,13 +7344,13 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
|
|
/* try SP4_MACH_CRED if krb5i/p */
|
|
|
if (authflavor == RPC_AUTH_GSS_KRB5I ||
|
|
|
authflavor == RPC_AUTH_GSS_KRB5P) {
|
|
|
- status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED);
|
|
|
+ status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED, NULL);
|
|
|
if (!status)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/* try SP4_NONE */
|
|
|
- return _nfs4_proc_exchange_id(clp, cred, SP4_NONE);
|
|
|
+ return _nfs4_proc_exchange_id(clp, cred, SP4_NONE, NULL);
|
|
|
}
|
|
|
|
|
|
static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
|