aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sunrpc/svc.h3
-rw-r--r--net/sunrpc/svc.c35
2 files changed, 20 insertions, 18 deletions
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 37003970cf2e..facb94488bb1 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -240,9 +240,10 @@ struct svc_deferred_req {
240}; 240};
241 241
242/* 242/*
243 * RPC program 243 * List of RPC programs on the same transport endpoint
244 */ 244 */
245struct svc_program { 245struct svc_program {
246 struct svc_program * pg_next; /* other programs (same xprt) */
246 u32 pg_prog; /* program number */ 247 u32 pg_prog; /* program number */
247 unsigned int pg_lovers; /* lowest version */ 248 unsigned int pg_lovers; /* lowest version */
248 unsigned int pg_hivers; /* lowest version */ 249 unsigned int pg_hivers; /* lowest version */
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index a02d424a7409..e9bd91265f70 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -35,20 +35,24 @@ svc_create(struct svc_program *prog, unsigned int bufsize)
35 if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL))) 35 if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL)))
36 return NULL; 36 return NULL;
37 memset(serv, 0, sizeof(*serv)); 37 memset(serv, 0, sizeof(*serv));
38 serv->sv_name = prog->pg_name;
38 serv->sv_program = prog; 39 serv->sv_program = prog;
39 serv->sv_nrthreads = 1; 40 serv->sv_nrthreads = 1;
40 serv->sv_stats = prog->pg_stats; 41 serv->sv_stats = prog->pg_stats;
41 serv->sv_bufsz = bufsize? bufsize : 4096; 42 serv->sv_bufsz = bufsize? bufsize : 4096;
42 prog->pg_lovers = prog->pg_nvers-1;
43 xdrsize = 0; 43 xdrsize = 0;
44 for (vers=0; vers<prog->pg_nvers ; vers++) 44 while (prog) {
45 if (prog->pg_vers[vers]) { 45 prog->pg_lovers = prog->pg_nvers-1;
46 prog->pg_hivers = vers; 46 for (vers=0; vers<prog->pg_nvers ; vers++)
47 if (prog->pg_lovers > vers) 47 if (prog->pg_vers[vers]) {
48 prog->pg_lovers = vers; 48 prog->pg_hivers = vers;
49 if (prog->pg_vers[vers]->vs_xdrsize > xdrsize) 49 if (prog->pg_lovers > vers)
50 xdrsize = prog->pg_vers[vers]->vs_xdrsize; 50 prog->pg_lovers = vers;
51 } 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 serv->sv_xdrsize = xdrsize; 56 serv->sv_xdrsize = xdrsize;
53 INIT_LIST_HEAD(&serv->sv_threads); 57 INIT_LIST_HEAD(&serv->sv_threads);
54 INIT_LIST_HEAD(&serv->sv_sockets); 58 INIT_LIST_HEAD(&serv->sv_sockets);
@@ -56,8 +60,6 @@ svc_create(struct svc_program *prog, unsigned int bufsize)
56 INIT_LIST_HEAD(&serv->sv_permsocks); 60 INIT_LIST_HEAD(&serv->sv_permsocks);
57 spin_lock_init(&serv->sv_lock); 61 spin_lock_init(&serv->sv_lock);
58 62
59 serv->sv_name = prog->pg_name;
60
61 /* Remove any stale portmap registrations */ 63 /* Remove any stale portmap registrations */
62 svc_register(serv, 0, 0); 64 svc_register(serv, 0, 0);
63 65
@@ -339,7 +341,10 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
339 goto sendit; 341 goto sendit;
340 } 342 }
341 343
342 if (prog != progp->pg_prog) 344 for (progp = serv->sv_program; progp; progp = progp->pg_next)
345 if (prog == progp->pg_prog)
346 break;
347 if (progp == NULL)
343 goto err_bad_prog; 348 goto err_bad_prog;
344 349
345 if (vers >= progp->pg_nvers || 350 if (vers >= progp->pg_nvers ||
@@ -452,11 +457,7 @@ err_bad_auth:
452 goto sendit; 457 goto sendit;
453 458
454err_bad_prog: 459err_bad_prog:
455#ifdef RPC_PARANOIA 460 dprintk("svc: unknown program %d\n", prog);
456 if (prog != 100227 || progp->pg_prog != 100003)
457 printk("svc: unknown program %d (me %d)\n", prog, progp->pg_prog);
458 /* else it is just a Solaris client seeing if ACLs are supported */
459#endif
460 serv->sv_stats->rpcbadfmt++; 461 serv->sv_stats->rpcbadfmt++;
461 svc_putu32(resv, rpc_prog_unavail); 462 svc_putu32(resv, rpc_prog_unavail);
462 goto sendit; 463 goto sendit;