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

[PATCH] RPC: Allow the sunrpc server to multiplex serveral programs on a single port

The NFS and NFSACL programs run on the same RPC transport. This patch adds
support for this by converting svc_program into a chained list of programs
(server-side).

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Signed-off-by: Olaf Kirch <okir@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

authored by

Andreas Gruenbacher and committed by
Trond Myklebust
9ba02638 a838cc49

+20 -18
+2 -1
include/linux/sunrpc/svc.h
··· 240 240 }; 241 241 242 242 /* 243 - * RPC program 243 + * List of RPC programs on the same transport endpoint 244 244 */ 245 245 struct svc_program { 246 + struct svc_program * pg_next; /* other programs (same xprt) */ 246 247 u32 pg_prog; /* program number */ 247 248 unsigned int pg_lovers; /* lowest version */ 248 249 unsigned int pg_hivers; /* lowest version */
+18 -17
net/sunrpc/svc.c
··· 35 35 if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL))) 36 36 return NULL; 37 37 memset(serv, 0, sizeof(*serv)); 38 + serv->sv_name = prog->pg_name; 38 39 serv->sv_program = prog; 39 40 serv->sv_nrthreads = 1; 40 41 serv->sv_stats = prog->pg_stats; 41 42 serv->sv_bufsz = bufsize? bufsize : 4096; 42 - prog->pg_lovers = prog->pg_nvers-1; 43 43 xdrsize = 0; 44 - for (vers=0; vers<prog->pg_nvers ; vers++) 45 - if (prog->pg_vers[vers]) { 46 - prog->pg_hivers = vers; 47 - if (prog->pg_lovers > vers) 48 - prog->pg_lovers = vers; 49 - if (prog->pg_vers[vers]->vs_xdrsize > xdrsize) 50 - xdrsize = prog->pg_vers[vers]->vs_xdrsize; 51 - } 44 + while (prog) { 45 + prog->pg_lovers = prog->pg_nvers-1; 46 + for (vers=0; vers<prog->pg_nvers ; vers++) 47 + if (prog->pg_vers[vers]) { 48 + prog->pg_hivers = vers; 49 + if (prog->pg_lovers > vers) 50 + prog->pg_lovers = vers; 51 + if (prog->pg_vers[vers]->vs_xdrsize > xdrsize) 52 + xdrsize = prog->pg_vers[vers]->vs_xdrsize; 53 + } 54 + prog = prog->pg_next; 55 + } 52 56 serv->sv_xdrsize = xdrsize; 53 57 INIT_LIST_HEAD(&serv->sv_threads); 54 58 INIT_LIST_HEAD(&serv->sv_sockets); 55 59 INIT_LIST_HEAD(&serv->sv_tempsocks); 56 60 INIT_LIST_HEAD(&serv->sv_permsocks); 57 61 spin_lock_init(&serv->sv_lock); 58 - 59 - serv->sv_name = prog->pg_name; 60 62 61 63 /* Remove any stale portmap registrations */ 62 64 svc_register(serv, 0, 0); ··· 341 339 goto sendit; 342 340 } 343 341 344 - if (prog != progp->pg_prog) 342 + for (progp = serv->sv_program; progp; progp = progp->pg_next) 343 + if (prog == progp->pg_prog) 344 + break; 345 + if (progp == NULL) 345 346 goto err_bad_prog; 346 347 347 348 if (vers >= progp->pg_nvers || ··· 457 452 goto sendit; 458 453 459 454 err_bad_prog: 460 - #ifdef RPC_PARANOIA 461 - if (prog != 100227 || progp->pg_prog != 100003) 462 - printk("svc: unknown program %d (me %d)\n", prog, progp->pg_prog); 463 - /* else it is just a Solaris client seeing if ACLs are supported */ 464 - #endif 455 + dprintk("svc: unknown program %d\n", prog); 465 456 serv->sv_stats->rpcbadfmt++; 466 457 svc_putu32(resv, rpc_prog_unavail); 467 458 goto sendit;