Skip to content

Commit 86ab08b

Browse files
neilbrownAnna Schumaker
authored andcommitted
SUNRPC: replace program list with program array
A service created with svc_create_pooled() can be given a linked list of programs and all of these will be served. Using a linked list makes it cumbersome when there are several programs that can be optionally selected with CONFIG settings. After this patch is applied, API consumers must use only svc_create_pooled() when creating an RPC service that listens for more than one RPC program. Signed-off-by: NeilBrown <[email protected]> Signed-off-by: Mike Snitzer <[email protected]> Acked-by: Chuck Lever <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 199f212 commit 86ab08b

File tree

7 files changed

+67
-55
lines changed

7 files changed

+67
-55
lines changed

fs/nfsd/nfsctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2246,7 +2246,7 @@ static __net_init int nfsd_net_init(struct net *net)
22462246
if (retval)
22472247
goto out_repcache_error;
22482248
memset(&nn->nfsd_svcstats, 0, sizeof(nn->nfsd_svcstats));
2249-
nn->nfsd_svcstats.program = &nfsd_program;
2249+
nn->nfsd_svcstats.program = &nfsd_programs[0];
22502250
for (i = 0; i < sizeof(nn->nfsd_versions); i++)
22512251
nn->nfsd_versions[i] = nfsd_support_version(i);
22522252
for (i = 0; i < sizeof(nn->nfsd4_minorversions); i++)

fs/nfsd/nfsd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ struct nfsd_genl_rqstp {
8585
u32 rq_opnum[NFSD_MAX_OPS_PER_COMPOUND];
8686
};
8787

88-
extern struct svc_program nfsd_program;
88+
extern struct svc_program nfsd_programs[];
8989
extern const struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
9090
extern struct mutex nfsd_mutex;
9191
extern spinlock_t nfsd_drc_lock;

fs/nfsd/nfssvc.c

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#define NFSDDBG_FACILITY NFSDDBG_SVC
3636

