Merge tag 'nfs-for-4.2-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[sfrench/cifs-2.6.git] / net / sunrpc / svc.c
index 852ae606b02a37760a5a4dc1fd1860b8a45b89a6..5a16d8d8c831c4ad2805f5958b9ccef63449af82 100644 (file)
@@ -1350,6 +1350,11 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
 {
        struct kvec     *argv = &rqstp->rq_arg.head[0];
        struct kvec     *resv = &rqstp->rq_res.head[0];
+       struct rpc_task *task;
+       int proc_error;
+       int error;
+
+       dprintk("svc: %s(%p)\n", __func__, req);
 
        /* Build the svc_rqst used by the common processing routine */
        rqstp->rq_xprt = serv->sv_bc_xprt;
@@ -1372,21 +1377,36 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
 
        /*
         * Skip the next two words because they've already been
-        * processed in the trasport
+        * processed in the transport
         */
        svc_getu32(argv);       /* XID */
        svc_getnl(argv);        /* CALLDIR */
 
-       /* Returns 1 for send, 0 for drop */
-       if (svc_process_common(rqstp, argv, resv)) {
-               memcpy(&req->rq_snd_buf, &rqstp->rq_res,
-                                               sizeof(req->rq_snd_buf));
-               return bc_send(req);
-       } else {
-               /* drop request */
+       /* Parse and execute the bc call */
+       proc_error = svc_process_common(rqstp, argv, resv);
+
+       atomic_inc(&req->rq_xprt->bc_free_slots);
+       if (!proc_error) {
+               /* Processing error: drop the request */
                xprt_free_bc_request(req);
                return 0;
        }
+
+       /* Finally, send the reply synchronously */
+       memcpy(&req->rq_snd_buf, &rqstp->rq_res, sizeof(req->rq_snd_buf));
+       task = rpc_run_bc_task(req);
+       if (IS_ERR(task)) {
+               error = PTR_ERR(task);
+               goto out;
+       }
+
+       WARN_ON_ONCE(atomic_read(&task->tk_count) != 1);
+       error = task->tk_status;
+       rpc_put_task(task);
+
+out:
+       dprintk("svc: %s(), error=%d\n", __func__, error);
+       return error;
 }
 EXPORT_SYMBOL_GPL(bc_svc_process);
 #endif /* CONFIG_SUNRPC_BACKCHANNEL */