Merge branch 'mount.part1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux] / net / sunrpc / svc.c
index d13e05f..e87ddb9 100644 (file)
@@ -1144,6 +1144,17 @@ void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...)
 static __printf(2,3) void svc_printk(struct svc_rqst *rqstp, const char *fmt, ...) {}
 #endif
 
+/*
+ * Setup response header for TCP, it has a 4B record length field.
+ */
+static void svc_tcp_prep_reply_hdr(struct svc_rqst *rqstp)
+{
+       struct kvec *resv = &rqstp->rq_res.head[0];
+
+       /* tcp needs a space for the record length... */
+       svc_putnl(resv, 0);
+}
+
 /*
  * Common routine for processing the RPC request.
  */
@@ -1172,7 +1183,8 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
        clear_bit(RQ_DROPME, &rqstp->rq_flags);
 
        /* Setup reply header */
-       rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp);
+       if (rqstp->rq_prot == IPPROTO_TCP)
+               svc_tcp_prep_reply_hdr(rqstp);
 
        svc_putu32(resv, rqstp->rq_xid);
 
@@ -1244,7 +1256,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
         * for lower versions. RPC_PROG_MISMATCH seems to be the closest
         * fit.
         */
-       if (versp->vs_need_cong_ctrl &&
+       if (versp->vs_need_cong_ctrl && rqstp->rq_xprt &&
            !test_bit(XPT_CONG_CTRL, &rqstp->rq_xprt->xpt_flags))
                goto err_bad_vers;
 
@@ -1336,7 +1348,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
        return 0;
 
  close:
-       if (test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags))
+       if (rqstp->rq_xprt && test_bit(XPT_TEMP, &rqstp->rq_xprt->xpt_flags))
                svc_close_xprt(rqstp->rq_xprt);
        dprintk("svc: svc_process close\n");
        return 0;
@@ -1459,10 +1471,10 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
        dprintk("svc: %s(%p)\n", __func__, req);
 
        /* Build the svc_rqst used by the common processing routine */
-       rqstp->rq_xprt = serv->sv_bc_xprt;
        rqstp->rq_xid = req->rq_xid;
        rqstp->rq_prot = req->rq_xprt->prot;
        rqstp->rq_server = serv;
+       rqstp->rq_bc_net = req->rq_xprt->xprt_net;
 
        rqstp->rq_addrlen = sizeof(req->rq_xprt->addr);
        memcpy(&rqstp->rq_addr, &req->rq_xprt->addr, rqstp->rq_addrlen);
@@ -1499,9 +1511,9 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
        if (!proc_error) {
                /* Processing error: drop the request */
                xprt_free_bc_request(req);
-               return 0;
+               error = -EINVAL;
+               goto out;
        }
-
        /* Finally, send the reply synchronously */
        memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf));
        task = rpc_run_bc_task(req);