3737
atomic_t nfsd_th_cnt = ATOMIC_INIT(0);
38-
extern struct svc_program nfsd_program;
3938
static int nfsd(void *vrqstp);
4039
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
4140
static int nfsd_acl_rpcbind_set(struct net *,
@@ -90,20 +89,9 @@ static const struct svc_version *nfsd_acl_version[] = {
9089
# endif
9190
};
9291

93-
#define NFSD_ACL_MINVERS 2
92+
#define NFSD_ACL_MINVERS 2
9493
#define NFSD_ACL_NRVERS ARRAY_SIZE(nfsd_acl_version)
9594

96-
static struct svc_program nfsd_acl_program = {
97-
.pg_prog = NFS_ACL_PROGRAM,
98-
.pg_nvers = NFSD_ACL_NRVERS,
99-
.pg_vers = nfsd_acl_version,
100-
.pg_name = "nfsacl",
101-
.pg_class = "nfsd",
102-
.pg_authenticate = &svc_set_client,
103-
.pg_init_request = nfsd_acl_init_request,
104-
.pg_rpcbind_set = nfsd_acl_rpcbind_set,
105-
};
106-
10795
#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
10896

10997
static const struct svc_version *nfsd_version[NFSD_MAXVERS+1] = {
@@ -116,18 +104,29 @@ static const struct svc_version *nfsd_version[NFSD_MAXVERS+1] = {
116104
#endif
117105
};
118106

119-
struct svc_program nfsd_program = {
120-
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
121-
.pg_next = &nfsd_acl_program,
122-
#endif
107+
struct svc_program nfsd_programs[] = {
108+
{
123109
.pg_prog = NFS_PROGRAM, /* program number */
124110
.pg_nvers = NFSD_MAXVERS+1, /* nr of entries in nfsd_version */
125111
.pg_vers = nfsd_version, /* version table */
126112
.pg_name = "nfsd", /* program name */
127113
.pg_class = "nfsd", /* authentication class */
128-
.pg_authenticate = &svc_set_client, /* export authentication */
114+
.pg_authenticate = svc_set_client, /* export authentication */
129115
.pg_init_request = nfsd_init_request,
130116
.pg_rpcbind_set = nfsd_rpcbind_set,
117+
},
118+
#if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
119+
{
120+
.pg_prog = NFS_ACL_PROGRAM,
121+
.pg_nvers = NFSD_ACL_NRVERS,
122+
.pg_vers = nfsd_acl_version,
123+
.pg_name = "nfsacl",
124+
.pg_class = "nfsd",
125+
.pg_authenticate = svc_set_client,
126+
.pg_init_request = nfsd_acl_init_request,
127+
.pg_rpcbind_set = nfsd_acl_rpcbind_set,
128+
},
129+
#endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
131130
};
132131

133132
bool nfsd_support_version(int vers)
@@ -641,7 +640,8 @@ int nfsd_create_serv(struct net *net)
641640
if (nfsd_max_blksize == 0)
642641
nfsd_max_blksize = nfsd_get_default_max_blksize();
643642
nfsd_reset_versions(nn);
644-
serv = svc_create_pooled(&nfsd_program, &nn->nfsd_svcstats,
643+
serv = svc_create_pooled(nfsd_programs, ARRAY_SIZE(nfsd_programs),
644+
&nn->nfsd_svcstats,
645645
nfsd_max_blksize, nfsd);
646646
if (serv == NULL)
647647
return -ENOMEM;

include/linux/sunrpc/svc.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,10 @@ enum {
6767
* We currently do not support more than one RPC program per daemon.
6868
*/
6969
struct svc_serv {
70-
struct svc_program * sv_program; /* RPC program */
70+
struct svc_program * sv_programs; /* RPC programs */
7171
struct svc_stat * sv_stats; /* RPC statistics */
7272
spinlock_t sv_lock;
73+
unsigned int sv_nprogs; /* Number of sv_programs */
7374
unsigned int sv_nrthreads; /* # of server threads */
7475
unsigned int sv_maxconn; /* max connections allowed or
7576
* '0' causing max to be based
@@ -360,10 +361,9 @@ struct svc_process_info {
360361
};
361362

362363
/*
363-
* List of RPC programs on the same transport endpoint
364+
* RPC program - an array of these can use the same transport endpoint
364365
*/
365366
struct svc_program {
366-
struct svc_program * pg_next; /* other programs (same xprt) */
367367
u32 pg_prog; /* program number */
368368
unsigned int pg_lovers; /* lowest version */
369369
unsigned int pg_hivers; /* highest version */
@@ -441,6 +441,7 @@ bool svc_rqst_replace_page(struct svc_rqst *rqstp,
441441
void svc_rqst_release_pages(struct svc_rqst *rqstp);
442442
void svc_exit_thread(struct svc_rqst *);
443443
struct svc_serv * svc_create_pooled(struct svc_program *prog,
444+
unsigned int nprog,
444445
struct svc_stat *stats,
445446
unsigned int bufsize,
446447
int (*threadfn)(void *data));

net/sunrpc/svc.c

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -440,10 +440,11 @@ EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
440440

441441
static 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
*/
482483
static 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,
558561
struct 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
}
563566
EXPORT_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
*/
574578
struct 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
12081214
static 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.

net/sunrpc/svc_xprt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
268268
spin_unlock(&svc_xprt_class_lock);
269269
newxprt = xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
270270
if (IS_ERR(newxprt)) {
271-
trace_svc_xprt_create_err(serv->sv_program->pg_name,
271+
trace_svc_xprt_create_err(serv->sv_programs->pg_name,
272272
xcl->xcl_name, sap, len,
273273
newxprt);
274274
module_put(xcl->xcl_owner);

net/sunrpc/svcauth_unix.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
697697
rqstp->rq_auth_stat = rpc_autherr_badcred;
698698
ipm = ip_map_cached_get(xprt);
699699
if (ipm == NULL)
700-
ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class,
700+
ipm = __ip_map_lookup(sn->ip_map_cache,
701+
rqstp->rq_server->sv_programs->pg_class,
701702
&sin6->sin6_addr);
702703

703704
if (ipm == NULL)

0 commit comments

Comments
 (0)