return dma_addr;
 }
 
-/* Returns the address of the first read chunk or <nul> if no read chunk
- * is present
+/* Parse the RPC Call's transport header.
  */
-struct rpcrdma_read_chunk *
-svc_rdma_get_read_chunk(struct rpcrdma_msg *rmsgp)
+static void svc_rdma_get_write_arrays(struct rpcrdma_msg *rmsgp,
+                                     struct rpcrdma_write_array **write,
+                                     struct rpcrdma_write_array **reply)
 {
-       struct rpcrdma_read_chunk *ch =
-               (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
+       __be32 *p;
 
-       if (ch->rc_discrim == xdr_zero)
-               return NULL;
-       return ch;
-}
-
-/* Returns the address of the first read write array element or <nul>
- * if no write array list is present
- */
-static struct rpcrdma_write_array *
-svc_rdma_get_write_array(struct rpcrdma_msg *rmsgp)
-{
-       if (rmsgp->rm_body.rm_chunks[0] != xdr_zero ||
-           rmsgp->rm_body.rm_chunks[1] == xdr_zero)
-               return NULL;
-       return (struct rpcrdma_write_array *)&rmsgp->rm_body.rm_chunks[1];
-}
+       p = (__be32 *)&rmsgp->rm_body.rm_chunks[0];
 
-/* Returns the address of the first reply array element or <nul> if no
- * reply array is present
- */
-static struct rpcrdma_write_array *
-svc_rdma_get_reply_array(struct rpcrdma_msg *rmsgp,
-                        struct rpcrdma_write_array *wr_ary)
-{
-       struct rpcrdma_read_chunk *rch;
-       struct rpcrdma_write_array *rp_ary;
+       /* Read list */
+       while (*p++ != xdr_zero)
+               p += 5;
 
-       /* XXX: Need to fix when reply chunk may occur with read list
-        *      and/or write list.
-        */
-       if (rmsgp->rm_body.rm_chunks[0] != xdr_zero ||
-           rmsgp->rm_body.rm_chunks[1] != xdr_zero)
-               return NULL;
-
-       rch = svc_rdma_get_read_chunk(rmsgp);
-       if (rch) {
-               while (rch->rc_discrim != xdr_zero)
-                       rch++;
-
-               /* The reply chunk follows an empty write array located
-                * at 'rc_position' here. The reply array is at rc_target.
-                */
-               rp_ary = (struct rpcrdma_write_array *)&rch->rc_target;
-               goto found_it;
-       }
-
-       if (wr_ary) {
-               int chunk = be32_to_cpu(wr_ary->wc_nchunks);
-
-               rp_ary = (struct rpcrdma_write_array *)
-                        &wr_ary->wc_array[chunk].wc_target.rs_length;
-               goto found_it;
+       /* Write list */
+       if (*p != xdr_zero) {
+               *write = (struct rpcrdma_write_array *)p;
+               while (*p++ != xdr_zero)
+                       p += 1 + be32_to_cpu(*p) * 4;
+       } else {
+               *write = NULL;
+               p++;
        }
 
-       /* No read list, no write list */
-       rp_ary = (struct rpcrdma_write_array *)&rmsgp->rm_body.rm_chunks[2];
-
- found_it:
-       if (rp_ary->wc_discrim == xdr_zero)
-               return NULL;
-       return rp_ary;
+       /* Reply chunk */
+       if (*p != xdr_zero)
+               *reply = (struct rpcrdma_write_array *)p;
+       else
+               *reply = NULL;
 }
 
 /* RPC-over-RDMA Version One private extension: Remote Invalidation.
 
        inv_rkey = 0;
 
-       rd_ary = svc_rdma_get_read_chunk(rdma_argp);
-       if (rd_ary) {
+       rd_ary = (struct rpcrdma_read_chunk *)&rdma_argp->rm_body.rm_chunks[0];
+       if (rd_ary->rc_discrim != xdr_zero) {
                inv_rkey = be32_to_cpu(rd_ary->rc_target.rs_handle);
                goto out;
        }
         * places this at the start of page 0.
         */
        rdma_argp = page_address(rqstp->rq_pages[0]);
-       wr_ary = svc_rdma_get_write_array(rdma_argp);
-       rp_ary = svc_rdma_get_reply_array(rdma_argp, wr_ary);
+       svc_rdma_get_write_arrays(rdma_argp, &wr_ary, &rp_ary);
 
        inv_rkey = 0;
        if (rdma->sc_snd_w_inv)