Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] RPC: Allow multiple RPC client programs to share the same transport

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Acked-by: Olaf Kirch <okir@suse.de>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

authored by

Andreas Gruenbacher and committed by
Trond Myklebust
007e251f cdf47706

+46
+2
include/linux/sunrpc/clnt.h
··· 114 114 struct rpc_clnt *rpc_new_client(struct rpc_xprt *xprt, char *servname, 115 115 struct rpc_program *info, 116 116 u32 version, rpc_authflavor_t authflavor); 117 + struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *, 118 + struct rpc_program *, int); 117 119 struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); 118 120 int rpc_shutdown_client(struct rpc_clnt *); 119 121 int rpc_destroy_client(struct rpc_clnt *);
+40
net/sunrpc/clnt.c
··· 241 241 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); 242 242 if (new->cl_auth) 243 243 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"); 244 246 return new; 245 247 out_no_clnt: 246 248 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); ··· 329 327 wake_up(&destroy_wait); 330 328 if (clnt->cl_oneshot || clnt->cl_dead) 331 329 rpc_destroy_client(clnt); 330 + } 331 + 332 + /** 333 + * rpc_bind_new_program - bind a new RPC program to an existing client 334 + * @old - old rpc_client 335 + * @program - rpc program to set 336 + * @vers - rpc program version 337 + * 338 + * Clones the rpc client and sets up a new RPC program. This is mainly 339 + * of use for enabling different RPC programs to share the same transport. 340 + * The Sun NFSv2/v3 ACL protocol can do this. 341 + */ 342 + struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old, 343 + struct rpc_program *program, 344 + int vers) 345 + { 346 + struct rpc_clnt *clnt; 347 + struct rpc_version *version; 348 + int err; 349 + 350 + BUG_ON(vers >= program->nrvers || !program->version[vers]); 351 + version = program->version[vers]; 352 + clnt = rpc_clone_client(old); 353 + if (IS_ERR(clnt)) 354 + goto out; 355 + clnt->cl_procinfo = version->procs; 356 + clnt->cl_maxproc = version->nrprocs; 357 + clnt->cl_protname = program->name; 358 + clnt->cl_prog = program->number; 359 + clnt->cl_vers = version->number; 360 + clnt->cl_stats = program->stats; 361 + err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR); 362 + if (err != 0) { 363 + rpc_shutdown_client(clnt); 364 + clnt = ERR_PTR(err); 365 + } 366 + out: 367 + return clnt; 332 368 } 333 369 334 370 /*
+3
net/sunrpc/pmap_clnt.c
··· 53 53 task->tk_pid, clnt->cl_server, 54 54 map->pm_prog, map->pm_vers, map->pm_prot); 55 55 56 + /* Autobind on cloned rpc clients is discouraged */ 57 + BUG_ON(clnt->cl_parent != clnt); 58 + 56 59 spin_lock(&pmap_lock); 57 60 if (map->pm_binding) { 58 61 rpc_sleep_on(&map->pm_bindwait, task, NULL, NULL);
+1
net/sunrpc/sunrpc_syms.c
··· 42 42 /* RPC client functions */ 43 43 EXPORT_SYMBOL(rpc_create_client); 44 44 EXPORT_SYMBOL(rpc_clone_client); 45 + EXPORT_SYMBOL(rpc_bind_new_program); 45 46 EXPORT_SYMBOL(rpc_destroy_client); 46 47 EXPORT_SYMBOL(rpc_shutdown_client); 47 48 EXPORT_SYMBOL(rpc_release_client);