Skip to content

Commit 8d89bd7

Browse files
androsadamsonamschuma-ntap
authored andcommitted
NFS setup async exchange_id
Testing an rpc_xprt for session trunking should not delay application progress over already established transports. Setup exchange_id to be able to be an async call to test an rpc_xprt for session trunking use. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
1 parent 5405fc4 commit 8d89bd7

File tree

1 file changed

+134
-81
lines changed

1 file changed

+134
-81
lines changed

fs/nfs/nfs4proc.c

Lines changed: 134 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -7104,6 +7104,80 @@ static int nfs4_sp4_select_mode(struct nfs_client *clp,
71047104
return 0;
71057105
}
71067106

7107+
struct nfs41_exchange_id_data {
7108+
struct nfs41_exchange_id_res res;
7109+
struct nfs41_exchange_id_args args;
7110+
int rpc_status;
7111+
};
7112+
7113+
static void nfs4_exchange_id_done(struct rpc_task *task, void *data)
7114+
{
7115+
struct nfs41_exchange_id_data *cdata =
7116+
(struct nfs41_exchange_id_data *)data;
7117+
struct nfs_client *clp = cdata->args.client;
7118+
int status = task->tk_status;
7119+
7120+
trace_nfs4_exchange_id(clp, status);
7121+
7122+
if (status == 0)
7123+
status = nfs4_check_cl_exchange_flags(cdata->res.flags);
7124+
if (status == 0)
7125+
status = nfs4_sp4_select_mode(clp, &cdata->res.state_protect);
7126+
7127+
if (status == 0) {
7128+
clp->cl_clientid = cdata->res.clientid;
7129+
clp->cl_exchange_flags = cdata->res.flags;
7130+
/* Client ID is not confirmed */
7131+
if (!(cdata->res.flags & EXCHGID4_FLAG_CONFIRMED_R)) {
7132+
clear_bit(NFS4_SESSION_ESTABLISHED,
7133+
&clp->cl_session->session_state);
7134+
clp->cl_seqid = cdata->res.seqid;
7135+
}
7136+
7137+
kfree(clp->cl_serverowner);
7138+
clp->cl_serverowner = cdata->res.server_owner;
7139+
cdata->res.server_owner = NULL;
7140+
7141+
/* use the most recent implementation id */
7142+
kfree(clp->cl_implid);
7143+
clp->cl_implid = cdata->res.impl_id;
7144+
cdata->res.impl_id = NULL;
7145+
7146+
if (clp->cl_serverscope != NULL &&
7147+
!nfs41_same_server_scope(clp->cl_serverscope,
7148+
cdata->res.server_scope)) {
7149+
dprintk("%s: server_scope mismatch detected\n",
7150+
__func__);
7151+
set_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, &clp->cl_state);
7152+
kfree(clp->cl_serverscope);
7153+
clp->cl_serverscope = NULL;
7154+
}
7155+
7156+
if (clp->cl_serverscope == NULL) {
7157+
clp->cl_serverscope = cdata->res.server_scope;
7158+
cdata->res.server_scope = NULL;
7159+
}
7160+
}
7161+
cdata->rpc_status = status;
7162+
}
7163+
7164+
static void nfs4_exchange_id_release(void *data)
7165+
{
7166+
struct nfs41_exchange_id_data *cdata =
7167+
(struct nfs41_exchange_id_data *)data;
7168+
7169+
nfs_put_client(cdata->args.client);
7170+
kfree(cdata->res.impl_id);
7171+
kfree(cdata->res.server_scope);
7172+
kfree(cdata->res.server_owner);
7173+
kfree(cdata);
7174+
}
7175+
7176+
static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
7177+
.rpc_call_done = nfs4_exchange_id_done,
7178+
.rpc_release = nfs4_exchange_id_release,
7179+
};
7180+
71077181
/*
71087182
* _nfs4_proc_exchange_id()
71097183
*
@@ -7113,66 +7187,60 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
71137187
u32 sp4_how)
71147188
{
71157189
nfs4_verifier verifier;
7116-
struct nfs41_exchange_id_args args = {
7117-
.verifier = &verifier,
7118-
.client = clp,
7119-
#ifdef CONFIG_NFS_V4_1_MIGRATION
7120-
.flags = EXCHGID4_FLAG_SUPP_MOVED_REFER |
7121-
EXCHGID4_FLAG_BIND_PRINC_STATEID |
7122-
EXCHGID4_FLAG_SUPP_MOVED_MIGR,
7123-
#else
7124-
.flags = EXCHGID4_FLAG_SUPP_MOVED_REFER |
7125-
EXCHGID4_FLAG_BIND_PRINC_STATEID,
7126-
#endif
7127-
};
7128-
struct nfs41_exchange_id_res res = {
7129-
0
7130-
};
7131-
int status;
71327190
struct rpc_message msg = {
71337191
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_EXCHANGE_ID],
7134-
.rpc_argp = &args,
7135-
.rpc_resp = &res,
71367192
.rpc_cred = cred,
71377193
};
7194+
struct rpc_task_setup task_setup_data = {
7195+
.rpc_client = clp->cl_rpcclient,
7196+
.callback_ops = &nfs4_exchange_id_call_ops,
7197+
.rpc_message = &msg,
7198+
.flags = RPC_TASK_ASYNC | RPC_TASK_TIMEOUT,
7199+
};
7200+
struct nfs41_exchange_id_data *calldata;
7201+
struct rpc_task *task;
7202+
int status = -EIO;
7203+
7204+
if (!atomic_inc_not_zero(&clp->cl_count))
7205+
goto out;
7206+
7207+
status = -ENOMEM;
7208+
calldata = kzalloc(sizeof(*calldata), GFP_NOFS);
7209+
if (!calldata)
7210+
goto out;
71387211

71397212
nfs4_init_boot_verifier(clp, &verifier);
71407213

71417214
status = nfs4_init_uniform_client_string(clp);
71427215
if (status)
7143-
goto out;
7216+
goto out_calldata;
71447217

71457218
dprintk("NFS call exchange_id auth=%s, '%s'\n",
71467219
clp->cl_rpcclient->cl_auth->au_ops->au_name,
71477220
clp->cl_owner_id);
71487221

7149-
res.server_owner = kzalloc(sizeof(struct nfs41_server_owner),
7150-
GFP_NOFS);
7151-
if (unlikely(res.server_owner == NULL)) {
7152-
status = -ENOMEM;
7153-
goto out;
7154-
}
7222+
calldata->res.server_owner = kzalloc(sizeof(struct nfs41_server_owner),
7223+
GFP_NOFS);
7224+
status = -ENOMEM;
7225+
if (unlikely(calldata->res.server_owner == NULL))
7226+
goto out_calldata;
71557227

7156-
res.server_scope = kzalloc(sizeof(struct nfs41_server_scope),
7228+
calldata->res.server_scope = kzalloc(sizeof(struct nfs41_server_scope),
71577229
GFP_NOFS);
7158-
if (unlikely(res.server_scope == NULL)) {
7159-
status = -ENOMEM;
7230+
if (unlikely(calldata->res.server_scope == NULL))
71607231
goto out_server_owner;
7161-
}
71627232

7163-
res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_NOFS);
7164-
if (unlikely(res.impl_id == NULL)) {
7165-
status = -ENOMEM;
7233+
calldata->res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_NOFS);
7234+
if (unlikely(calldata->res.impl_id == NULL))
71667235
goto out_server_scope;
7167-
}
71687236

71697237
switch (sp4_how) {
71707238
case SP4_NONE:
7171-
args.state_protect.how = SP4_NONE;
7239+
calldata->args.state_protect.how = SP4_NONE;
71727240
break;
71737241

71747242
case SP4_MACH_CRED:
7175-
args.state_protect = nfs4_sp4_mach_cred_request;
7243+
calldata->args.state_protect = nfs4_sp4_mach_cred_request;
71767244
break;
71777245

71787246
default:
@@ -7182,55 +7250,30 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
71827250
goto out_impl_id;
71837251
}
71847252

7185-
status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
7186-
trace_nfs4_exchange_id(clp, status);
7187-
if (status == 0)
7188-
status = nfs4_check_cl_exchange_flags(res.flags);
7189-
7190-
if (status == 0)
7191-
status = nfs4_sp4_select_mode(clp, &res.state_protect);
7192-
7193-
if (status == 0) {
7194-
clp->cl_clientid = res.clientid;
7195-
clp->cl_exchange_flags = res.flags;
7196-
/* Client ID is not confirmed */
7197-
if (!(res.flags & EXCHGID4_FLAG_CONFIRMED_R)) {
7198-
clear_bit(NFS4_SESSION_ESTABLISHED,
7199-
&clp->cl_session->session_state);
7200-
clp->cl_seqid = res.seqid;
7201-
}
7202-
7203-
kfree(clp->cl_serverowner);
7204-
clp->cl_serverowner = res.server_owner;
7205-
res.server_owner = NULL;
7206-
7207-
/* use the most recent implementation id */
7208-
kfree(clp->cl_implid);
7209-
clp->cl_implid = res.impl_id;
7210-
res.impl_id = NULL;
7211-
7212-
if (clp->cl_serverscope != NULL &&
7213-
!nfs41_same_server_scope(clp->cl_serverscope,
7214-
res.server_scope)) {
7215-
dprintk("%s: server_scope mismatch detected\n",
7216-
__func__);
7217-
set_bit(NFS4CLNT_SERVER_SCOPE_MISMATCH, &clp->cl_state);
7218-
kfree(clp->cl_serverscope);
7219-
clp->cl_serverscope = NULL;
7220-
}
7253+
calldata->args.verifier = &verifier;
7254+
calldata->args.client = clp;
7255+
#ifdef CONFIG_NFS_V4_1_MIGRATION
7256+
calldata->args.flags = EXCHGID4_FLAG_SUPP_MOVED_REFER |
7257+
EXCHGID4_FLAG_BIND_PRINC_STATEID |
7258+
EXCHGID4_FLAG_SUPP_MOVED_MIGR,
7259+
#else
7260+
calldata->args.flags = EXCHGID4_FLAG_SUPP_MOVED_REFER |
7261+
EXCHGID4_FLAG_BIND_PRINC_STATEID,
7262+
#endif
7263+
msg.rpc_argp = &calldata->args;
7264+
msg.rpc_resp = &calldata->res;
7265+
task_setup_data.callback_data = calldata;
72217266

