[PATCH] knfsd: Drop 'serv' option to svc_recv and svc_process
[deliverable/linux.git] / net / sunrpc / svc.c
index e4296c8b861eba85fead5bf1d839aa212e59ac7c..eee45a58f3ee08ab0fc3b6a6fc749f620675d69b 100644 (file)
  * Create an RPC service
  */
 struct svc_serv *
-svc_create(struct svc_program *prog, unsigned int bufsize)
+svc_create(struct svc_program *prog, unsigned int bufsize,
+          void (*shutdown)(struct svc_serv *serv))
 {
        struct svc_serv *serv;
        int vers;
        unsigned int xdrsize;
 
-       if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL)))
+       if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
                return NULL;
-       memset(serv, 0, sizeof(*serv));
        serv->sv_name      = prog->pg_name;
        serv->sv_program   = prog;
        serv->sv_nrthreads = 1;
        serv->sv_stats     = prog->pg_stats;
        serv->sv_bufsz     = bufsize? bufsize : 4096;
+       serv->sv_shutdown  = shutdown;
        xdrsize = 0;
        while (prog) {
                prog->pg_lovers = prog->pg_nvers-1;
@@ -92,6 +93,9 @@ svc_destroy(struct svc_serv *serv)
                                  sk_list);
                svc_delete_socket(svsk);
        }
+       if (serv->sv_shutdown)
+               serv->sv_shutdown(serv);
+
        while (!list_empty(&serv->sv_permsocks)) {
                svsk = list_entry(serv->sv_permsocks.next,
                                  struct svc_sock,
@@ -122,8 +126,7 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size)
        rqstp->rq_argused = 0;
        rqstp->rq_resused = 0;
        arghi = 0;
-       if (pages > RPCSVC_MAXPAGES)
-               BUG();
+       BUG_ON(pages > RPCSVC_MAXPAGES);
        while (pages) {
                struct page *p = alloc_page(GFP_KERNEL);
                if (!p)
@@ -160,15 +163,14 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv)
        struct svc_rqst *rqstp;
        int             error = -ENOMEM;
 
-       rqstp = kmalloc(sizeof(*rqstp), GFP_KERNEL);
+       rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL);
        if (!rqstp)
                goto out;
 
-       memset(rqstp, 0, sizeof(*rqstp));
        init_waitqueue_head(&rqstp->rq_wait);
 
-       if (!(rqstp->rq_argp = (u32 *) kmalloc(serv->sv_xdrsize, GFP_KERNEL))
-        || !(rqstp->rq_resp = (u32 *) kmalloc(serv->sv_xdrsize, GFP_KERNEL))
+       if (!(rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL))
+        || !(rqstp->rq_resp = kmalloc(serv->sv_xdrsize, GFP_KERNEL))
         || !svc_init_buffer(rqstp, serv->sv_bufsz))
                goto out_thread;
 
@@ -251,19 +253,20 @@ svc_register(struct svc_serv *serv, int proto, unsigned short port)
  * Process the RPC request.
  */
 int
-svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
+svc_process(struct svc_rqst *rqstp)
 {
        struct svc_program      *progp;
        struct svc_version      *versp = NULL;  /* compiler food */
        struct svc_procedure    *procp = NULL;
        struct kvec *           argv = &rqstp->rq_arg.head[0];
        struct kvec *           resv = &rqstp->rq_res.head[0];
+       struct svc_serv         *serv = rqstp->rq_server;
        kxdrproc_t              xdr;
-       u32                     *statp;
-       u32                     dir, prog, vers, proc,
-                               auth_stat, rpc_stat;
+       __be32                  *statp;
+       u32                     dir, prog, vers, proc;
+       __be32                  auth_stat, rpc_stat;
        int                     auth_res;
-       u32                     *accept_statp;
+       __be32                  *accept_statp;
 
        rpc_stat = rpc_success;
 
@@ -281,19 +284,22 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
        rqstp->rq_res.page_base = 0;
        rqstp->rq_res.page_len = 0;
        rqstp->rq_res.buflen = PAGE_SIZE;
+       rqstp->rq_res.tail[0].iov_base = NULL;
        rqstp->rq_res.tail[0].iov_len = 0;
+       /* Will be turned off only in gss privacy case: */
+       rqstp->rq_sendfile_ok = 1;
        /* tcp needs a space for the record length... */
        if (rqstp->rq_prot == IPPROTO_TCP)
-               svc_putu32(resv, 0);
+               svc_putnl(resv, 0);
 
        rqstp->rq_xid = svc_getu32(argv);
        svc_putu32(resv, rqstp->rq_xid);
 
-       dir  = ntohl(svc_getu32(argv));
-       vers = ntohl(svc_getu32(argv));
+       dir  = svc_getnl(argv);
+       vers = svc_getnl(argv);
 
        /* First words of reply: */
-       svc_putu32(resv, xdr_one);              /* REPLY */
+       svc_putnl(resv, 1);             /* REPLY */
 
        if (dir != 0)           /* direction != CALL */
                goto err_bad_dir;
@@ -303,11 +309,11 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
        /* Save position in case we later decide to reject: */
        accept_statp = resv->iov_base + resv->iov_len;
 
-       svc_putu32(resv, xdr_zero);             /* ACCEPT */
+       svc_putnl(resv, 0);             /* ACCEPT */
 
-       rqstp->rq_prog = prog = ntohl(svc_getu32(argv));        /* program number */
-       rqstp->rq_vers = vers = ntohl(svc_getu32(argv));        /* version number */
-       rqstp->rq_proc = proc = ntohl(svc_getu32(argv));        /* procedure number */
+       rqstp->rq_prog = prog = svc_getnl(argv);        /* program number */
+       rqstp->rq_vers = vers = svc_getnl(argv);        /* version number */
+       rqstp->rq_proc = proc = svc_getnl(argv);        /* procedure number */
 
        progp = serv->sv_program;
 
@@ -361,7 +367,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
 
        /* Build the reply header. */
        statp = resv->iov_base +resv->iov_len;
-       svc_putu32(resv, rpc_success);          /* RPC_SUCCESS */
+       svc_putnl(resv, RPC_SUCCESS);
 
        /* Bump per-procedure stats counter */
        procp->pc_count++;
@@ -439,10 +445,10 @@ err_bad_dir:
 
 err_bad_rpc:
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, xdr_one);      /* REJECT */
-       svc_putu32(resv, xdr_zero);     /* RPC_MISMATCH */
-       svc_putu32(resv, xdr_two);      /* Only RPCv2 supported */
-       svc_putu32(resv, xdr_two);
+       svc_putnl(resv, 1);     /* REJECT */
+       svc_putnl(resv, 0);     /* RPC_MISMATCH */
+       svc_putnl(resv, 2);     /* Only RPCv2 supported */
+       svc_putnl(resv, 2);
        goto sendit;
 
 err_bad_auth:
@@ -450,15 +456,15 @@ err_bad_auth:
        serv->sv_stats->rpcbadauth++;
        /* Restore write pointer to location of accept status: */
        xdr_ressize_check(rqstp, accept_statp);
-       svc_putu32(resv, xdr_one);      /* REJECT */
-       svc_putu32(resv, xdr_one);      /* AUTH_ERROR */
-       svc_putu32(resv, auth_stat);    /* status */
+       svc_putnl(resv, 1);     /* REJECT */
+       svc_putnl(resv, 1);     /* AUTH_ERROR */
+       svc_putnl(resv, ntohl(auth_stat));      /* status */
        goto sendit;
 
 err_bad_prog:
        dprintk("svc: unknown program %d\n", prog);
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, rpc_prog_unavail);
+       svc_putnl(resv, RPC_PROG_UNAVAIL);
        goto sendit;
 
 err_bad_vers:
@@ -466,9 +472,9 @@ err_bad_vers:
        printk("svc: unknown version (%d)\n", vers);
 #endif
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, rpc_prog_mismatch);
-       svc_putu32(resv, htonl(progp->pg_lovers));
-       svc_putu32(resv, htonl(progp->pg_hivers));
+       svc_putnl(resv, RPC_PROG_MISMATCH);
+       svc_putnl(resv, progp->pg_lovers);
+       svc_putnl(resv, progp->pg_hivers);
        goto sendit;
 
 err_bad_proc:
@@ -476,7 +482,7 @@ err_bad_proc:
        printk("svc: unknown procedure (%d)\n", proc);
 #endif
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, rpc_proc_unavail);
+       svc_putnl(resv, RPC_PROC_UNAVAIL);
        goto sendit;
 
 err_garbage:
@@ -486,6 +492,6 @@ err_garbage:
        rpc_stat = rpc_garbage_args;
 err_bad:
        serv->sv_stats->rpcbadfmt++;
-       svc_putu32(resv, rpc_stat);
+       svc_putnl(resv, ntohl(rpc_stat));
        goto sendit;
 }
This page took 0.026856 seconds and 5 git commands to generate.