Merge tag 'nfs-for-4.9-1' of git://git.linux-nfs.org/projects/anna/linux-nfs
[cascardo/linux.git] / net / sunrpc / xprtrdma / svc_rdma_backchannel.c
index 65a7c23..2d8545c 100644 (file)
@@ -107,26 +107,18 @@ static int svc_rdma_bc_sendto(struct svcxprt_rdma *rdma,
        int ret;
 
        vec = svc_rdma_get_req_map(rdma);
-       ret = svc_rdma_map_xdr(rdma, sndbuf, vec);
+       ret = svc_rdma_map_xdr(rdma, sndbuf, vec, false);
        if (ret)
                goto out_err;
 
-       /* Post a recv buffer to handle the reply for this request. */
-       ret = svc_rdma_post_recv(rdma, GFP_NOIO);
-       if (ret) {
-               pr_err("svcrdma: Failed to post bc receive buffer, err=%d.\n",
-                      ret);
-               pr_err("svcrdma: closing transport %p.\n", rdma);
-               set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
-               ret = -ENOTCONN;
+       ret = svc_rdma_repost_recv(rdma, GFP_NOIO);
+       if (ret)
                goto out_err;
-       }
 
        ctxt = svc_rdma_get_context(rdma);
        ctxt->pages[0] = virt_to_page(rqst->rq_buffer);
        ctxt->count = 1;
 
-       ctxt->wr_op = IB_WR_SEND;
        ctxt->direction = DMA_TO_DEVICE;
        ctxt->sge[0].lkey = rdma->sc_pd->local_dma_lkey;
        ctxt->sge[0].length = sndbuf->len;
@@ -137,10 +129,11 @@ static int svc_rdma_bc_sendto(struct svcxprt_rdma *rdma,
                ret = -EIO;
                goto out_unmap;
        }
-       atomic_inc(&rdma->sc_dma_used);
+       svc_rdma_count_mappings(rdma, ctxt);
 
        memset(&send_wr, 0, sizeof(send_wr));
-       send_wr.wr_id = (unsigned long)ctxt;
+       ctxt->cqe.done = svc_rdma_wc_send;
+       send_wr.wr_cqe = &ctxt->cqe;
        send_wr.sg_list = ctxt->sge;
        send_wr.num_sge = 1;
        send_wr.opcode = IB_WR_SEND;
@@ -166,33 +159,34 @@ out_unmap:
 /* Server-side transport endpoint wants a whole page for its send
  * buffer. The client RPC code constructs the RPC header in this
  * buffer before it invokes ->send_request.
- *
- * Returns NULL if there was a temporary allocation failure.
  */
-static void *
-xprt_rdma_bc_allocate(struct rpc_task *task, size_t size)
+static int
+xprt_rdma_bc_allocate(struct rpc_task *task)
 {
        struct rpc_rqst *rqst = task->tk_rqstp;
        struct svc_xprt *sxprt = rqst->rq_xprt->bc_xprt;
+       size_t size = rqst->rq_callsize;
        struct svcxprt_rdma *rdma;
        struct page *page;
 
        rdma = container_of(sxprt, struct svcxprt_rdma, sc_xprt);
 
-       /* Prevent an infinite loop: try to make this case work */
-       if (size > PAGE_SIZE)
+       if (size > PAGE_SIZE) {
                WARN_ONCE(1, "svcrdma: large bc buffer request (size %zu)\n",
                          size);
+               return -EINVAL;
+       }
 
        page = alloc_page(RPCRDMA_DEF_GFP);
        if (!page)
-               return NULL;
+               return -ENOMEM;
 
-       return page_address(page);
+       rqst->rq_buffer = page_address(page);
+       return 0;
 }
 
 static void
-xprt_rdma_bc_free(void *buffer)
+xprt_rdma_bc_free(struct rpc_task *task)
 {
        /* No-op: ctxt and page have already been freed. */
 }