Udiff nfs3_srv.c
--- /webrev/webrev/usr/src/uts/common/fs/nfs/nfs3_srv.c-        Mon Aug 14 13:12:12 2006
+++ nfs3_srv.c  Sun Jul 23 00:43:22 2006
@@ -25,11 +25,23 @@
  */
 
 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
 /* All Rights Reserved */
 
-#pragma ident  "@(#)nfs3_srv.c 1.114   05/12/16 SMI"
+ /* Copyright (c) 2006, The Ohio State University. All rights reserved.
+  *
+  * Portions of this source code is developed by the team members of
+  * The Ohio State University's Network-Based Computing Laboratory (NBCL),
+  * headed by Professor Dhabaleswar K. (DK) Panda.
+  *
+  * Acknowledgements to contributions from developors:
+  *   Ranjit Noronha: noronha@cse.ohio-state.edu
+  *   Lei Chai      : chail@cse.ohio-state.edu
+  *   Weikuan Yu    : yuw@cse.ohio-state.edu
+  *
+  */
+#pragma ident  "@(#)nfs3_srv.c 1.113   05/07/25 SMI"
 
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/systm.h>
 #include <sys/cred.h>
@@ -56,10 +68,12 @@
 #include <nfs/nfs.h>
 #include <nfs/export.h>
 
 #include <sys/strsubr.h>
 
+/* #define RPC_RDMA_INLINE 1 */
+
 /*
  * These are the interface routines for the server side of the
  * Network File System.  See the NFS version 3 protocol specification
  * for a description of this interface.
  */
@@ -847,22 +861,31 @@
         */
        if (args->count > rfs3_tsize(req))
                args->count = rfs3_tsize(req);
 
        /*
+        * If we aren't returning READ data w/RDMA_WRITE, then grab
+        * a mblk.
+        */
+       if (SVC_GET_WCHUNK(req->rq_xprt, req, &iov) == FALSE) {
+
+       /*
         * mp will contain the data to be sent out in the read reply.
         * This will be freed after the reply has been sent out (by the
         * driver).
         * Let's roundup the data to a BYTES_PER_XDR_UNIT multiple, so
         * that the call to xdrmblk_putmblk() never fails.
         */
-       mp = allocb_wait(RNDUP(args->count), BPRI_MED, STR_NOSIG, &alloc_err);
+        mp = allocb_wait(RNDUP(args->count), BPRI_MED, STR_NOSIG,
+                               &alloc_err);
        ASSERT(mp != NULL);
        ASSERT(alloc_err == 0);
 
        iov.iov_base = (caddr_t)mp->b_datap->db_base;
        iov.iov_len = args->count;
+       } else
+               mp = NULL;
        uio.uio_iov = &iov;
        uio.uio_iovcnt = 1;
        uio.uio_segflg = UIO_SYSSPACE;
        uio.uio_extflg = UIO_COPY_CACHED;
        uio.uio_loffset = args->offset;
@@ -917,12 +940,15 @@
        if (!error && offset + resp->resok.count == va.va_size)
                resp->resok.eof = TRUE;
        else
                resp->resok.eof = FALSE;
        resp->resok.data.data_len = resp->resok.count;
-       resp->resok.data.data_val = (char *)mp->b_datap->db_base;
-
+#ifndef RPC_RDMA_INLINE
+        resp->resok.data.data_val = (caddr_t)iov.iov_base;
+#else
+        resp->resok.data.data_val = (caddr_t)mp->b_datap->db_base;
+#endif
        resp->resok.data.mp = mp;
 
        resp->resok.size = (uint_t)args->count;
        return;
 
@@ -2411,10 +2437,11 @@
                vn_setpath(rootdir, tvp, srcvp, args->to.name,
                                strlen(args->to.name));
                if (tmp != NULL)
                        kmem_free(tmp, strlen(tmp) + 1);
        }
+
        VN_RELE(srcvp);
        srcvp = NULL;
 
 #ifdef DEBUG
        if (rfs3_do_post_op_attr) {
@@ -3740,5 +3767,6 @@
 void
 rfs3_srvrfini(void)
 {
        /* Nothing to do */
 }
+