@@ -440,10 +440,11 @@ EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
440440
441441static int svc_uses_rpcbind (struct svc_serv * serv )
442442{
443- struct svc_program * progp ;
444- unsigned int i ;
443+ unsigned int p , i ;
444+
445+ for (p = 0 ; p < serv -> sv_nprogs ; p ++ ) {
446+ struct svc_program * progp = & serv -> sv_programs [p ];
445447
446- for (progp = serv -> sv_program ; progp ; progp = progp -> pg_next ) {
447448 for (i = 0 ; i < progp -> pg_nvers ; i ++ ) {
448449 if (progp -> pg_vers [i ] == NULL )
449450 continue ;
@@ -480,7 +481,7 @@ __svc_init_bc(struct svc_serv *serv)
480481 * Create an RPC service
481482 */
482483static struct svc_serv *
483- __svc_create (struct svc_program * prog , struct svc_stat * stats ,
484+ __svc_create (struct svc_program * prog , int nprogs , struct svc_stat * stats ,
484485 unsigned int bufsize , int npools , int (* threadfn )(void * data ))
485486{
486487 struct svc_serv * serv ;
@@ -491,25 +492,27 @@ __svc_create(struct svc_program *prog, struct svc_stat *stats,
491492 if (!(serv = kzalloc (sizeof (* serv ), GFP_KERNEL )))
492493 return NULL ;
493494 serv -> sv_name = prog -> pg_name ;
494- serv -> sv_program = prog ;
495+ serv -> sv_programs = prog ;
496+ serv -> sv_nprogs = nprogs ;
495497 serv -> sv_stats = stats ;
496498 if (bufsize > RPCSVC_MAXPAYLOAD )
497499 bufsize = RPCSVC_MAXPAYLOAD ;
498500 serv -> sv_max_payload = bufsize ? bufsize : 4096 ;
499501 serv -> sv_max_mesg = roundup (serv -> sv_max_payload + PAGE_SIZE , PAGE_SIZE );
500502 serv -> sv_threadfn = threadfn ;
501503 xdrsize = 0 ;
502- while (prog ) {
503- prog -> pg_lovers = prog -> pg_nvers - 1 ;
504- for (vers = 0 ; vers < prog -> pg_nvers ; vers ++ )
505- if (prog -> pg_vers [vers ]) {
506- prog -> pg_hivers = vers ;
507- if (prog -> pg_lovers > vers )
508- prog -> pg_lovers = vers ;
509- if (prog -> pg_vers [vers ]-> vs_xdrsize > xdrsize )
510- xdrsize = prog -> pg_vers [vers ]-> vs_xdrsize ;
504+ for (i = 0 ; i < nprogs ; i ++ ) {
505+ struct svc_program * progp = & prog [i ];
506+
507+ progp -> pg_lovers = progp -> pg_nvers - 1 ;
508+ for (vers = 0 ; vers < progp -> pg_nvers ; vers ++ )
509+ if (progp -> pg_vers [vers ]) {
510+ progp -> pg_hivers = vers ;
511+ if (progp -> pg_lovers > vers )
512+ progp -> pg_lovers = vers ;
513+ if (progp -> pg_vers [vers ]-> vs_xdrsize > xdrsize )
514+ xdrsize = progp -> pg_vers [vers ]-> vs_xdrsize ;
511515 }
512- prog = prog -> pg_next ;
513516 }
514517 serv -> sv_xdrsize = xdrsize ;
515518 INIT_LIST_HEAD (& serv -> sv_tempsocks );
@@ -558,28 +561,30 @@ __svc_create(struct svc_program *prog, struct svc_stat *stats,
558561struct svc_serv * svc_create (struct svc_program * prog , unsigned int bufsize ,
559562 int (* threadfn )(void * data ))
560563{
561- return __svc_create (prog , NULL , bufsize , 1 , threadfn );
564+ return __svc_create (prog , 1 , NULL , bufsize , 1 , threadfn );
562565}
563566EXPORT_SYMBOL_GPL (svc_create );
564567
565568/**
566569 * svc_create_pooled - Create an RPC service with pooled threads
567- * @prog: the RPC program the new service will handle
570+ * @prog: Array of RPC programs the new service will handle
571+ * @nprogs: Number of programs in the array
568572 * @stats: the stats struct if desired
569573 * @bufsize: maximum message size for @prog
570574 * @threadfn: a function to service RPC requests for @prog
571575 *
572576 * Returns an instantiated struct svc_serv object or NULL.
573577 */
574578struct svc_serv * svc_create_pooled (struct svc_program * prog ,
579+ unsigned int nprogs ,
575580 struct svc_stat * stats ,
576581 unsigned int bufsize ,
577582 int (* threadfn )(void * data ))
578583{
579584 struct svc_serv * serv ;
580585 unsigned int npools = svc_pool_map_get ();
581586
582- serv = __svc_create (prog , stats , bufsize , npools , threadfn );
587+ serv = __svc_create (prog , nprogs , stats , bufsize , npools , threadfn );
583588 if (!serv )
584589 goto out_err ;
585590 serv -> sv_is_pooled = true;
@@ -602,16 +607,16 @@ svc_destroy(struct svc_serv **servp)
602607
603608 * servp = NULL ;
604609
605- dprintk ("svc: svc_destroy(%s)\n" , serv -> sv_program -> pg_name );
610+ dprintk ("svc: svc_destroy(%s)\n" , serv -> sv_programs -> pg_name );
606611 timer_shutdown_sync (& serv -> sv_temptimer );
607612
608613 /*
609614 * Remaining transports at this point are not expected.
610615 */
611616 WARN_ONCE (!list_empty (& serv -> sv_permsocks ),
612- "SVC: permsocks remain for %s\n" , serv -> sv_program -> pg_name );
617+ "SVC: permsocks remain for %s\n" , serv -> sv_programs -> pg_name );
613618 WARN_ONCE (!list_empty (& serv -> sv_tempsocks ),
614- "SVC: tempsocks remain for %s\n" , serv -> sv_program -> pg_name );
619+ "SVC: tempsocks remain for %s\n" , serv -> sv_programs -> pg_name );
615620
616621 cache_clean_deferred (serv );
617622
@@ -1148,15 +1153,16 @@ int svc_register(const struct svc_serv *serv, struct net *net,
11481153 const int family , const unsigned short proto ,
11491154 const unsigned short port )
11501155{
1151- struct svc_program * progp ;
1152- unsigned int i ;
1156+ unsigned int p , i ;
11531157 int error = 0 ;
11541158
11551159 WARN_ON_ONCE (proto == 0 && port == 0 );
11561160 if (proto == 0 && port == 0 )
11571161 return - EINVAL ;
11581162
1159- for (progp = serv -> sv_program ; progp ; progp = progp -> pg_next ) {
1163+ for (p = 0 ; p < serv -> sv_nprogs ; p ++ ) {
1164+ struct svc_program * progp = & serv -> sv_programs [p ];
1165+
11601166 for (i = 0 ; i < progp -> pg_nvers ; i ++ ) {
11611167
11621168 error = progp -> pg_rpcbind_set (net , progp , i ,
@@ -1208,13 +1214,14 @@ static void __svc_unregister(struct net *net, const u32 program, const u32 versi
12081214static void svc_unregister (const struct svc_serv * serv , struct net * net )
12091215{
12101216 struct sighand_struct * sighand ;
1211- struct svc_program * progp ;
12121217 unsigned long flags ;
1213- unsigned int i ;
1218+ unsigned int p , i ;
12141219
12151220 clear_thread_flag (TIF_SIGPENDING );
12161221
1217- for (progp = serv -> sv_program ; progp ; progp = progp -> pg_next ) {
1222+ for (p = 0 ; p < serv -> sv_nprogs ; p ++ ) {
1223+ struct svc_program * progp = & serv -> sv_programs [p ];
1224+
12181225 for (i = 0 ; i < progp -> pg_nvers ; i ++ ) {
12191226 if (progp -> pg_vers [i ] == NULL )
12201227 continue ;
@@ -1320,7 +1327,7 @@ svc_process_common(struct svc_rqst *rqstp)
13201327 struct svc_process_info process ;
13211328 enum svc_auth_status auth_res ;
13221329 unsigned int aoffset ;
1323- int rc ;
1330+ int pr , rc ;
13241331 __be32 * p ;
13251332
13261333 /* Will be turned off only when NFSv4 Sessions are used */
@@ -1344,9 +1351,12 @@ svc_process_common(struct svc_rqst *rqstp)
13441351 rqstp -> rq_vers = be32_to_cpup (p ++ );
13451352 rqstp -> rq_proc = be32_to_cpup (p );
13461353
1347- for (progp = serv -> sv_program ; progp ; progp = progp -> pg_next )
1354+ for (pr = 0 ; pr < serv -> sv_nprogs ; pr ++ ) {
1355+ progp = & serv -> sv_programs [pr ];
1356+
13481357 if (rqstp -> rq_prog == progp -> pg_prog )
13491358 break ;
1359+ }
13501360
13511361 /*
13521362 * Decode auth data, and add verifier to reply buffer.
0 commit comments