NFSv4: Refactor _nfs4_proc_exchange_id()
Tease apart the functionality in nfs4_exchange_id_done() so that it is easier to debug exchange id vs trunking issues by moving all the processing out of nfs4_exchange_id_done() and into the callers. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
@@ -7403,72 +7403,8 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp,
|
|||||||
struct nfs41_exchange_id_data {
|
struct nfs41_exchange_id_data {
|
||||||
struct nfs41_exchange_id_res res;
|
struct nfs41_exchange_id_res res;
|
||||||
struct nfs41_exchange_id_args args;
|
struct nfs41_exchange_id_args args;
|
||||||
struct rpc_xprt *xprt;
|
|
||||||
int rpc_status;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void nfs4_exchange_id_done(struct rpc_task *task, void *data)
|
|
||||||
{
|
|
||||||
struct nfs41_exchange_id_data *cdata =
|
|
||||||
(struct nfs41_exchange_id_data *)data;
|
|
||||||
struct nfs_client *clp = cdata->args.client;
|
|
||||||
int status = task->tk_status;
|
|
||||||
|
|
||||||
trace_nfs4_exchange_id(clp, status);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (status == 0) {
|
|
||||||
clp->cl_clientid = cdata->res.clientid;
|
|
||||||
clp->cl_exchange_flags = cdata->res.flags;
|
|
||||||
clp->cl_seqid = cdata->res.seqid;
|
|
||||||
/* Client ID is not confirmed */
|
|
||||||
if (!(cdata->res.flags & EXCHGID4_FLAG_CONFIRMED_R))
|
|
||||||
clear_bit(NFS4_SESSION_ESTABLISHED,
|
|
||||||
&clp->cl_session->session_state);
|
|
||||||
|
|
||||||
kfree(clp->cl_serverowner);
|
|
||||||
clp->cl_serverowner = cdata->res.server_owner;
|
|
||||||
cdata->res.server_owner = NULL;
|
|
||||||
|
|
||||||
/* use the most recent implementation id */
|
|
||||||
kfree(clp->cl_implid);
|
|
||||||
clp->cl_implid = cdata->res.impl_id;
|
|
||||||
cdata->res.impl_id = NULL;
|
|
||||||
|
|
||||||
if (clp->cl_serverscope != NULL &&
|
|
||||||
!nfs41_same_server_scope(clp->cl_serverscope,
|
|
||||||
cdata->res.server_scope)) {
|
|
||||||
dprintk("%s: server_scope mismatch detected\n",
|
|
||||||
__func__);
|
|
||||||
set_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, &clp->cl_state);
|
|
||||||
kfree(clp->cl_serverscope);
|
|
||||||
clp->cl_serverscope = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clp->cl_serverscope == NULL) {
|
|
||||||
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)
|
static void nfs4_exchange_id_release(void *data)
|
||||||
{
|
{
|
||||||
struct nfs41_exchange_id_data *cdata =
|
struct nfs41_exchange_id_data *cdata =
|
||||||
@@ -7482,7 +7418,6 @@ static void nfs4_exchange_id_release(void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
|
static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
|
||||||
.rpc_call_done = nfs4_exchange_id_done,
|
|
||||||
.rpc_release = nfs4_exchange_id_release,
|
.rpc_release = nfs4_exchange_id_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -7491,7 +7426,8 @@ static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
|
|||||||
*
|
*
|
||||||
* Wrapper for EXCHANGE_ID operation.
|
* Wrapper for EXCHANGE_ID operation.
|
||||||
*/
|
*/
|
||||||
static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
static struct rpc_task *
|
||||||
|
nfs4_run_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
||||||
u32 sp4_how, struct rpc_xprt *xprt)
|
u32 sp4_how, struct rpc_xprt *xprt)
|
||||||
{
|
{
|
||||||
struct rpc_message msg = {
|
struct rpc_message msg = {
|
||||||
@@ -7505,17 +7441,15 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
|||||||
.flags = RPC_TASK_TIMEOUT,
|
.flags = RPC_TASK_TIMEOUT,
|
||||||
};
|
};
|
||||||
struct nfs41_exchange_id_data *calldata;
|
struct nfs41_exchange_id_data *calldata;
|
||||||
struct rpc_task *task;
|
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!atomic_inc_not_zero(&clp->cl_count))
|
if (!atomic_inc_not_zero(&clp->cl_count))
|
||||||
return -EIO;
|
return ERR_PTR(-EIO);
|
||||||
|
|
||||||
|
status = -ENOMEM;
|
||||||
calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
|
calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
|
||||||
if (!calldata) {
|
if (!calldata)
|
||||||
nfs_put_client(clp);
|
goto out;
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
nfs4_init_boot_verifier(clp, &calldata->args.verifier);
|
nfs4_init_boot_verifier(clp, &calldata->args.verifier);
|
||||||
|
|
||||||
@@ -7554,7 +7488,6 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
|||||||
goto out_impl_id;
|
goto out_impl_id;
|
||||||
}
|
}
|
||||||
if (xprt) {
|
if (xprt) {
|
||||||
calldata->xprt = xprt;
|
|
||||||
task_setup_data.rpc_xprt = xprt;
|
task_setup_data.rpc_xprt = xprt;
|
||||||
task_setup_data.flags |= RPC_TASK_SOFTCONN;
|
task_setup_data.flags |= RPC_TASK_SOFTCONN;
|
||||||
memcpy(calldata->args.verifier.data, clp->cl_confirm.data,
|
memcpy(calldata->args.verifier.data, clp->cl_confirm.data,
|
||||||
@@ -7573,15 +7506,7 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
|||||||
msg.rpc_resp = &calldata->res;
|
msg.rpc_resp = &calldata->res;
|
||||||
task_setup_data.callback_data = calldata;
|
task_setup_data.callback_data = calldata;
|
||||||
|
|
||||||
task = rpc_run_task(&task_setup_data);
|
return rpc_run_task(&task_setup_data);
|
||||||
if (IS_ERR(task))
|
|
||||||
return PTR_ERR(task);
|
|
||||||
|
|
||||||
status = calldata->rpc_status;
|
|
||||||
|
|
||||||
rpc_put_task(task);
|
|
||||||
out:
|
|
||||||
return status;
|
|
||||||
|
|
||||||
out_impl_id:
|
out_impl_id:
|
||||||
kfree(calldata->res.impl_id);
|
kfree(calldata->res.impl_id);
|
||||||
@@ -7591,8 +7516,69 @@ out_server_owner:
|
|||||||
kfree(calldata->res.server_owner);
|
kfree(calldata->res.server_owner);
|
||||||
out_calldata:
|
out_calldata:
|
||||||
kfree(calldata);
|
kfree(calldata);
|
||||||
|
out:
|
||||||
nfs_put_client(clp);
|
nfs_put_client(clp);
|
||||||
goto out;
|
return ERR_PTR(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _nfs4_proc_exchange_id()
|
||||||
|
*
|
||||||
|
* Wrapper for EXCHANGE_ID operation.
|
||||||
|
*/
|
||||||
|
static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
|
||||||
|
u32 sp4_how)
|
||||||
|
{
|
||||||
|
struct rpc_task *task;
|
||||||
|
struct nfs41_exchange_id_args *argp;
|
||||||
|
struct nfs41_exchange_id_res *resp;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
task = nfs4_run_exchange_id(clp, cred, sp4_how, NULL);
|
||||||
|
if (IS_ERR(task))
|
||||||
|
return PTR_ERR(task);
|
||||||
|
|
||||||
|
argp = task->tk_msg.rpc_argp;
|
||||||
|
resp = task->tk_msg.rpc_resp;
|
||||||
|
status = task->tk_status;
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
status = nfs4_check_cl_exchange_flags(resp->flags);
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
status = nfs4_sp4_select_mode(clp, &resp->state_protect);
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
clp->cl_clientid = resp->clientid;
|
||||||
|
clp->cl_exchange_flags = resp->flags;
|
||||||
|
clp->cl_seqid = resp->seqid;
|
||||||
|
/* Client ID is not confirmed */
|
||||||
|
if (!(resp->flags & EXCHGID4_FLAG_CONFIRMED_R))
|
||||||
|
clear_bit(NFS4_SESSION_ESTABLISHED,
|
||||||
|
&clp->cl_session->session_state);
|
||||||
|
|
||||||
|
if (clp->cl_serverscope != NULL &&
|
||||||
|
!nfs41_same_server_scope(clp->cl_serverscope,
|
||||||
|
resp->server_scope)) {
|
||||||
|
dprintk("%s: server_scope mismatch detected\n",
|
||||||
|
__func__);
|
||||||
|
set_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, &clp->cl_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
swap(clp->cl_serverowner, resp->server_owner);
|
||||||
|
swap(clp->cl_serverscope, resp->server_scope);
|
||||||
|
swap(clp->cl_implid, resp->impl_id);
|
||||||
|
|
||||||
|
/* Save the EXCHANGE_ID verifier session trunk tests */
|
||||||
|
memcpy(clp->cl_confirm.data, argp->verifier.data,
|
||||||
|
sizeof(clp->cl_confirm.data));
|
||||||
|
out:
|
||||||
|
trace_nfs4_exchange_id(clp, status);
|
||||||
|
rpc_put_task(task);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7615,13 +7601,13 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
|||||||
/* try SP4_MACH_CRED if krb5i/p */
|
/* try SP4_MACH_CRED if krb5i/p */
|
||||||
if (authflavor == RPC_AUTH_GSS_KRB5I ||
|
if (authflavor == RPC_AUTH_GSS_KRB5I ||
|
||||||
authflavor == RPC_AUTH_GSS_KRB5P) {
|
authflavor == RPC_AUTH_GSS_KRB5P) {
|
||||||
status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED, NULL);
|
status = _nfs4_proc_exchange_id(clp, cred, SP4_MACH_CRED);
|
||||||
if (!status)
|
if (!status)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try SP4_NONE */
|
/* try SP4_NONE */
|
||||||
return _nfs4_proc_exchange_id(clp, cred, SP4_NONE, NULL);
|
return _nfs4_proc_exchange_id(clp, cred, SP4_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7643,6 +7629,9 @@ int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
|
|||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct nfs4_add_xprt_data *adata = (struct nfs4_add_xprt_data *)data;
|
struct nfs4_add_xprt_data *adata = (struct nfs4_add_xprt_data *)data;
|
||||||
|
struct rpc_task *task;
|
||||||
|
int status;
|
||||||
|
|
||||||
u32 sp4_how;
|
u32 sp4_how;
|
||||||
|
|
||||||
dprintk("--> %s try %s\n", __func__,
|
dprintk("--> %s try %s\n", __func__,
|
||||||
@@ -7651,7 +7640,17 @@ int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
|
|||||||
sp4_how = (adata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED);
|
sp4_how = (adata->clp->cl_sp4_flags == 0 ? SP4_NONE : SP4_MACH_CRED);
|
||||||
|
|
||||||
/* Test connection for session trunking. Async exchange_id call */
|
/* Test connection for session trunking. Async exchange_id call */
|
||||||
return _nfs4_proc_exchange_id(adata->clp, adata->cred, sp4_how, xprt);
|
task = nfs4_run_exchange_id(adata->clp, adata->cred, sp4_how, xprt);
|
||||||
|
if (IS_ERR(task))
|
||||||
|
return PTR_ERR(task);
|
||||||
|
|
||||||
|
status = task->tk_status;
|
||||||
|
if (status == 0)
|
||||||
|
status = nfs4_detect_session_trunking(adata->clp,
|
||||||
|
task->tk_msg.rpc_resp, xprt);
|
||||||
|
|
||||||
|
rpc_put_task(task);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nfs4_test_session_trunk);
|
EXPORT_SYMBOL_GPL(nfs4_test_session_trunk);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user