Skip to content

Commit 007e251

Browse files
Andreas GruenbacherTrond Myklebust
authored andcommitted
[PATCH] RPC: Allow multiple RPC client programs to share the same transport
Signed-off-by: Andreas Gruenbacher <[email protected]> Acked-by: Olaf Kirch <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent cdf4770 commit 007e251

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

include/linux/sunrpc/clnt.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname,
114114
struct rpc_clnt *rpc_new_client(struct rpc_xprt *xprt, char *servname,
115115
struct rpc_program *info,
116116
u32 version, rpc_authflavor_t authflavor);
117+
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
118+
struct rpc_program *, int);
117119
struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
118120
int rpc_shutdown_client(struct rpc_clnt *);
119121
int rpc_destroy_client(struct rpc_clnt *);

net/sunrpc/clnt.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ rpc_clone_client(struct rpc_clnt *clnt)
241241
rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
242242
if (new->cl_auth)
243243
atomic_inc(&new->cl_auth->au_count);
244+
new->cl_pmap = &new->cl_pmap_default;
245+
rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait");
244246
return new;
245247
out_no_clnt:
246248
printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__);
@@ -329,6 +331,44 @@ rpc_release_client(struct rpc_clnt *clnt)
329331
rpc_destroy_client(clnt);
330332
}
331333

334+
/**
335+
* rpc_bind_new_program - bind a new RPC program to an existing client
336+
* @old - old rpc_client
337+
* @program - rpc program to set
338+
* @vers - rpc program version
339+
*
340+
* Clones the rpc client and sets up a new RPC program. This is mainly
341+
* of use for enabling different RPC programs to share the same transport.
342+
* The Sun NFSv2/v3 ACL protocol can do this.
343+
*/
344+
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
345+
struct rpc_program *program,
346+
int vers)
347+
{
348+
struct rpc_clnt *clnt;
349+
struct rpc_version *version;
350+
int err;
351+
352+
BUG_ON(vers >= program->nrvers || !program->version[vers]);
353+
version = program->version[vers];
354+
clnt = rpc_clone_client(old);
355+
if (IS_ERR(clnt))
356+
goto out;
357+
clnt->cl_procinfo = version->procs;
358+
clnt->cl_maxproc = version->nrprocs;
359+
clnt->cl_protname = program->name;
360+
clnt->cl_prog = program->number;
361+
clnt->cl_vers = version->number;
362+
clnt->cl_stats = program->stats;
363+
err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
364+
if (err != 0) {
365+
rpc_shutdown_client(clnt);
366+
clnt = ERR_PTR(err);
367+
}
368+
out:
369+
return clnt;
370+
}
371+
332372
/*
333373
* Default callback for async RPC calls
334374
*/

net/sunrpc/pmap_clnt.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt)
5353
task->tk_pid, clnt->cl_server,
5454
map->pm_prog, map->pm_vers, map->pm_prot);
5555

56+
/* Autobind on cloned rpc clients is discouraged */
57+
BUG_ON(clnt->cl_parent != clnt);
58+
5659
spin_lock(&pmap_lock);
5760
if (map->pm_binding) {
5861
rpc_sleep_on(&map->pm_bindwait, task, NULL, NULL);

net/sunrpc/sunrpc_syms.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ EXPORT_SYMBOL(rpc_release_task);
4242
/* RPC client functions */
4343
EXPORT_SYMBOL(rpc_create_client);
4444
EXPORT_SYMBOL(rpc_clone_client);
45+
EXPORT_SYMBOL(rpc_bind_new_program);
4546
EXPORT_SYMBOL(rpc_destroy_client);
4647
EXPORT_SYMBOL(rpc_shutdown_client);
4748
EXPORT_SYMBOL(rpc_release_client);

0 commit comments

Comments
 (0)