]> Git Repo - linux.git/blobdiff - net/sunrpc/svc.c
SUNRPC: replace program list with program array
[linux.git] / net / sunrpc / svc.c
index 9aff845196ce76b7a1dcc9a44612e5d0054c860f..7e7f4e0390c7f017ade735f849776db0df9a088c 100644 (file)
@@ -440,10 +440,11 @@ EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
 
 static int svc_uses_rpcbind(struct svc_serv *serv)
 {
-       struct svc_program      *progp;
-       unsigned int            i;
+       unsigned int            p, i;
+
+       for (p = 0; p < serv->sv_nprogs; p++) {
+               struct svc_program *progp = &serv->sv_programs[p];
 
-       for (progp = serv->sv_program; progp; progp = progp->pg_next) {
                for (i = 0; i < progp->pg_nvers; i++) {
                        if (progp->pg_vers[i] == NULL)
                                continue;
@@ -480,7 +481,7 @@ __svc_init_bc(struct svc_serv *serv)
  * Create an RPC service
  */
 static struct svc_serv *
-__svc_create(struct svc_program *prog, struct svc_stat *stats,
+__svc_create(struct svc_program *prog, int nprogs, struct svc_stat *stats,
             unsigned int bufsize, int npools, int (*threadfn)(void *data))
 {
        struct svc_serv *serv;
@@ -491,7 +492,8 @@ __svc_create(struct svc_program *prog, struct svc_stat *stats,
        if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
                return NULL;
        serv->sv_name      = prog->pg_name;
-       serv->sv_program   = prog;
+       serv->sv_programs  = prog;
+       serv->sv_nprogs    = nprogs;
        serv->sv_stats     = stats;
        if (bufsize > RPCSVC_MAXPAYLOAD)
                bufsize = RPCSVC_MAXPAYLOAD;
@@ -499,17 +501,18 @@ __svc_create(struct svc_program *prog, struct svc_stat *stats,
        serv->sv_max_mesg  = roundup(serv->sv_max_payload + PAGE_SIZE, PAGE_SIZE);
        serv->sv_threadfn = threadfn;
        xdrsize = 0;
-       while (prog) {
-               prog->pg_lovers = prog->pg_nvers-1;
-               for (vers=0; vers<prog->pg_nvers ; vers++)
-                       if (prog->pg_vers[vers]) {
-                               prog->pg_hivers = vers;
-                               if (prog->pg_lovers > vers)
-                                       prog->pg_lovers = vers;
-                               if (prog->pg_vers[vers]->vs_xdrsize > xdrsize)
-                                       xdrsize = prog->pg_vers[vers]->vs_xdrsize;
+       for (i = 0; i < nprogs; i++) {
+               struct svc_program *progp = &prog[i];
+
+               progp->pg_lovers = progp->pg_nvers-1;
+               for (vers = 0; vers < progp->pg_nvers ; vers++)
+                       if (progp->pg_vers[vers]) {
+                               progp->pg_hivers = vers;
+                               if (progp->pg_lovers > vers)
+                                       progp->pg_lovers = vers;
+                               if (progp->pg_vers[vers]->vs_xdrsize > xdrsize)
+                                       xdrsize = progp->pg_vers[vers]->vs_xdrsize;
                        }
-               prog = prog->pg_next;
        }
        serv->sv_xdrsize   = xdrsize;
        INIT_LIST_HEAD(&serv->sv_tempsocks);
@@ -558,13 +561,14 @@ __svc_create(struct svc_program *prog, struct svc_stat *stats,
 struct svc_serv *svc_create(struct svc_program *prog, unsigned int bufsize,
                            int (*threadfn)(void *data))
 {
-       return __svc_create(prog, NULL, bufsize, 1, threadfn);
+       return __svc_create(prog, 1, NULL, bufsize, 1, threadfn);
 }
 EXPORT_SYMBOL_GPL(svc_create);
 
 /**
  * svc_create_pooled - Create an RPC service with pooled threads
- * @prog: the RPC program the new service will handle
+ * @prog:  Array of RPC programs the new service will handle
+ * @nprogs: Number of programs in the array
  * @stats: the stats struct if desired
  * @bufsize: maximum message size for @prog
  * @threadfn: a function to service RPC requests for @prog
@@ -572,6 +576,7 @@ EXPORT_SYMBOL_GPL(svc_create);
  * Returns an instantiated struct svc_serv object or NULL.
  */
 struct svc_serv *svc_create_pooled(struct svc_program *prog,
+                                  unsigned int nprogs,
                                   struct svc_stat *stats,
                                   unsigned int bufsize,
                                   int (*threadfn)(void *data))
@@ -579,7 +584,7 @@ struct svc_serv *svc_create_pooled(struct svc_program *prog,
        struct svc_serv *serv;
        unsigned int npools = svc_pool_map_get();
 
-       serv = __svc_create(prog, stats, bufsize, npools, threadfn);
+       serv = __svc_create(prog, nprogs, stats, bufsize, npools, threadfn);
        if (!serv)
                goto out_err;
        serv->sv_is_pooled = true;
@@ -602,16 +607,16 @@ svc_destroy(struct svc_serv **servp)
 
        *servp = NULL;
 
-       dprintk("svc: svc_destroy(%s)\n", serv->sv_program->pg_name);
+       dprintk("svc: svc_destroy(%s)\n", serv->sv_programs->pg_name);
        timer_shutdown_sync(&serv->sv_temptimer);
 
        /*
         * Remaining transports at this point are not expected.
         */
        WARN_ONCE(!list_empty(&serv->sv_permsocks),
-                 "SVC: permsocks remain for %s\n", serv->sv_program->pg_name);
+                 "SVC: permsocks remain for %s\n", serv->sv_programs->pg_name);
        WARN_ONCE(!list_empty(&serv->sv_tempsocks),
-                 "SVC: tempsocks remain for %s\n", serv->sv_program->pg_name);
+                 "SVC: tempsocks remain for %s\n", serv->sv_programs->pg_name);
 
        cache_clean_deferred(serv);
 
@@ -1148,15 +1153,16 @@ int svc_register(const struct svc_serv *serv, struct net *net,
                 const int family, const unsigned short proto,
                 const unsigned short port)
 {
-       struct svc_program      *progp;
-       unsigned int            i;
+       unsigned int            p, i;
        int                     error = 0;
 
        WARN_ON_ONCE(proto == 0 && port == 0);
        if (proto == 0 && port == 0)
                return -EINVAL;
 
-       for (progp = serv->sv_program; progp; progp = progp->pg_next) {
+       for (p = 0; p < serv->sv_nprogs; p++) {
+               struct svc_program *progp = &serv->sv_programs[p];
+
                for (i = 0; i < progp->pg_nvers; i++) {
 
                        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
 static void svc_unregister(const struct svc_serv *serv, struct net *net)
 {
        struct sighand_struct *sighand;
-       struct svc_program *progp;
        unsigned long flags;
-       unsigned int i;
+       unsigned int p, i;
 
        clear_thread_flag(TIF_SIGPENDING);
 
-       for (progp = serv->sv_program; progp; progp = progp->pg_next) {
+       for (p = 0; p < serv->sv_nprogs; p++) {
+               struct svc_program *progp = &serv->sv_programs[p];
+
                for (i = 0; i < progp->pg_nvers; i++) {
                        if (progp->pg_vers[i] == NULL)
                                continue;
@@ -1320,7 +1327,7 @@ svc_process_common(struct svc_rqst *rqstp)
        struct svc_process_info process;
        enum svc_auth_status    auth_res;
        unsigned int            aoffset;
-       int                     rc;
+       int                     pr, rc;
        __be32                  *p;
 
        /* Will be turned off only when NFSv4 Sessions are used */
@@ -1344,9 +1351,12 @@ svc_process_common(struct svc_rqst *rqstp)
        rqstp->rq_vers = be32_to_cpup(p++);
        rqstp->rq_proc = be32_to_cpup(p);
 
-       for (progp = serv->sv_program; progp; progp = progp->pg_next)
+       for (pr = 0; pr < serv->sv_nprogs; pr++) {
+               progp = &serv->sv_programs[pr];
+
                if (rqstp->rq_prog == progp->pg_prog)
                        break;
+       }
 
        /*
         * Decode auth data, and add verifier to reply buffer.
This page took 0.040193 seconds and 4 git commands to generate.