struct page *pages[RPCSVC_MAXPAGES];
 };
 
+/*
+ * NFS_ requests are mapped on the client side by the chunk lists in
+ * the RPCRDMA header. During the fetching of the RPC from the client
+ * and the writing of the reply to the client, the memory in the
+ * client and the memory in the server must be mapped as contiguous
+ * vaddr/len for access by the hardware. These data strucures keep
+ * these mappings.
+ *
+ * For an RDMA_WRITE, the 'sge' maps the RPC REPLY. For RDMA_READ, the
+ * 'sge' in the svc_rdma_req_map maps the server side RPC reply and the
+ * 'ch' field maps the read-list of the RPCRDMA header to the 'sge'
+ * mapping of the reply.
+ */
+struct svc_rdma_chunk_sge {
+       int start;              /* sge no for this chunk */
+       int count;              /* sge count for this chunk */
+};
+struct svc_rdma_req_map {
+       unsigned long count;
+       union {
+               struct kvec sge[RPCSVC_MAXPAGES];
+               struct svc_rdma_chunk_sge ch[RPCSVC_MAXPAGES];
+       };
+};
+
 #define RDMACTXT_F_LAST_CTXT   2
 
 struct svcxprt_rdma {
 extern int svc_rdma_create_listen(struct svc_serv *, int, struct sockaddr *);
 extern struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *);
 extern void svc_rdma_put_context(struct svc_rdma_op_ctxt *, int);
+extern struct svc_rdma_req_map *svc_rdma_get_req_map(void);
+extern void svc_rdma_put_req_map(struct svc_rdma_req_map *);
 extern void svc_sq_reap(struct svcxprt_rdma *);
 extern void svc_rq_reap(struct svcxprt_rdma *);
 extern struct svc_xprt_class svc_rdma_class;
 
 atomic_t rdma_stat_sq_poll;
 atomic_t rdma_stat_sq_prod;
 
+/* Temporary NFS request map cache */
+struct kmem_cache *svc_rdma_map_cachep;
+
 /*
  * This function implements reading and resetting an atomic_t stat
  * variable through read/write to a proc file. Any write to the file
                svcrdma_table_header = NULL;
        }
        svc_unreg_xprt_class(&svc_rdma_class);
+       kmem_cache_destroy(svc_rdma_map_cachep);
 }
 
 int svc_rdma_init(void)
                svcrdma_table_header =
                        register_sysctl_table(svcrdma_root_table);
 
+       /* Create the temporary map cache */
+       svc_rdma_map_cachep = kmem_cache_create("svc_rdma_map_cache",
+                                               sizeof(struct svc_rdma_req_map),
+                                               0,
+                                               SLAB_HWCACHE_ALIGN,
+                                               NULL);
+       if (!svc_rdma_map_cachep) {
+               printk(KERN_INFO "Could not allocate map cache.\n");
+               goto err;
+       }
+
        /* Register RDMA with the SVC transport switch */
        svc_reg_xprt_class(&svc_rdma_class);
        return 0;
+
+ err:
+       unregister_sysctl_table(svcrdma_table_header);
+       return -ENOMEM;
 }
 MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>");
 MODULE_DESCRIPTION("SVC RDMA Transport");
 
        atomic_dec(&xprt->sc_ctxt_used);
 }
 
+/* Temporary NFS request map cache. Created in svc_rdma.c  */
+extern struct kmem_cache *svc_rdma_map_cachep;
+
+/*
+ * Temporary NFS req mappings are shared across all transport
+ * instances. These are short lived and should be bounded by the number
+ * of concurrent server threads * depth of the SQ.
+ */
+struct svc_rdma_req_map *svc_rdma_get_req_map(void)
+{
+       struct svc_rdma_req_map *map;
+       while (1) {
+               map = kmem_cache_alloc(svc_rdma_map_cachep, GFP_KERNEL);
+               if (map)
+                       break;
+               schedule_timeout_uninterruptible(msecs_to_jiffies(500));
+       }
+       map->count = 0;
+       return map;
+}
+
+void svc_rdma_put_req_map(struct svc_rdma_req_map *map)
+{
+       kmem_cache_free(svc_rdma_map_cachep, map);
+}
+
 /* ib_cq event handler */
 static void cq_event_handler(struct ib_event *event, void *context)
 {