Udiff nfs3_xdr.c
--- /webrev/webrev/usr/src/uts/common/fs/nfs/nfs3_xdr.c- Mon Aug 14 13:12:13 2006
+++ nfs3_xdr.c Sun Jul 23 00:43:22 2006
@@ -25,10 +25,22 @@
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
+ /* 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_xdr.c 1.62 05/06/08 SMI"
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
@@ -49,10 +61,11 @@
#include <rpc/types.h>
#include <rpc/xdr.h>
#include <nfs/nfs.h>
#include <nfs/rnode.h>
+#include <rpc/rpc_rdma.h>
/* Checks if the fh is 32 bytes and returns TRUE if it is, otherwise FALSE */
#define XDR_CHECKFHSIZE(x, len, sz) \
(((int32_t)ntohl(len) == NFS3_CURFHSIZE) ? TRUE : \
(xdr_rewind(x, sz), FALSE))
@@ -1270,28 +1283,46 @@
*mp->b_wptr++ = '\0';
if (xdrmblk_putmblk(xdrs, mp, resokp->count) == TRUE) {
resokp->data.mp = NULL;
return (TRUE);
}
+
+ } else {
+ if(xdr_u_int(xdrs, &resokp->count) == FALSE){
+ return (FALSE);
}
/*
+ * If read data sent by wlist (RDMA_WRITE), don't do
+ * xdr_bytes() below. RDMA_WRITE transfers the data.
+ * Note: this is encode-only because the client code
+ * uses xdr_READ3vres/xdr_READ3uiores to decode results.
+ */
+ if (resokp->wlist) {
+ /*clist_free(resokp->wlist);*/
+ return (TRUE);
+ }
+ }
+
+ /*
* Fall thru for the xdr_bytes()
*
* note: the mblk will be freed in
* rfs3_read_free.
*/
}
+ /* no RDMA_WRITE transfer -- send data inline */
+
ret = xdr_bytes(xdrs, (char **)&resokp->data.data_val,
&resokp->data.data_len, nfs3tsize());
-
return (ret);
}
bool_t
xdr_READ3vres(XDR *xdrs, READ3vres *objp)
{
+count3 ocount;
/*
* DECODE or FREE only
*/
if (xdrs->x_op == XDR_FREE)
return (TRUE);
@@ -1312,17 +1343,34 @@
return (FALSE);
if (!xdr_bool(xdrs, &objp->eof))
return (FALSE);
+ /*
+ * If read data received via RDMA_WRITE, don't do xdr_bytes().
+ * RDMA_WRITE already moved the data so decode length of RDMA_WRITE.
+ */
+ if (objp->wlist) {
+ if (!xdr_u_int(xdrs, &ocount))
+ return (FALSE);
+ if(ocount != objp->count){
+ cmn_err(CE_NOTE,"NFS: READ count doesn't match RPC opaque count.\n");
+ return(FALSE);
+ }
+ objp->data.data_len = objp->wlist_len;
+ clist_free(objp->wlist);
+ return (TRUE);
+ }
+
return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
&objp->data.data_len, nfs3tsize()));
}
bool_t
xdr_READ3uiores(XDR *xdrs, READ3uiores *objp)
{
+ count3 ocount;
bool_t attributes;
mblk_t *mp;
size_t n;
int error;
int size = (int)objp->size;
@@ -1394,10 +1442,30 @@
while (mp && (mp->b_rptr >= mp->b_wptr))
mp = mp->b_cont;
} while (mp && size > 0 && uiop->uio_resid > 0);
return (TRUE);
+ }
+
+ if (objp->wlist) {
+ if (!xdr_u_int(xdrs, &ocount))
+ return (FALSE);
+ if(ocount != objp->count){
+ cmn_err(CE_NOTE,"NFS: READ count doesn't match RPC opaque count.\n");
+ return(FALSE);
+ }
+ /*
+ * XXX: Assume 1 iov, needs to be changed.
+ */
+ uiop->uio_resid -= objp->count;
+ uiop->uio_iov->iov_len -= objp->count;
+ uiop->uio_iov->iov_base += objp->count;
+ uiop->uio_loffset += objp->count;
+ objp->size = objp->wlist_len;
+ clist_free(objp->wlist);
+
+ return (TRUE);
}
/*
* This isn't an xdrmblk stream. Handle the likely
* case that it can be inlined (ex. xdrmem).