return total_len;
 }
 
-/*
- * Scatter inline received data back into provided iov's.
+/**
+ * rpcrdma_inline_fixup - Scatter inline received data into rqst's iovecs
+ * @rqst: controlling RPC request
+ * @srcp: points to RPC message payload in receive buffer
+ * @copy_len: remaining length of receive buffer content
+ * @pad: Write chunk pad bytes needed (zero for pure inline)
+ *
+ * The upper layer has set the maximum number of bytes it can
+ * receive in each component of rq_rcv_buf. These values are set in
+ * the head.iov_len, page_len, tail.iov_len, and buflen fields.
  */
 static void
 rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
        struct page **ppages;
        int page_base;
 
+       /* The head iovec is redirected to the RPC reply message
+        * in the receive buffer, to avoid a memcopy.
+        */
+       rqst->rq_rcv_buf.head[0].iov_base = srcp;
+
+       /* The contents of the receive buffer that follow
+        * head.iov_len bytes are copied into the page list.
+        */
        curlen = rqst->rq_rcv_buf.head[0].iov_len;
-       if (curlen > copy_len) {        /* write chunk header fixup */
+       if (curlen > copy_len)
                curlen = copy_len;
-               rqst->rq_rcv_buf.head[0].iov_len = curlen;
-       }
-
        dprintk("RPC:       %s: srcp 0x%p len %d hdrlen %d\n",
                __func__, srcp, copy_len, curlen);
-
-       /* Shift pointer for first receive segment only */
-       rqst->rq_rcv_buf.head[0].iov_base = srcp;
        srcp += curlen;
        copy_len -= curlen;
 
                                break;
                        page_base = 0;
                }
-       }
 
-       if (copy_len && rqst->rq_rcv_buf.tail[0].iov_len) {
-               curlen = copy_len;
-               if (curlen > rqst->rq_rcv_buf.tail[0].iov_len)
-                       curlen = rqst->rq_rcv_buf.tail[0].iov_len;
-               if (rqst->rq_rcv_buf.tail[0].iov_base != srcp)
-                       memmove(rqst->rq_rcv_buf.tail[0].iov_base, srcp, curlen);
-               dprintk("RPC:       %s: tail srcp 0x%p len %d curlen %d\n",
-                       __func__, srcp, copy_len, curlen);
-               rqst->rq_rcv_buf.tail[0].iov_len = curlen;
-               copy_len -= curlen; ++i;
-       } else
-               rqst->rq_rcv_buf.tail[0].iov_len = 0;
-
-       if (pad) {
-               /* implicit padding on terminal chunk */
-               unsigned char *p = rqst->rq_rcv_buf.tail[0].iov_base;
-               while (pad--)
-                       p[rqst->rq_rcv_buf.tail[0].iov_len++] = 0;
+               /* Implicit padding for the last segment in a Write
+                * chunk is inserted inline at the front of the tail
+                * iovec. The upper layer ignores the content of
+                * the pad. Simply ensure inline content in the tail
+                * that follows the Write chunk is properly aligned.
+                */
+               if (pad)
+                       srcp -= pad;
        }
 
+       /* The tail iovec is redirected to the remaining data
+        * in the receive buffer, to avoid a memcopy.
+        */
+       if (copy_len || pad)
+               rqst->rq_rcv_buf.tail[0].iov_base = srcp;
+
        if (copy_len)
                dprintk("RPC:       %s: %d bytes in"
                        " %d extra segments (%d lost)\n",