7222-
if (clp->cl_serverscope == NULL) {
7223-
clp->cl_serverscope = res.server_scope;
7224-
res.server_scope = NULL;
7225-
}
7267+
task = rpc_run_task(&task_setup_data);
7268+
if (IS_ERR(task)) {
7269+
status = PTR_ERR(task);
7270+
goto out_impl_id;
72267271
}
72277272

7228-
out_impl_id:
7229-
kfree(res.impl_id);
7230-
out_server_scope:
7231-
kfree(res.server_scope);
7232-
out_server_owner:
7233-
kfree(res.server_owner);
7273+
status = rpc_wait_for_completion_task(task);
7274+
if (!status)
7275+
status = calldata->rpc_status;
7276+
rpc_put_task(task);
72347277
out:
72357278
if (clp->cl_implid != NULL)
72367279
dprintk("NFS reply exchange_id: Server Implementation ID: "
@@ -7240,6 +7283,16 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
72407283
clp->cl_implid->date.nseconds);
72417284
dprintk("NFS reply exchange_id: %d\n", status);
72427285
return status;
7286+
7287+
out_impl_id:
7288+
kfree(calldata->res.impl_id);
7289+
out_server_scope:
7290+
kfree(calldata->res.server_scope);
7291+
out_server_owner:
7292+
kfree(calldata->res.server_owner);
7293+
out_calldata:
7294+
kfree(calldata);
7295+
goto out;
72437296
}
72447297

72457298
/*

0 commit comments

Comments
 (0)