Commit 10e037d1 authored by Santosh kumar pradhan's avatar Santosh kumar pradhan Committed by Anna Schumaker

sunrpc: Add xprt after nfs4_test_session_trunk()

Multipathing: In case of NFSv3, rpc_clnt_test_and_add_xprt() adds
the xprt to xprt switch (i.e. xps) if rpc_call_null_helper() returns
success. But in case of NFSv4.1, it needs to do EXCHANGEID to verify
the path along with check for session trunking.

Add the xprt in nfs4_test_session_trunk() only when
nfs4_detect_session_trunking() returns success. Also release refcount
hold by rpc_clnt_setup_test_and_add_xprt().
Signed-off-by: default avatarSantosh kumar pradhan <santoshkumar.pradhan@wdc.com>
Tested-by: default avatarSuresh Jayaraman <suresh.jayaraman@wdc.com>
Reported-by: default avatarAditya Agnihotri <aditya.agnihotri@wdc.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent cb24e35b
...@@ -568,9 +568,9 @@ extern int nfs40_walk_client_list(struct nfs_client *clp, ...@@ -568,9 +568,9 @@ extern int nfs40_walk_client_list(struct nfs_client *clp,
extern int nfs41_walk_client_list(struct nfs_client *clp, extern int nfs41_walk_client_list(struct nfs_client *clp,
struct nfs_client **result, struct nfs_client **result,
const struct cred *cred); const struct cred *cred);
extern int nfs4_test_session_trunk(struct rpc_clnt *, extern void nfs4_test_session_trunk(struct rpc_clnt *clnt,
struct rpc_xprt *, struct rpc_xprt *xprt,
void *); void *data);
static inline struct inode *nfs_igrab_and_active(struct inode *inode) static inline struct inode *nfs_igrab_and_active(struct inode *inode)
{ {
......
...@@ -65,7 +65,8 @@ struct nfs4_minor_version_ops { ...@@ -65,7 +65,8 @@ struct nfs4_minor_version_ops {
nfs4_stateid *, const struct cred *); nfs4_stateid *, const struct cred *);
struct nfs_seqid * struct nfs_seqid *
(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t); (*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
int (*session_trunk)(struct rpc_clnt *, struct rpc_xprt *, void *); void (*session_trunk)(struct rpc_clnt *clnt,
struct rpc_xprt *xprt, void *data);
const struct rpc_call_ops *call_sync_ops; const struct rpc_call_ops *call_sync_ops;
const struct nfs4_state_recovery_ops *reboot_recovery_ops; const struct nfs4_state_recovery_ops *reboot_recovery_ops;
const struct nfs4_state_recovery_ops *nograce_recovery_ops; const struct nfs4_state_recovery_ops *nograce_recovery_ops;
......
...@@ -8082,7 +8082,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred) ...@@ -8082,7 +8082,7 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred)
* @xprt: the rpc_xprt to test * @xprt: the rpc_xprt to test
* @data: call data for _nfs4_proc_exchange_id. * @data: call data for _nfs4_proc_exchange_id.
*/ */
int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt, void 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;
...@@ -8099,15 +8099,17 @@ int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt, ...@@ -8099,15 +8099,17 @@ int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
/* Test connection for session trunking. Async exchange_id call */ /* Test connection for session trunking. Async exchange_id call */
task = nfs4_run_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)) if (IS_ERR(task))
return PTR_ERR(task); return;
status = task->tk_status; status = task->tk_status;
if (status == 0) if (status == 0)
status = nfs4_detect_session_trunking(adata->clp, status = nfs4_detect_session_trunking(adata->clp,
task->tk_msg.rpc_resp, xprt); task->tk_msg.rpc_resp, xprt);
if (status == 0)
rpc_clnt_xprt_switch_add_xprt(clnt, xprt);
rpc_put_task(task); rpc_put_task(task);
return status;
} }
EXPORT_SYMBOL_GPL(nfs4_test_session_trunk); EXPORT_SYMBOL_GPL(nfs4_test_session_trunk);
......
...@@ -128,8 +128,8 @@ struct rpc_create_args { ...@@ -128,8 +128,8 @@ struct rpc_create_args {
}; };
struct rpc_add_xprt_test { struct rpc_add_xprt_test {
int (*add_xprt_test)(struct rpc_clnt *, void (*add_xprt_test)(struct rpc_clnt *clnt,
struct rpc_xprt *, struct rpc_xprt *xprt,
void *calldata); void *calldata);
void *data; void *data;
}; };
......
...@@ -2661,6 +2661,9 @@ int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *clnt, ...@@ -2661,6 +2661,9 @@ int rpc_clnt_setup_test_and_add_xprt(struct rpc_clnt *clnt,
/* rpc_xprt_switch and rpc_xprt are deferrenced by add_xprt_test() */ /* rpc_xprt_switch and rpc_xprt are deferrenced by add_xprt_test() */
xtest->add_xprt_test(clnt, xprt, xtest->data); xtest->add_xprt_test(clnt, xprt, xtest->data);
xprt_put(xprt);
xprt_switch_put(xps);
/* so that rpc_clnt_add_xprt does not call rpc_xprt_switch_add_xprt */ /* so that rpc_clnt_add_xprt does not call rpc_xprt_switch_add_xprt */
return 1; return 1;
out_err: out_err:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment