Commit 612b41f8 authored by Trond Myklebust's avatar Trond Myklebust Committed by Trond Myklebust

SUNRPC: Allow creation of RPC clients with multiple connections

Add an argument to struct rpc_create_args that allows the specification
of how many transport connections you want to set up to the server.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 21f0ffaf
...@@ -124,6 +124,7 @@ struct rpc_create_args { ...@@ -124,6 +124,7 @@ struct rpc_create_args {
u32 prognumber; /* overrides program->number */ u32 prognumber; /* overrides program->number */
u32 version; u32 version;
rpc_authflavor_t authflavor; rpc_authflavor_t authflavor;
u32 nconnect;
unsigned long flags; unsigned long flags;
char *client_name; char *client_name;
struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */ struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */
......
...@@ -528,6 +528,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) ...@@ -528,6 +528,8 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
.bc_xprt = args->bc_xprt, .bc_xprt = args->bc_xprt,
}; };
char servername[48]; char servername[48];
struct rpc_clnt *clnt;
int i;
if (args->bc_xprt) { if (args->bc_xprt) {
WARN_ON_ONCE(!(args->protocol & XPRT_TRANSPORT_BC)); WARN_ON_ONCE(!(args->protocol & XPRT_TRANSPORT_BC));
...@@ -590,7 +592,15 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) ...@@ -590,7 +592,15 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT) if (args->flags & RPC_CLNT_CREATE_NONPRIVPORT)
xprt->resvport = 0; xprt->resvport = 0;
return rpc_create_xprt(args, xprt); clnt = rpc_create_xprt(args, xprt);
if (IS_ERR(clnt) || args->nconnect <= 1)
return clnt;
for (i = 0; i < args->nconnect - 1; i++) {
if (rpc_clnt_add_xprt(clnt, &xprtargs, NULL, NULL) < 0)
break;
}
return clnt;
} }
EXPORT_SYMBOL_GPL(rpc_create); EXPORT_SYMBOL_GPL(rpc_create);
...@@ -2730,6 +2740,10 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, ...@@ -2730,6 +2740,10 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
return -ENOMEM; return -ENOMEM;
data->xps = xprt_switch_get(xps); data->xps = xprt_switch_get(xps);
data->xprt = xprt_get(xprt); data->xprt = xprt_get(xprt);
if (rpc_xprt_switch_has_addr(data->xps, (struct sockaddr *)&xprt->addr)) {
rpc_cb_add_xprt_release(data);
goto success;
}
task = rpc_call_null_helper(clnt, xprt, NULL, task = rpc_call_null_helper(clnt, xprt, NULL,
RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC|RPC_TASK_NULLCREDS, RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC|RPC_TASK_NULLCREDS,
...@@ -2737,6 +2751,7 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, ...@@ -2737,6 +2751,7 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt,
if (IS_ERR(task)) if (IS_ERR(task))
return PTR_ERR(task); return PTR_ERR(task);
rpc_put_task(task); rpc_put_task(task);
success:
return 1; return 1;
} }
EXPORT_SYMBOL_GPL(rpc_clnt_test_and_add_xprt); EXPORT_SYMBOL_GPL(rpc_clnt_test_and_add_xprt);
......
...@@ -52,8 +52,7 @@ void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps, ...@@ -52,8 +52,7 @@ void rpc_xprt_switch_add_xprt(struct rpc_xprt_switch *xps,
if (xprt == NULL) if (xprt == NULL)
return; return;
spin_lock(&xps->xps_lock); spin_lock(&xps->xps_lock);
if ((xps->xps_net == xprt->xprt_net || xps->xps_net == NULL) && if (xps->xps_net == xprt->xprt_net || xps->xps_net == NULL)
!rpc_xprt_switch_has_addr(xps, (struct sockaddr *)&xprt->addr))
xprt_switch_add_xprt_locked(xps, xprt); xprt_switch_add_xprt_locked(xps, xprt);
spin_unlock(&xps->xps_lock); spin_unlock(&xps->xps_lock);
} }
......
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