xref: /titanic_51/usr/src/uts/common/fs/nfs/nfs3_xdr.c (revision e36d7b1181d9f0bc91b073751e5602af8e92c0ab)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
527242a7cSthurlow  * Common Development and Distribution License (the "License").
627242a7cSthurlow  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22c242f9a0Schunli zhang - Sun Microsystems - Irvine United States  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
277c478bd9Sstevel@tonic-gate /* All Rights Reserved */
287c478bd9Sstevel@tonic-gate 
29*e36d7b11SSebastien Roy /*
30*e36d7b11SSebastien Roy  * Copyright (c) 2013 by Delphix. All rights reserved.
31*e36d7b11SSebastien Roy  */
32*e36d7b11SSebastien Roy 
337c478bd9Sstevel@tonic-gate #include <sys/param.h>
347c478bd9Sstevel@tonic-gate #include <sys/types.h>
357c478bd9Sstevel@tonic-gate #include <sys/systm.h>
367c478bd9Sstevel@tonic-gate #include <sys/user.h>
377c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
387c478bd9Sstevel@tonic-gate #include <sys/file.h>
397c478bd9Sstevel@tonic-gate #include <sys/dirent.h>
407c478bd9Sstevel@tonic-gate #include <sys/vfs.h>
417c478bd9Sstevel@tonic-gate #include <sys/stream.h>
427c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
437c478bd9Sstevel@tonic-gate #include <sys/debug.h>
447c478bd9Sstevel@tonic-gate #include <sys/t_lock.h>
457c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
467c478bd9Sstevel@tonic-gate #include <sys/dnlc.h>
477c478bd9Sstevel@tonic-gate #include <sys/cred.h>
487c478bd9Sstevel@tonic-gate #include <sys/time.h>
4927242a7cSthurlow #include <sys/sdt.h>
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #include <rpc/types.h>
527c478bd9Sstevel@tonic-gate #include <rpc/xdr.h>
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate #include <nfs/nfs.h>
557c478bd9Sstevel@tonic-gate #include <nfs/rnode.h>
560a701b1eSRobert Gordon #include <rpc/rpc_rdma.h>
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /*
597c478bd9Sstevel@tonic-gate  * These are the XDR routines used to serialize and deserialize
607c478bd9Sstevel@tonic-gate  * the various structures passed as parameters across the network
617c478bd9Sstevel@tonic-gate  * between NFS clients and servers.
627c478bd9Sstevel@tonic-gate  */
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate /*
657c478bd9Sstevel@tonic-gate  * XDR null terminated ASCII strings
667c478bd9Sstevel@tonic-gate  * xdr_string3 deals with "C strings" - arrays of bytes that are
677c478bd9Sstevel@tonic-gate  * terminated by a NULL character.  The parameter cpp references a
687c478bd9Sstevel@tonic-gate  * pointer to storage; If the pointer is null, then the necessary
697c478bd9Sstevel@tonic-gate  * storage is allocated.  The last parameter is the max allowed length
707c478bd9Sstevel@tonic-gate  * of the string as allowed by the system.  The NFS Version 3 protocol
717c478bd9Sstevel@tonic-gate  * does not place limits on strings, but the implementation needs to
727c478bd9Sstevel@tonic-gate  * place a reasonable limit to avoid problems.
737c478bd9Sstevel@tonic-gate  */
747c478bd9Sstevel@tonic-gate bool_t
757c478bd9Sstevel@tonic-gate xdr_string3(XDR *xdrs, char **cpp, uint_t maxsize)
767c478bd9Sstevel@tonic-gate {
777c478bd9Sstevel@tonic-gate 	char *sp;
787c478bd9Sstevel@tonic-gate 	uint_t size;
797c478bd9Sstevel@tonic-gate 	uint_t nodesize;
807c478bd9Sstevel@tonic-gate 	bool_t mem_alloced = FALSE;
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	/*
837c478bd9Sstevel@tonic-gate 	 * first deal with the length since xdr strings are counted-strings
847c478bd9Sstevel@tonic-gate 	 */
857c478bd9Sstevel@tonic-gate 	sp = *cpp;
867c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
877c478bd9Sstevel@tonic-gate 	case XDR_FREE:
887c478bd9Sstevel@tonic-gate 		if (sp == NULL || sp == nfs3nametoolong)
897c478bd9Sstevel@tonic-gate 			return (TRUE);	/* already free */
907c478bd9Sstevel@tonic-gate 		/* FALLTHROUGH */
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
937c478bd9Sstevel@tonic-gate 		size = (uint_t)strlen(sp);
947c478bd9Sstevel@tonic-gate 		break;
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
977c478bd9Sstevel@tonic-gate 		break;
987c478bd9Sstevel@tonic-gate 	}
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &size))
1017c478bd9Sstevel@tonic-gate 		return (FALSE);
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	/*
1047c478bd9Sstevel@tonic-gate 	 * now deal with the actual bytes
1057c478bd9Sstevel@tonic-gate 	 */
1067c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
1077c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
1087c478bd9Sstevel@tonic-gate 		if (size >= maxsize) {
1097c478bd9Sstevel@tonic-gate 			*cpp = nfs3nametoolong;
1107c478bd9Sstevel@tonic-gate 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size))
1117c478bd9Sstevel@tonic-gate 				return (FALSE);
1127c478bd9Sstevel@tonic-gate 			return (TRUE);
1137c478bd9Sstevel@tonic-gate 		}
1147c478bd9Sstevel@tonic-gate 		nodesize = size + 1;
1157c478bd9Sstevel@tonic-gate 		if (nodesize == 0)
1167c478bd9Sstevel@tonic-gate 			return (TRUE);
1177c478bd9Sstevel@tonic-gate 		if (sp == NULL) {
1187c478bd9Sstevel@tonic-gate 			sp = kmem_alloc(nodesize, KM_NOSLEEP);
1197c478bd9Sstevel@tonic-gate 			*cpp = sp;
1207c478bd9Sstevel@tonic-gate 			if (sp == NULL)
1217c478bd9Sstevel@tonic-gate 				return (FALSE);
1227c478bd9Sstevel@tonic-gate 			mem_alloced = TRUE;
1237c478bd9Sstevel@tonic-gate 		}
1247c478bd9Sstevel@tonic-gate 		sp[size] = 0;
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 		if (xdr_opaque(xdrs, sp, size)) {
1277c478bd9Sstevel@tonic-gate 			if (strlen(sp) != size) {
1287c478bd9Sstevel@tonic-gate 				if (mem_alloced)
1297c478bd9Sstevel@tonic-gate 					kmem_free(sp, nodesize);
1307c478bd9Sstevel@tonic-gate 				*cpp = NULL;
1317c478bd9Sstevel@tonic-gate 				return (FALSE);
1327c478bd9Sstevel@tonic-gate 			}
1337c478bd9Sstevel@tonic-gate 		} else {
1347c478bd9Sstevel@tonic-gate 			if (mem_alloced)
1357c478bd9Sstevel@tonic-gate 				kmem_free(sp, nodesize);
1367c478bd9Sstevel@tonic-gate 			*cpp = NULL;
1377c478bd9Sstevel@tonic-gate 			return (FALSE);
1387c478bd9Sstevel@tonic-gate 		}
1397c478bd9Sstevel@tonic-gate 		return (TRUE);
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
1427c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs, sp, size));
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	case XDR_FREE:
1457c478bd9Sstevel@tonic-gate 		nodesize = size + 1;
1467c478bd9Sstevel@tonic-gate 		kmem_free(sp, nodesize);
1477c478bd9Sstevel@tonic-gate 		*cpp = NULL;
1487c478bd9Sstevel@tonic-gate 		return (TRUE);
1497c478bd9Sstevel@tonic-gate 	}
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	return (FALSE);
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate /*
15527242a7cSthurlow  * XDR_INLINE decode a filehandle.
1567c478bd9Sstevel@tonic-gate  */
15727242a7cSthurlow bool_t
15827242a7cSthurlow xdr_inline_decode_nfs_fh3(uint32_t *ptr, nfs_fh3 *fhp, uint32_t fhsize)
1597c478bd9Sstevel@tonic-gate {
16027242a7cSthurlow 	uchar_t *bp = (uchar_t *)ptr;
16127242a7cSthurlow 	uchar_t *cp;
16227242a7cSthurlow 	uint32_t dsize;
16327242a7cSthurlow 	uintptr_t resid;
1647c478bd9Sstevel@tonic-gate 
16527242a7cSthurlow 	/*
16627242a7cSthurlow 	 * Check to see if what the client sent us is bigger or smaller
16727242a7cSthurlow 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
16827242a7cSthurlow 	 * unfortunately badly named as it is no longer the max and is
16927242a7cSthurlow 	 * really the min of what is sent over the wire.
17027242a7cSthurlow 	 */
17127242a7cSthurlow 	if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) +
17227242a7cSthurlow 	    sizeof (ushort_t) + NFS_FHMAXDATA +
17327242a7cSthurlow 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
17427242a7cSthurlow 		return (FALSE);
1757c478bd9Sstevel@tonic-gate 	}
1767c478bd9Sstevel@tonic-gate 
17727242a7cSthurlow 	/*
17827242a7cSthurlow 	 * All internal parts of a filehandle are in native byte order.
17927242a7cSthurlow 	 *
18027242a7cSthurlow 	 * Decode what should be fh3_fsid, it is aligned.
18127242a7cSthurlow 	 */
18227242a7cSthurlow 	fhp->fh3_fsid.val[0] = *(uint32_t *)bp;
18327242a7cSthurlow 	bp += BYTES_PER_XDR_UNIT;
18427242a7cSthurlow 	fhp->fh3_fsid.val[1] = *(uint32_t *)bp;
18527242a7cSthurlow 	bp += BYTES_PER_XDR_UNIT;
18627242a7cSthurlow 
18727242a7cSthurlow 	/*
18827242a7cSthurlow 	 * Decode what should be fh3_len.  fh3_len is two bytes, so we're
18927242a7cSthurlow 	 * unaligned now.
19027242a7cSthurlow 	 */
19127242a7cSthurlow 	cp = (uchar_t *)&fhp->fh3_len;
19227242a7cSthurlow 	*cp++ = *bp++;
19327242a7cSthurlow 	*cp++ = *bp++;
19427242a7cSthurlow 	fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
19527242a7cSthurlow 
19627242a7cSthurlow 	/*
19727242a7cSthurlow 	 * For backwards compatability, the fid length may be less than
19827242a7cSthurlow 	 * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
19927242a7cSthurlow 	 */
20027242a7cSthurlow 	dsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len;
20127242a7cSthurlow 
20227242a7cSthurlow 	/*
20327242a7cSthurlow 	 * Make sure the client isn't sending us a bogus length for fh3x_data.
20427242a7cSthurlow 	 */
20527242a7cSthurlow 	if (fhsize < dsize)
20627242a7cSthurlow 		return (FALSE);
20727242a7cSthurlow 	bcopy(bp, fhp->fh3_data, dsize);
20827242a7cSthurlow 	bp += dsize;
20927242a7cSthurlow 	fhsize -= dsize;
21027242a7cSthurlow 
21127242a7cSthurlow 	if (fhsize < sizeof (ushort_t))
21227242a7cSthurlow 		return (FALSE);
21327242a7cSthurlow 	cp = (uchar_t *)&fhp->fh3_xlen;
21427242a7cSthurlow 	*cp++ = *bp++;
21527242a7cSthurlow 	*cp++ = *bp++;
21627242a7cSthurlow 	fhsize -= sizeof (ushort_t);
21727242a7cSthurlow 
21827242a7cSthurlow 	dsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen;
21927242a7cSthurlow 
22027242a7cSthurlow 	/*
22127242a7cSthurlow 	 * Make sure the client isn't sending us a bogus length for fh3x_xdata.
22227242a7cSthurlow 	 */
22327242a7cSthurlow 	if (fhsize < dsize)
22427242a7cSthurlow 		return (FALSE);
22527242a7cSthurlow 	bcopy(bp, fhp->fh3_xdata, dsize);
22627242a7cSthurlow 	fhsize -= dsize;
22727242a7cSthurlow 	bp += dsize;
22827242a7cSthurlow 
22927242a7cSthurlow 	/*
23027242a7cSthurlow 	 * We realign things on purpose, so skip any padding
23127242a7cSthurlow 	 */
23227242a7cSthurlow 	resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
23327242a7cSthurlow 	if (resid != 0) {
23427242a7cSthurlow 		if (fhsize < (BYTES_PER_XDR_UNIT - resid))
23527242a7cSthurlow 			return (FALSE);
23627242a7cSthurlow 		bp += BYTES_PER_XDR_UNIT - resid;
23727242a7cSthurlow 		fhsize -= BYTES_PER_XDR_UNIT - resid;
23827242a7cSthurlow 	}
23927242a7cSthurlow 
24027242a7cSthurlow 	/*
24127242a7cSthurlow 	 * Make sure client didn't send extra bytes
24227242a7cSthurlow 	 */
24327242a7cSthurlow 	if (fhsize != 0)
24427242a7cSthurlow 		return (FALSE);
24527242a7cSthurlow 	return (TRUE);
24627242a7cSthurlow }
24727242a7cSthurlow 
24827242a7cSthurlow static bool_t
24927242a7cSthurlow xdr_decode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
25027242a7cSthurlow {
25127242a7cSthurlow 	uint32_t fhsize;		/* filehandle size */
25227242a7cSthurlow 	uint32_t bufsize;
25327242a7cSthurlow 	rpc_inline_t *ptr;
25427242a7cSthurlow 	uchar_t *bp;
25527242a7cSthurlow 
25627242a7cSthurlow 	ASSERT(xdrs->x_op == XDR_DECODE);
25727242a7cSthurlow 
25827242a7cSthurlow 	/*
25927242a7cSthurlow 	 * Retrieve the filehandle length.
26027242a7cSthurlow 	 */
26127242a7cSthurlow 	if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
26227242a7cSthurlow 		return (FALSE);
26327242a7cSthurlow 
26427242a7cSthurlow 	bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
26527242a7cSthurlow 	objp->fh3_length = 0;
26627242a7cSthurlow 
26727242a7cSthurlow 	/*
26827242a7cSthurlow 	 * Check to see if what the client sent us is bigger or smaller
26927242a7cSthurlow 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
27027242a7cSthurlow 	 * unfortunately badly named as it is no longer the max and is
27127242a7cSthurlow 	 * really the min of what is sent over the wire.
27227242a7cSthurlow 	 */
27327242a7cSthurlow 	if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) +
27427242a7cSthurlow 	    sizeof (ushort_t) + NFS_FHMAXDATA +
27527242a7cSthurlow 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
27627242a7cSthurlow 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
27727242a7cSthurlow 			return (FALSE);
27827242a7cSthurlow 		return (TRUE);
27927242a7cSthurlow 	}
28027242a7cSthurlow 
28127242a7cSthurlow 	/*
28227242a7cSthurlow 	 * bring in fhsize plus any padding
28327242a7cSthurlow 	 */
28427242a7cSthurlow 	bufsize = RNDUP(fhsize);
28527242a7cSthurlow 	ptr = XDR_INLINE(xdrs, bufsize);
28627242a7cSthurlow 	bp = (uchar_t *)ptr;
28727242a7cSthurlow 	if (ptr == NULL) {
28827242a7cSthurlow 		bp = kmem_alloc(bufsize, KM_SLEEP);
28927242a7cSthurlow 		if (!xdr_opaque(xdrs, (char *)bp, bufsize)) {
29027242a7cSthurlow 			kmem_free(bp, bufsize);
29127242a7cSthurlow 			return (FALSE);
29227242a7cSthurlow 		}
29327242a7cSthurlow 	}
29427242a7cSthurlow 
29527242a7cSthurlow 	objp->fh3_length = sizeof (fhandle3_t);
29627242a7cSthurlow 
29727242a7cSthurlow 	if (xdr_inline_decode_nfs_fh3((uint32_t *)bp, objp, fhsize) == FALSE) {
29827242a7cSthurlow 		/*
29927242a7cSthurlow 		 * If in the process of decoding we find the file handle
30027242a7cSthurlow 		 * is not correctly formed, we need to continue decoding
30127242a7cSthurlow 		 * and trigger an NFS layer error. Set the nfs_fh3_len to
30227242a7cSthurlow 		 * zero so it gets caught as a bad length.
30327242a7cSthurlow 		 */
30427242a7cSthurlow 		bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
30527242a7cSthurlow 		objp->fh3_length = 0;
30627242a7cSthurlow 	}
30727242a7cSthurlow 
30827242a7cSthurlow 	if (ptr == NULL)
30927242a7cSthurlow 		kmem_free(bp, bufsize);
31027242a7cSthurlow 	return (TRUE);
31127242a7cSthurlow }
31227242a7cSthurlow 
31327242a7cSthurlow /*
31427242a7cSthurlow  * XDR_INLINE encode a filehandle.
31527242a7cSthurlow  */
31627242a7cSthurlow bool_t
31727242a7cSthurlow xdr_inline_encode_nfs_fh3(uint32_t **ptrp, uint32_t *ptr_redzone,
31827242a7cSthurlow 	nfs_fh3 *fhp)
31927242a7cSthurlow {
32027242a7cSthurlow 	uint32_t *ptr = *ptrp;
32127242a7cSthurlow 	uchar_t *cp;
32227242a7cSthurlow 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
32327242a7cSthurlow 	uint32_t padword;
32427242a7cSthurlow 
32527242a7cSthurlow 	fsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len;
32627242a7cSthurlow 	xsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen;
32727242a7cSthurlow 
32827242a7cSthurlow 	/*
32927242a7cSthurlow 	 * First get the initial and variable sized part of the filehandle.
33027242a7cSthurlow 	 */
33127242a7cSthurlow 	otw_len = sizeof (fhp->fh3_fsid) +
33227242a7cSthurlow 	    sizeof (fhp->fh3_len) + fsize +
33327242a7cSthurlow 	    sizeof (fhp->fh3_xlen) + xsize;
33427242a7cSthurlow 
33527242a7cSthurlow 	/*
33627242a7cSthurlow 	 * Round out to a full word.
33727242a7cSthurlow 	 */
33827242a7cSthurlow 	otw_len = RNDUP(otw_len);
33927242a7cSthurlow 	padword = (otw_len / BYTES_PER_XDR_UNIT);	/* includes fhlen */
34027242a7cSthurlow 
34127242a7cSthurlow 	/*
34227242a7cSthurlow 	 * Make sure we don't exceed our buffer.
34327242a7cSthurlow 	 */
34427242a7cSthurlow 	if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone)
34527242a7cSthurlow 		return (FALSE);
34627242a7cSthurlow 
34727242a7cSthurlow 	/*
34827242a7cSthurlow 	 * Zero out the pading.
34927242a7cSthurlow 	 */
35027242a7cSthurlow 	ptr[padword] = 0;
35127242a7cSthurlow 
35227242a7cSthurlow 	IXDR_PUT_U_INT32(ptr, otw_len);
35327242a7cSthurlow 
35427242a7cSthurlow 	/*
35527242a7cSthurlow 	 * The rest of the filehandle is in native byteorder
35627242a7cSthurlow 	 */
35727242a7cSthurlow 	/* fh3_fsid */
35827242a7cSthurlow 	*ptr++ = (uint32_t)fhp->fh3_fsid.val[0];
35927242a7cSthurlow 	*ptr++ = (uint32_t)fhp->fh3_fsid.val[1];
36027242a7cSthurlow 
36127242a7cSthurlow 	/*
36227242a7cSthurlow 	 * Since the next pieces are unaligned, we need to
36327242a7cSthurlow 	 * do bytewise copies.
36427242a7cSthurlow 	 */
36527242a7cSthurlow 	cp = (uchar_t *)ptr;
36627242a7cSthurlow 
36727242a7cSthurlow 	/* fh3_len + fh3_data */
36827242a7cSthurlow 	bcopy(&fhp->fh3_len, cp, sizeof (fhp->fh3_len) + fsize);
36927242a7cSthurlow 	cp += sizeof (fhp->fh3_len) + fsize;
37027242a7cSthurlow 
37127242a7cSthurlow 	/* fh3_xlen + fh3_xdata */
37227242a7cSthurlow 	bcopy(&fhp->fh3_xlen, cp, sizeof (fhp->fh3_xlen) + xsize);
37327242a7cSthurlow 	cp += sizeof (fhp->fh3_xlen) + xsize;
37427242a7cSthurlow 
37527242a7cSthurlow 	/* do necessary rounding/padding */
37627242a7cSthurlow 	cp = (uchar_t *)RNDUP((uintptr_t)cp);
37727242a7cSthurlow 	ptr = (uint32_t *)cp;
37827242a7cSthurlow 
37927242a7cSthurlow 	/*
38027242a7cSthurlow 	 * With the above padding, we're word aligned again.
38127242a7cSthurlow 	 */
38227242a7cSthurlow 	ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0);
38327242a7cSthurlow 
38427242a7cSthurlow 	*ptrp = ptr;
38527242a7cSthurlow 
38627242a7cSthurlow 	return (TRUE);
38727242a7cSthurlow }
38827242a7cSthurlow 
38927242a7cSthurlow static bool_t
39027242a7cSthurlow xdr_encode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
39127242a7cSthurlow {
39227242a7cSthurlow 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
39327242a7cSthurlow 	bool_t ret;
39427242a7cSthurlow 	rpc_inline_t *ptr;
39527242a7cSthurlow 	rpc_inline_t *buf = NULL;
39627242a7cSthurlow 	uint32_t *ptr_redzone;
39727242a7cSthurlow 
39827242a7cSthurlow 	ASSERT(xdrs->x_op == XDR_ENCODE);
39927242a7cSthurlow 
40027242a7cSthurlow 	fsize = objp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_len;
40127242a7cSthurlow 	xsize = objp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_xlen;
40227242a7cSthurlow 
40327242a7cSthurlow 	/*
40427242a7cSthurlow 	 * First get the over the wire size, it is the 4 bytes
40527242a7cSthurlow 	 * for the length, plus the combined size of the
40627242a7cSthurlow 	 * file handle components.
40727242a7cSthurlow 	 */
40827242a7cSthurlow 	otw_len = BYTES_PER_XDR_UNIT + sizeof (objp->fh3_fsid) +
40927242a7cSthurlow 	    sizeof (objp->fh3_len) + fsize +
41027242a7cSthurlow 	    sizeof (objp->fh3_xlen) + xsize;
41127242a7cSthurlow 	/*
41227242a7cSthurlow 	 * Round out to a full word.
41327242a7cSthurlow 	 */
41427242a7cSthurlow 	otw_len = RNDUP(otw_len);
41527242a7cSthurlow 
41627242a7cSthurlow 	/*
41727242a7cSthurlow 	 * Next try to inline the XDR stream, if that fails (rare)
41827242a7cSthurlow 	 * allocate a buffer to encode the file handle and then
41927242a7cSthurlow 	 * copy it using xdr_opaque and free the buffer.
42027242a7cSthurlow 	 */
42127242a7cSthurlow 	ptr = XDR_INLINE(xdrs, otw_len);
42227242a7cSthurlow 	if (ptr == NULL)
42327242a7cSthurlow 		ptr = buf = kmem_alloc(otw_len, KM_SLEEP);
42427242a7cSthurlow 
42527242a7cSthurlow 	ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT));
42627242a7cSthurlow 	ret = xdr_inline_encode_nfs_fh3((uint32_t **)&ptr, ptr_redzone, objp);
42727242a7cSthurlow 
42827242a7cSthurlow 	if (buf != NULL) {
42927242a7cSthurlow 		if (ret == TRUE)
43027242a7cSthurlow 			ret = xdr_opaque(xdrs, (char *)buf, otw_len);
43127242a7cSthurlow 		kmem_free(buf, otw_len);
43227242a7cSthurlow 	}
43327242a7cSthurlow 	return (ret);
43427242a7cSthurlow }
43527242a7cSthurlow 
43627242a7cSthurlow /*
43727242a7cSthurlow  * XDR a NFSv3 filehandle the naive way.
43827242a7cSthurlow  */
4397c478bd9Sstevel@tonic-gate bool_t
4407c478bd9Sstevel@tonic-gate xdr_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
4417c478bd9Sstevel@tonic-gate {
4427c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
4437c478bd9Sstevel@tonic-gate 		return (TRUE);
4447c478bd9Sstevel@tonic-gate 
4457c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->fh3_length))
4467c478bd9Sstevel@tonic-gate 		return (FALSE);
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 	if (objp->fh3_length > NFS3_FHSIZE)
4497c478bd9Sstevel@tonic-gate 		return (FALSE);
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, objp->fh3_u.data, objp->fh3_length));
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate /*
45527242a7cSthurlow  * XDR a NFSv3 filehandle with intelligence on the server.
45627242a7cSthurlow  * Encoding goes from our in-memory structure to wire format.
45727242a7cSthurlow  * Decoding goes from wire format to our in-memory structure.
4587c478bd9Sstevel@tonic-gate  */
4597c478bd9Sstevel@tonic-gate bool_t
46027242a7cSthurlow xdr_nfs_fh3_server(XDR *xdrs, nfs_fh3 *objp)
4617c478bd9Sstevel@tonic-gate {
46227242a7cSthurlow 	switch (xdrs->x_op) {
46327242a7cSthurlow 	case XDR_ENCODE:
4646a8ebdc3Sthurlow 		if (objp->fh3_flags & FH_WEBNFS)
4656a8ebdc3Sthurlow 			return (xdr_nfs_fh3(xdrs, objp));
4666a8ebdc3Sthurlow 		else
46727242a7cSthurlow 			return (xdr_encode_nfs_fh3(xdrs, objp));
46827242a7cSthurlow 	case XDR_DECODE:
46927242a7cSthurlow 		return (xdr_decode_nfs_fh3(xdrs, objp));
47027242a7cSthurlow 	case XDR_FREE:
47127242a7cSthurlow 		if (objp->fh3_u.data != NULL)
47227242a7cSthurlow 			bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
4737c478bd9Sstevel@tonic-gate 		return (TRUE);
4747c478bd9Sstevel@tonic-gate 	}
4757c478bd9Sstevel@tonic-gate 	return (FALSE);
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate bool_t
4797c478bd9Sstevel@tonic-gate xdr_diropargs3(XDR *xdrs, diropargs3 *objp)
4807c478bd9Sstevel@tonic-gate {
48127242a7cSthurlow 	switch (xdrs->x_op) {
48227242a7cSthurlow 	case XDR_FREE:
48327242a7cSthurlow 	case XDR_ENCODE:
4847c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, objp->dirp))
4857c478bd9Sstevel@tonic-gate 			return (FALSE);
48627242a7cSthurlow 		break;
48727242a7cSthurlow 	case XDR_DECODE:
48827242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
48927242a7cSthurlow 			return (FALSE);
49027242a7cSthurlow 		break;
49127242a7cSthurlow 	}
4927c478bd9Sstevel@tonic-gate 	return (xdr_string3(xdrs, &objp->name, MAXNAMELEN));
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate static bool_t
4967c478bd9Sstevel@tonic-gate xdr_fattr3(XDR *xdrs, fattr3 *na)
4977c478bd9Sstevel@tonic-gate {
4987c478bd9Sstevel@tonic-gate 	int32_t *ptr;
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
5017c478bd9Sstevel@tonic-gate 		return (TRUE);
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
5047c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
5057c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
5067c478bd9Sstevel@tonic-gate 			na->type = IXDR_GET_ENUM(ptr, enum ftype3);
5077c478bd9Sstevel@tonic-gate 			na->mode = IXDR_GET_U_INT32(ptr);
5087c478bd9Sstevel@tonic-gate 			na->nlink = IXDR_GET_U_INT32(ptr);
5097c478bd9Sstevel@tonic-gate 			na->uid = IXDR_GET_U_INT32(ptr);
5107c478bd9Sstevel@tonic-gate 			na->gid = IXDR_GET_U_INT32(ptr);
5117c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, na->size);
5127c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, na->used);
5137c478bd9Sstevel@tonic-gate 			na->rdev.specdata1 = IXDR_GET_U_INT32(ptr);
5147c478bd9Sstevel@tonic-gate 			na->rdev.specdata2 = IXDR_GET_U_INT32(ptr);
5157c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, na->fsid);
5167c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, na->fileid);
5177c478bd9Sstevel@tonic-gate 			na->atime.seconds = IXDR_GET_U_INT32(ptr);
5187c478bd9Sstevel@tonic-gate 			na->atime.nseconds = IXDR_GET_U_INT32(ptr);
5197c478bd9Sstevel@tonic-gate 			na->mtime.seconds = IXDR_GET_U_INT32(ptr);
5207c478bd9Sstevel@tonic-gate 			na->mtime.nseconds = IXDR_GET_U_INT32(ptr);
5217c478bd9Sstevel@tonic-gate 			na->ctime.seconds = IXDR_GET_U_INT32(ptr);
5227c478bd9Sstevel@tonic-gate 			na->ctime.nseconds = IXDR_GET_U_INT32(ptr);
5237c478bd9Sstevel@tonic-gate 		} else {
5247c478bd9Sstevel@tonic-gate 			IXDR_PUT_ENUM(ptr, na->type);
5257c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->mode);
5267c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->nlink);
5277c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->uid);
5287c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->gid);
5297c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_HYPER(ptr, na->size);
5307c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_HYPER(ptr, na->used);
5317c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->rdev.specdata1);
5327c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->rdev.specdata2);
5337c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_HYPER(ptr, na->fsid);
5347c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_HYPER(ptr, na->fileid);
5357c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->atime.seconds);
5367c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->atime.nseconds);
5377c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->mtime.seconds);
5387c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->mtime.nseconds);
5397c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->ctime.seconds);
5407c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->ctime.nseconds);
5417c478bd9Sstevel@tonic-gate 		}
5427c478bd9Sstevel@tonic-gate 		return (TRUE);
5437c478bd9Sstevel@tonic-gate 	}
5447c478bd9Sstevel@tonic-gate 	if (!(xdr_enum(xdrs, (enum_t *)&na->type) &&
5457c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->mode) &&
5467c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->nlink) &&
5477c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->uid) &&
5487c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->gid) &&
5497c478bd9Sstevel@tonic-gate 	    xdr_u_longlong_t(xdrs, &na->size) &&
5507c478bd9Sstevel@tonic-gate 	    xdr_u_longlong_t(xdrs, &na->used) &&
5517c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->rdev.specdata1) &&
5527c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->rdev.specdata2) &&
5537c478bd9Sstevel@tonic-gate 	    xdr_u_longlong_t(xdrs, &na->fsid) &&
5547c478bd9Sstevel@tonic-gate 	    xdr_u_longlong_t(xdrs, &na->fileid) &&
5557c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->atime.seconds) &&
5567c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->atime.nseconds) &&
5577c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->mtime.seconds) &&
5587c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->mtime.nseconds) &&
5597c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->ctime.seconds) &&
5607c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &na->ctime.nseconds)))
5617c478bd9Sstevel@tonic-gate 			return (FALSE);
5627c478bd9Sstevel@tonic-gate 	return (TRUE);
5637c478bd9Sstevel@tonic-gate }
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate /*
5667c478bd9Sstevel@tonic-gate  * Fast decode of an fattr3 to a vattr
5677c478bd9Sstevel@tonic-gate  * Only return FALSE on decode error, all other fattr to vattr translation
5687c478bd9Sstevel@tonic-gate  * failures set status.
5697c478bd9Sstevel@tonic-gate  *
5707c478bd9Sstevel@tonic-gate  * Callers must catch the following errors:
5717c478bd9Sstevel@tonic-gate  *	EFBIG - file size will not fit in va_size
5727c478bd9Sstevel@tonic-gate  *	EOVERFLOW - time will not fit in va_*time
5737c478bd9Sstevel@tonic-gate  */
5747c478bd9Sstevel@tonic-gate static bool_t
5757c478bd9Sstevel@tonic-gate xdr_fattr3_to_vattr(XDR *xdrs, fattr3_res *objp)
5767c478bd9Sstevel@tonic-gate {
5777c478bd9Sstevel@tonic-gate 	int32_t *ptr;
5787c478bd9Sstevel@tonic-gate 	size3 used;
5797c478bd9Sstevel@tonic-gate 	specdata3 rdev;
5807c478bd9Sstevel@tonic-gate 	uint32_t ntime;
5817c478bd9Sstevel@tonic-gate 	vattr_t *vap = objp->vap;
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate 	/*
5847c478bd9Sstevel@tonic-gate 	 * DECODE only
5857c478bd9Sstevel@tonic-gate 	 */
5867c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
5877c478bd9Sstevel@tonic-gate 
5881e96f9d6SRich Brown 	/* On success, all attributes will be decoded */
5891e96f9d6SRich Brown 	vap->va_mask = AT_ALL;
5901e96f9d6SRich Brown 
5917c478bd9Sstevel@tonic-gate 	objp->status = 0;
5927c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
5937c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
5947c478bd9Sstevel@tonic-gate 		/*
5957c478bd9Sstevel@tonic-gate 		 * Common case
5967c478bd9Sstevel@tonic-gate 		 */
5977c478bd9Sstevel@tonic-gate 		vap->va_type = IXDR_GET_ENUM(ptr, enum vtype);
5982c2d21e9SRichard Lowe 		if ((ftype3)vap->va_type < NF3REG ||
5992c2d21e9SRichard Lowe 		    (ftype3)vap->va_type > NF3FIFO)
6007c478bd9Sstevel@tonic-gate 			vap->va_type = VBAD;
6017c478bd9Sstevel@tonic-gate 		else
6027c478bd9Sstevel@tonic-gate 			vap->va_type = nf3_to_vt[vap->va_type];
6037c478bd9Sstevel@tonic-gate 		vap->va_mode = IXDR_GET_U_INT32(ptr);
6047c478bd9Sstevel@tonic-gate 		vap->va_nlink = IXDR_GET_U_INT32(ptr);
6057c478bd9Sstevel@tonic-gate 		vap->va_uid = (uid_t)IXDR_GET_U_INT32(ptr);
6067c478bd9Sstevel@tonic-gate 		if (vap->va_uid == NFS_UID_NOBODY)
6077c478bd9Sstevel@tonic-gate 			vap->va_uid = UID_NOBODY;
6087c478bd9Sstevel@tonic-gate 		vap->va_gid = (gid_t)IXDR_GET_U_INT32(ptr);
6097c478bd9Sstevel@tonic-gate 		if (vap->va_gid == NFS_GID_NOBODY)
6107c478bd9Sstevel@tonic-gate 			vap->va_gid = GID_NOBODY;
6117c478bd9Sstevel@tonic-gate 		IXDR_GET_U_HYPER(ptr, vap->va_size);
6127c478bd9Sstevel@tonic-gate 		/*
6137c478bd9Sstevel@tonic-gate 		 * If invalid size, stop decode, set status, and
6147c478bd9Sstevel@tonic-gate 		 * return TRUE, x_handy will be correct, caller must ignore vap.
6157c478bd9Sstevel@tonic-gate 		 */
6167c478bd9Sstevel@tonic-gate 		if (!NFS3_SIZE_OK(vap->va_size)) {
6177c478bd9Sstevel@tonic-gate 			objp->status = EFBIG;
6187c478bd9Sstevel@tonic-gate 			return (TRUE);
6197c478bd9Sstevel@tonic-gate 		}
6207c478bd9Sstevel@tonic-gate 		IXDR_GET_U_HYPER(ptr, used);
6217c478bd9Sstevel@tonic-gate 		rdev.specdata1 = IXDR_GET_U_INT32(ptr);
6227c478bd9Sstevel@tonic-gate 		rdev.specdata2 = IXDR_GET_U_INT32(ptr);
6237c478bd9Sstevel@tonic-gate 		/* fsid is ignored */
6247c478bd9Sstevel@tonic-gate 		ptr += 2;
6257c478bd9Sstevel@tonic-gate 		IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate 		/*
6287c478bd9Sstevel@tonic-gate 		 * nfs protocol defines times as unsigned so don't
6297c478bd9Sstevel@tonic-gate 		 * extend sign, unless sysadmin set nfs_allow_preepoch_time.
6307c478bd9Sstevel@tonic-gate 		 * The inline macros do the equivilant of NFS_TIME_T_CONVERT
6317c478bd9Sstevel@tonic-gate 		 */
6327c478bd9Sstevel@tonic-gate 		if (nfs_allow_preepoch_time) {
6337c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_sec = IXDR_GET_INT32(ptr);
6347c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
6357c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_sec = IXDR_GET_INT32(ptr);
6367c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
6377c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_sec = IXDR_GET_INT32(ptr);
6387c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
6397c478bd9Sstevel@tonic-gate 		} else {
6407c478bd9Sstevel@tonic-gate 			/*
6417c478bd9Sstevel@tonic-gate 			 * Check if the time would overflow on 32-bit
6427c478bd9Sstevel@tonic-gate 			 */
6437c478bd9Sstevel@tonic-gate 			ntime = IXDR_GET_U_INT32(ptr);
6447c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
6457c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
6467c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
6477c478bd9Sstevel@tonic-gate 				return (TRUE);
6487c478bd9Sstevel@tonic-gate 			}
6497c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_sec = ntime;
6507c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate 			ntime = IXDR_GET_U_INT32(ptr);
6537c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
6547c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
6557c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
6567c478bd9Sstevel@tonic-gate 				return (TRUE);
6577c478bd9Sstevel@tonic-gate 			}
6587c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_sec = ntime;
6597c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
6607c478bd9Sstevel@tonic-gate 
6617c478bd9Sstevel@tonic-gate 			ntime = IXDR_GET_U_INT32(ptr);
6627c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
6637c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
6647c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
6657c478bd9Sstevel@tonic-gate 				return (TRUE);
6667c478bd9Sstevel@tonic-gate 			}
6677c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_sec = ntime;
6687c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
6697c478bd9Sstevel@tonic-gate 		}
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 	} else {
6727c478bd9Sstevel@tonic-gate 		uint64 fsid;
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate 		/*
6757c478bd9Sstevel@tonic-gate 		 * Slow path
6767c478bd9Sstevel@tonic-gate 		 */
6777c478bd9Sstevel@tonic-gate 		if (!(xdr_enum(xdrs, (enum_t *)&vap->va_type) &&
6787c478bd9Sstevel@tonic-gate 		    xdr_u_int(xdrs, &vap->va_mode) &&
6797c478bd9Sstevel@tonic-gate 		    xdr_u_int(xdrs, &vap->va_nlink) &&
6807c478bd9Sstevel@tonic-gate 		    xdr_u_int(xdrs, (uint_t *)&vap->va_uid) &&
6817c478bd9Sstevel@tonic-gate 		    xdr_u_int(xdrs, (uint_t *)&vap->va_gid) &&
6827c478bd9Sstevel@tonic-gate 		    xdr_u_longlong_t(xdrs, &vap->va_size) &&
6837c478bd9Sstevel@tonic-gate 		    xdr_u_longlong_t(xdrs, &used) &&
6847c478bd9Sstevel@tonic-gate 		    xdr_u_int(xdrs, &rdev.specdata1) &&
6857c478bd9Sstevel@tonic-gate 		    xdr_u_int(xdrs, &rdev.specdata2) &&
6867c478bd9Sstevel@tonic-gate 		    xdr_u_longlong_t(xdrs, &fsid) &&	/* ignored */
6877c478bd9Sstevel@tonic-gate 		    xdr_u_longlong_t(xdrs, &vap->va_nodeid)))
6887c478bd9Sstevel@tonic-gate 				return (FALSE);
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 		if (nfs_allow_preepoch_time) {
6917c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
6927c478bd9Sstevel@tonic-gate 				return (FALSE);
6937c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_sec = (int32_t)ntime;
6947c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
6957c478bd9Sstevel@tonic-gate 				return (FALSE);
6967c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_nsec = ntime;
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
6997c478bd9Sstevel@tonic-gate 				return (FALSE);
7007c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_sec = (int32_t)ntime;
7017c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7027c478bd9Sstevel@tonic-gate 				return (FALSE);
7037c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_nsec = ntime;
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7067c478bd9Sstevel@tonic-gate 				return (FALSE);
7077c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_sec = (int32_t)ntime;
7087c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7097c478bd9Sstevel@tonic-gate 				return (FALSE);
7107c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_nsec = ntime;
7117c478bd9Sstevel@tonic-gate 		} else {
7127c478bd9Sstevel@tonic-gate 			/*
7137c478bd9Sstevel@tonic-gate 			 * Check if the time would overflow on 32-bit
7147c478bd9Sstevel@tonic-gate 			 * Set status and keep decoding stream.
7157c478bd9Sstevel@tonic-gate 			 */
7167c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7177c478bd9Sstevel@tonic-gate 				return (FALSE);
7187c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
7197c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
7207c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
7217c478bd9Sstevel@tonic-gate 			}
7227c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_sec = ntime;
7237c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7247c478bd9Sstevel@tonic-gate 				return (FALSE);
7257c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_nsec = ntime;
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7287c478bd9Sstevel@tonic-gate 				return (FALSE);
7297c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
7307c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
7317c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
7327c478bd9Sstevel@tonic-gate 			}
7337c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_sec = ntime;
7347c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7357c478bd9Sstevel@tonic-gate 				return (FALSE);
7367c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_nsec = ntime;
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7397c478bd9Sstevel@tonic-gate 				return (FALSE);
7407c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
7417c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
7427c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
7437c478bd9Sstevel@tonic-gate 			}
7447c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_sec = ntime;
7457c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7467c478bd9Sstevel@tonic-gate 				return (FALSE);
7477c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_nsec = ntime;
7487c478bd9Sstevel@tonic-gate 		}
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate 		/*
7517c478bd9Sstevel@tonic-gate 		 * Fixup as needed
7527c478bd9Sstevel@tonic-gate 		 */
7532c2d21e9SRichard Lowe 		if ((ftype3)vap->va_type < NF3REG ||
7542c2d21e9SRichard Lowe 		    (ftype3)vap->va_type > NF3FIFO)
7557c478bd9Sstevel@tonic-gate 			vap->va_type = VBAD;
7567c478bd9Sstevel@tonic-gate 		else
7577c478bd9Sstevel@tonic-gate 			vap->va_type = nf3_to_vt[vap->va_type];
7587c478bd9Sstevel@tonic-gate 		if (vap->va_uid == NFS_UID_NOBODY)
7597c478bd9Sstevel@tonic-gate 			vap->va_uid = UID_NOBODY;
7607c478bd9Sstevel@tonic-gate 		if (vap->va_gid == NFS_GID_NOBODY)
7617c478bd9Sstevel@tonic-gate 			vap->va_gid = GID_NOBODY;
7627c478bd9Sstevel@tonic-gate 		/*
7637c478bd9Sstevel@tonic-gate 		 * If invalid size, set status, and
7647c478bd9Sstevel@tonic-gate 		 * return TRUE, caller must ignore vap.
7657c478bd9Sstevel@tonic-gate 		 */
7667c478bd9Sstevel@tonic-gate 		if (!NFS3_SIZE_OK(vap->va_size)) {
7677c478bd9Sstevel@tonic-gate 			objp->status = EFBIG;
7687c478bd9Sstevel@tonic-gate 			return (TRUE);
7697c478bd9Sstevel@tonic-gate 		}
7707c478bd9Sstevel@tonic-gate 	}
7717c478bd9Sstevel@tonic-gate 
7727c478bd9Sstevel@tonic-gate 	/*
7737c478bd9Sstevel@tonic-gate 	 * Fill in derived fields
7747c478bd9Sstevel@tonic-gate 	 */
7757c478bd9Sstevel@tonic-gate 	vap->va_fsid = objp->vp->v_vfsp->vfs_dev;
7767c478bd9Sstevel@tonic-gate 	vap->va_seq = 0;
7777c478bd9Sstevel@tonic-gate 
7787c478bd9Sstevel@tonic-gate 	/*
7797c478bd9Sstevel@tonic-gate 	 * Common case values
7807c478bd9Sstevel@tonic-gate 	 */
7817c478bd9Sstevel@tonic-gate 	vap->va_rdev = 0;
7827c478bd9Sstevel@tonic-gate 	vap->va_blksize = MAXBSIZE;
7837c478bd9Sstevel@tonic-gate 	vap->va_nblocks = 0;
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	switch (vap->va_type) {
7867c478bd9Sstevel@tonic-gate 	case VREG:
7877c478bd9Sstevel@tonic-gate 	case VDIR:
7887c478bd9Sstevel@tonic-gate 	case VLNK:
7897c478bd9Sstevel@tonic-gate 		vap->va_nblocks = (u_longlong_t)
7907c478bd9Sstevel@tonic-gate 		    ((used + (size3)DEV_BSIZE - (size3)1) /
7917c478bd9Sstevel@tonic-gate 		    (size3)DEV_BSIZE);
7927c478bd9Sstevel@tonic-gate 		break;
7937c478bd9Sstevel@tonic-gate 	case VBLK:
7947c478bd9Sstevel@tonic-gate 		vap->va_blksize = DEV_BSIZE;
7957c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
7967c478bd9Sstevel@tonic-gate 	case VCHR:
7977c478bd9Sstevel@tonic-gate 		vap->va_rdev = makedevice(rdev.specdata1, rdev.specdata2);
7987c478bd9Sstevel@tonic-gate 		break;
7997c478bd9Sstevel@tonic-gate 	case VSOCK:
8007c478bd9Sstevel@tonic-gate 	case VFIFO:
8017c478bd9Sstevel@tonic-gate 	default:
8027c478bd9Sstevel@tonic-gate 		break;
8037c478bd9Sstevel@tonic-gate 	}
8047c478bd9Sstevel@tonic-gate 
8057c478bd9Sstevel@tonic-gate 	return (TRUE);
8067c478bd9Sstevel@tonic-gate }
8077c478bd9Sstevel@tonic-gate 
8087c478bd9Sstevel@tonic-gate static bool_t
8097c478bd9Sstevel@tonic-gate xdr_post_op_vattr(XDR *xdrs, post_op_vattr *objp)
8107c478bd9Sstevel@tonic-gate {
8117c478bd9Sstevel@tonic-gate 	/*
8127c478bd9Sstevel@tonic-gate 	 * DECODE only
8137c478bd9Sstevel@tonic-gate 	 */
8147c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->attributes))
8177c478bd9Sstevel@tonic-gate 		return (FALSE);
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate 	if (objp->attributes == FALSE)
8207c478bd9Sstevel@tonic-gate 		return (TRUE);
8217c478bd9Sstevel@tonic-gate 
8227c478bd9Sstevel@tonic-gate 	if (objp->attributes != TRUE)
8237c478bd9Sstevel@tonic-gate 		return (FALSE);
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate 	if (!xdr_fattr3_to_vattr(xdrs, &objp->fres))
8267c478bd9Sstevel@tonic-gate 		return (FALSE);
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate 	/*
8297c478bd9Sstevel@tonic-gate 	 * The file size may cause an EFBIG or the time values
8307c478bd9Sstevel@tonic-gate 	 * may cause EOVERFLOW, if so simply drop the attributes.
8317c478bd9Sstevel@tonic-gate 	 */
8327c478bd9Sstevel@tonic-gate 	if (objp->fres.status != NFS3_OK)
8337c478bd9Sstevel@tonic-gate 		objp->attributes = FALSE;
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 	return (TRUE);
8367c478bd9Sstevel@tonic-gate }
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate bool_t
8397c478bd9Sstevel@tonic-gate xdr_post_op_attr(XDR *xdrs, post_op_attr *objp)
8407c478bd9Sstevel@tonic-gate {
8417c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->attributes))
8427c478bd9Sstevel@tonic-gate 		return (FALSE);
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 	if (objp->attributes == FALSE)
8457c478bd9Sstevel@tonic-gate 		return (TRUE);
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate 	if (objp->attributes != TRUE)
8487c478bd9Sstevel@tonic-gate 		return (FALSE);
8497c478bd9Sstevel@tonic-gate 
8507c478bd9Sstevel@tonic-gate 	if (!xdr_fattr3(xdrs, &objp->attr))
8517c478bd9Sstevel@tonic-gate 		return (FALSE);
8527c478bd9Sstevel@tonic-gate 
8537c478bd9Sstevel@tonic-gate 	/*
8547c478bd9Sstevel@tonic-gate 	 * Check that we don't get a file we can't handle through
8557c478bd9Sstevel@tonic-gate 	 *	existing interfaces (especially stat64()).
8567c478bd9Sstevel@tonic-gate 	 * Decode only check since on encode the data has
8577c478bd9Sstevel@tonic-gate 	 * been dealt with in the above call to xdr_fattr3().
8587c478bd9Sstevel@tonic-gate 	 */
8597c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
8607c478bd9Sstevel@tonic-gate 		/* Set attrs to false if invalid size or time */
8617c478bd9Sstevel@tonic-gate 		if (!NFS3_SIZE_OK(objp->attr.size)) {
8627c478bd9Sstevel@tonic-gate 			objp->attributes = FALSE;
8637c478bd9Sstevel@tonic-gate 			return (TRUE);
8647c478bd9Sstevel@tonic-gate 		}
8657c478bd9Sstevel@tonic-gate #ifndef _LP64
8667c478bd9Sstevel@tonic-gate 		if (!NFS3_FATTR_TIME_OK(&objp->attr))
8677c478bd9Sstevel@tonic-gate 			objp->attributes = FALSE;
8687c478bd9Sstevel@tonic-gate #endif
8697c478bd9Sstevel@tonic-gate 	}
8707c478bd9Sstevel@tonic-gate 	return (TRUE);
8717c478bd9Sstevel@tonic-gate }
8727c478bd9Sstevel@tonic-gate 
8737c478bd9Sstevel@tonic-gate static bool_t
8747c478bd9Sstevel@tonic-gate xdr_wcc_data(XDR *xdrs, wcc_data *objp)
8757c478bd9Sstevel@tonic-gate {
8767c478bd9Sstevel@tonic-gate 	int32_t *ptr;
8777c478bd9Sstevel@tonic-gate 	wcc_attr *attrp;
8787c478bd9Sstevel@tonic-gate 
8797c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
8807c478bd9Sstevel@tonic-gate 		return (TRUE);
8817c478bd9Sstevel@tonic-gate 
8827c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
8837c478bd9Sstevel@tonic-gate 		/* pre_op_attr */
8847c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->before.attributes))
8857c478bd9Sstevel@tonic-gate 			return (FALSE);
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 		switch (objp->before.attributes) {
8887c478bd9Sstevel@tonic-gate 		case TRUE:
8897c478bd9Sstevel@tonic-gate 			attrp = &objp->before.attr;
8907c478bd9Sstevel@tonic-gate 			ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
8917c478bd9Sstevel@tonic-gate 			if (ptr != NULL) {
8927c478bd9Sstevel@tonic-gate 				IXDR_GET_U_HYPER(ptr, attrp->size);
8937c478bd9Sstevel@tonic-gate 				attrp->mtime.seconds = IXDR_GET_U_INT32(ptr);
8947c478bd9Sstevel@tonic-gate 				attrp->mtime.nseconds = IXDR_GET_U_INT32(ptr);
8957c478bd9Sstevel@tonic-gate 				attrp->ctime.seconds = IXDR_GET_U_INT32(ptr);
8967c478bd9Sstevel@tonic-gate 				attrp->ctime.nseconds = IXDR_GET_U_INT32(ptr);
8977c478bd9Sstevel@tonic-gate 			} else {
8987c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs, &attrp->size))
8997c478bd9Sstevel@tonic-gate 					return (FALSE);
9007c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
9017c478bd9Sstevel@tonic-gate 					return (FALSE);
9027c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
9037c478bd9Sstevel@tonic-gate 					return (FALSE);
9047c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
9057c478bd9Sstevel@tonic-gate 					return (FALSE);
9067c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
9077c478bd9Sstevel@tonic-gate 					return (FALSE);
9087c478bd9Sstevel@tonic-gate 			}
9097c478bd9Sstevel@tonic-gate 
9107c478bd9Sstevel@tonic-gate #ifndef _LP64
9117c478bd9Sstevel@tonic-gate 			/*
9127c478bd9Sstevel@tonic-gate 			 * check time overflow.
9137c478bd9Sstevel@tonic-gate 			 */
9147c478bd9Sstevel@tonic-gate 			if (!NFS3_TIME_OK(attrp->mtime.seconds) ||
9157c478bd9Sstevel@tonic-gate 			    !NFS3_TIME_OK(attrp->ctime.seconds))
9167c478bd9Sstevel@tonic-gate 				objp->before.attributes = FALSE;
9177c478bd9Sstevel@tonic-gate #endif
9187c478bd9Sstevel@tonic-gate 			break;
9197c478bd9Sstevel@tonic-gate 		case FALSE:
9207c478bd9Sstevel@tonic-gate 			break;
9217c478bd9Sstevel@tonic-gate 		default:
9227c478bd9Sstevel@tonic-gate 			return (FALSE);
9237c478bd9Sstevel@tonic-gate 		}
9247c478bd9Sstevel@tonic-gate 	}
9257c478bd9Sstevel@tonic-gate 
9267c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
9277c478bd9Sstevel@tonic-gate 		/* pre_op_attr */
9287c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->before.attributes))
9297c478bd9Sstevel@tonic-gate 			return (FALSE);
9307c478bd9Sstevel@tonic-gate 
9317c478bd9Sstevel@tonic-gate 		switch (objp->before.attributes) {
9327c478bd9Sstevel@tonic-gate 		case TRUE:
9337c478bd9Sstevel@tonic-gate 			attrp = &objp->before.attr;
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate 			ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
9367c478bd9Sstevel@tonic-gate 			if (ptr != NULL) {
9377c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_HYPER(ptr, attrp->size);
9387c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_INT32(ptr, attrp->mtime.seconds);
9397c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_INT32(ptr, attrp->mtime.nseconds);
9407c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_INT32(ptr, attrp->ctime.seconds);
9417c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_INT32(ptr, attrp->ctime.nseconds);
9427c478bd9Sstevel@tonic-gate 			} else {
9437c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs, &attrp->size))
9447c478bd9Sstevel@tonic-gate 					return (FALSE);
9457c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
9467c478bd9Sstevel@tonic-gate 					return (FALSE);
9477c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
9487c478bd9Sstevel@tonic-gate 					return (FALSE);
9497c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
9507c478bd9Sstevel@tonic-gate 					return (FALSE);
9517c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
9527c478bd9Sstevel@tonic-gate 					return (FALSE);
9537c478bd9Sstevel@tonic-gate 			}
9547c478bd9Sstevel@tonic-gate 			break;
9557c478bd9Sstevel@tonic-gate 		case FALSE:
9567c478bd9Sstevel@tonic-gate 			break;
9577c478bd9Sstevel@tonic-gate 		default:
9587c478bd9Sstevel@tonic-gate 			return (FALSE);
9597c478bd9Sstevel@tonic-gate 		}
9607c478bd9Sstevel@tonic-gate 	}
9617c478bd9Sstevel@tonic-gate 	return (xdr_post_op_attr(xdrs, &objp->after));
9627c478bd9Sstevel@tonic-gate }
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate bool_t
9657c478bd9Sstevel@tonic-gate xdr_post_op_fh3(XDR *xdrs, post_op_fh3 *objp)
9667c478bd9Sstevel@tonic-gate {
9677c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->handle_follows))
9687c478bd9Sstevel@tonic-gate 		return (FALSE);
9697c478bd9Sstevel@tonic-gate 	switch (objp->handle_follows) {
9707c478bd9Sstevel@tonic-gate 	case TRUE:
97127242a7cSthurlow 		switch (xdrs->x_op) {
97227242a7cSthurlow 		case XDR_ENCODE:
97327242a7cSthurlow 			if (!xdr_nfs_fh3_server(xdrs, &objp->handle))
97427242a7cSthurlow 				return (FALSE);
97527242a7cSthurlow 			break;
97627242a7cSthurlow 		case XDR_FREE:
97727242a7cSthurlow 		case XDR_DECODE:
97827242a7cSthurlow 			if (!xdr_nfs_fh3(xdrs, &objp->handle))
97927242a7cSthurlow 				return (FALSE);
98027242a7cSthurlow 			break;
98127242a7cSthurlow 		}
98227242a7cSthurlow 		return (TRUE);
9837c478bd9Sstevel@tonic-gate 	case FALSE:
9847c478bd9Sstevel@tonic-gate 		return (TRUE);
9857c478bd9Sstevel@tonic-gate 	default:
9867c478bd9Sstevel@tonic-gate 		return (FALSE);
9877c478bd9Sstevel@tonic-gate 	}
9887c478bd9Sstevel@tonic-gate }
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate static bool_t
9917c478bd9Sstevel@tonic-gate xdr_sattr3(XDR *xdrs, sattr3 *objp)
9927c478bd9Sstevel@tonic-gate {
9937c478bd9Sstevel@tonic-gate 	/* set_mode3 */
9947c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->mode.set_it))
9957c478bd9Sstevel@tonic-gate 		return (FALSE);
9967c478bd9Sstevel@tonic-gate 	if (objp->mode.set_it)
9977c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->mode.mode))
9987c478bd9Sstevel@tonic-gate 			return (FALSE);
9997c478bd9Sstevel@tonic-gate 	/* set_uid3 */
10007c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->uid.set_it))
10017c478bd9Sstevel@tonic-gate 		return (FALSE);
10027c478bd9Sstevel@tonic-gate 	if (objp->uid.set_it)
10037c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->uid.uid))
10047c478bd9Sstevel@tonic-gate 			return (FALSE);
10057c478bd9Sstevel@tonic-gate 	/* set_gid3 */
10067c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->gid.set_it))
10077c478bd9Sstevel@tonic-gate 		return (FALSE);
10087c478bd9Sstevel@tonic-gate 	if (objp->gid.set_it)
10097c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->gid.gid))
10107c478bd9Sstevel@tonic-gate 			return (FALSE);
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate 	/* set_size3 */
10137c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->size.set_it))
10147c478bd9Sstevel@tonic-gate 		return (FALSE);
10157c478bd9Sstevel@tonic-gate 	if (objp->size.set_it)
10167c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, &objp->size.size))
10177c478bd9Sstevel@tonic-gate 			return (FALSE);
10187c478bd9Sstevel@tonic-gate 
10197c478bd9Sstevel@tonic-gate 	/* set_atime */
10207c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->atime.set_it))
10217c478bd9Sstevel@tonic-gate 		return (FALSE);
10227c478bd9Sstevel@tonic-gate 	if (objp->atime.set_it == SET_TO_CLIENT_TIME) {
10237c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->atime.atime.seconds))
10247c478bd9Sstevel@tonic-gate 			return (FALSE);
10257c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->atime.atime.nseconds))
10267c478bd9Sstevel@tonic-gate 			return (FALSE);
10277c478bd9Sstevel@tonic-gate 	}
10287c478bd9Sstevel@tonic-gate 
10297c478bd9Sstevel@tonic-gate 	/* set_mtime */
10307c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->mtime.set_it))
10317c478bd9Sstevel@tonic-gate 		return (FALSE);
10327c478bd9Sstevel@tonic-gate 	if (objp->mtime.set_it == SET_TO_CLIENT_TIME) {
10337c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->mtime.mtime.seconds))
10347c478bd9Sstevel@tonic-gate 			return (FALSE);
10357c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->mtime.mtime.nseconds))
10367c478bd9Sstevel@tonic-gate 			return (FALSE);
10377c478bd9Sstevel@tonic-gate 	}
10387c478bd9Sstevel@tonic-gate 
10397c478bd9Sstevel@tonic-gate 	return (TRUE);
10407c478bd9Sstevel@tonic-gate }
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate bool_t
10437c478bd9Sstevel@tonic-gate xdr_GETATTR3res(XDR *xdrs, GETATTR3res *objp)
10447c478bd9Sstevel@tonic-gate {
10457c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
10467c478bd9Sstevel@tonic-gate 		return (FALSE);
10477c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
10487c478bd9Sstevel@tonic-gate 		return (TRUE);
10497c478bd9Sstevel@tonic-gate 	/* xdr_GETATTR3resok */
10507c478bd9Sstevel@tonic-gate 	return (xdr_fattr3(xdrs, &objp->resok.obj_attributes));
10517c478bd9Sstevel@tonic-gate }
10527c478bd9Sstevel@tonic-gate 
10537c478bd9Sstevel@tonic-gate bool_t
10547c478bd9Sstevel@tonic-gate xdr_GETATTR3vres(XDR *xdrs, GETATTR3vres *objp)
10557c478bd9Sstevel@tonic-gate {
10567c478bd9Sstevel@tonic-gate 	/*
10577c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
10587c478bd9Sstevel@tonic-gate 	 */
10597c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
10607c478bd9Sstevel@tonic-gate 		return (TRUE);
10617c478bd9Sstevel@tonic-gate 
10627c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
10637c478bd9Sstevel@tonic-gate 		return (FALSE);
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
10667c478bd9Sstevel@tonic-gate 		return (FALSE);
10677c478bd9Sstevel@tonic-gate 
10687c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
10697c478bd9Sstevel@tonic-gate 		return (TRUE);
10707c478bd9Sstevel@tonic-gate 
10717c478bd9Sstevel@tonic-gate 	return (xdr_fattr3_to_vattr(xdrs, &objp->fres));
10727c478bd9Sstevel@tonic-gate }
10737c478bd9Sstevel@tonic-gate 
10747c478bd9Sstevel@tonic-gate 
10757c478bd9Sstevel@tonic-gate bool_t
10767c478bd9Sstevel@tonic-gate xdr_SETATTR3args(XDR *xdrs, SETATTR3args *objp)
10777c478bd9Sstevel@tonic-gate {
107827242a7cSthurlow 	switch (xdrs->x_op) {
107927242a7cSthurlow 	case XDR_FREE:
108027242a7cSthurlow 	case XDR_ENCODE:
10817c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, &objp->object))
10827c478bd9Sstevel@tonic-gate 			return (FALSE);
108327242a7cSthurlow 		break;
108427242a7cSthurlow 	case XDR_DECODE:
108527242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->object))
108627242a7cSthurlow 			return (FALSE);
108727242a7cSthurlow 		break;
108827242a7cSthurlow 	}
10897c478bd9Sstevel@tonic-gate 	if (!xdr_sattr3(xdrs, &objp->new_attributes))
10907c478bd9Sstevel@tonic-gate 		return (FALSE);
10917c478bd9Sstevel@tonic-gate 
10927c478bd9Sstevel@tonic-gate 	/* sattrguard3 */
10937c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->guard.check))
10947c478bd9Sstevel@tonic-gate 		return (FALSE);
10957c478bd9Sstevel@tonic-gate 	switch (objp->guard.check) {
10967c478bd9Sstevel@tonic-gate 	case TRUE:
10977c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->guard.obj_ctime.seconds))
10987c478bd9Sstevel@tonic-gate 			return (FALSE);
10997c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->guard.obj_ctime.nseconds));
11007c478bd9Sstevel@tonic-gate 	case FALSE:
11017c478bd9Sstevel@tonic-gate 		return (TRUE);
11027c478bd9Sstevel@tonic-gate 	default:
11037c478bd9Sstevel@tonic-gate 		return (FALSE);
11047c478bd9Sstevel@tonic-gate 	}
11057c478bd9Sstevel@tonic-gate }
11067c478bd9Sstevel@tonic-gate 
11077c478bd9Sstevel@tonic-gate bool_t
11087c478bd9Sstevel@tonic-gate xdr_SETATTR3res(XDR *xdrs, SETATTR3res *objp)
11097c478bd9Sstevel@tonic-gate {
11107c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
11117c478bd9Sstevel@tonic-gate 		return (FALSE);
11127c478bd9Sstevel@tonic-gate 	switch (objp->status) {
11137c478bd9Sstevel@tonic-gate 	case NFS3_OK:
11147c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resok.obj_wcc));
11157c478bd9Sstevel@tonic-gate 	default:
11167c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.obj_wcc));
11177c478bd9Sstevel@tonic-gate 	}
11187c478bd9Sstevel@tonic-gate }
11197c478bd9Sstevel@tonic-gate 
11207c478bd9Sstevel@tonic-gate bool_t
11217c478bd9Sstevel@tonic-gate xdr_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp)
11227c478bd9Sstevel@tonic-gate {
11237c478bd9Sstevel@tonic-gate 	LOOKUP3resok *resokp;
11247c478bd9Sstevel@tonic-gate 
11257c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
11267c478bd9Sstevel@tonic-gate 		return (FALSE);
11277c478bd9Sstevel@tonic-gate 
11287c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
11297c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
11307c478bd9Sstevel@tonic-gate 
11317c478bd9Sstevel@tonic-gate 	/* xdr_LOOKUP3resok */
11327c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
113327242a7cSthurlow 	switch (xdrs->x_op) {
113427242a7cSthurlow 	case XDR_ENCODE:
113527242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &resokp->object))
113627242a7cSthurlow 			return (FALSE);
113727242a7cSthurlow 		break;
113827242a7cSthurlow 	case XDR_FREE:
113927242a7cSthurlow 	case XDR_DECODE:
11407c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, &resokp->object))
11417c478bd9Sstevel@tonic-gate 			return (FALSE);
114227242a7cSthurlow 		break;
114327242a7cSthurlow 	}
11447c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
11457c478bd9Sstevel@tonic-gate 		return (FALSE);
11467c478bd9Sstevel@tonic-gate 	return (xdr_post_op_attr(xdrs, &resokp->dir_attributes));
11477c478bd9Sstevel@tonic-gate }
11487c478bd9Sstevel@tonic-gate 
11497c478bd9Sstevel@tonic-gate bool_t
11507c478bd9Sstevel@tonic-gate xdr_LOOKUP3vres(XDR *xdrs, LOOKUP3vres *objp)
11517c478bd9Sstevel@tonic-gate {
11527c478bd9Sstevel@tonic-gate 	/*
11537c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
11547c478bd9Sstevel@tonic-gate 	 */
11557c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
11567c478bd9Sstevel@tonic-gate 		return (TRUE);
11577c478bd9Sstevel@tonic-gate 
11587c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
11597c478bd9Sstevel@tonic-gate 		return (FALSE);
11607c478bd9Sstevel@tonic-gate 
11617c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
11627c478bd9Sstevel@tonic-gate 		return (FALSE);
11637c478bd9Sstevel@tonic-gate 
11647c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
11657c478bd9Sstevel@tonic-gate 		return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
11667c478bd9Sstevel@tonic-gate 
11677c478bd9Sstevel@tonic-gate 	if (!xdr_nfs_fh3(xdrs, &objp->object))
11687c478bd9Sstevel@tonic-gate 		return (FALSE);
11697c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_vattr(xdrs, &objp->obj_attributes))
11707c478bd9Sstevel@tonic-gate 		return (FALSE);
11717c478bd9Sstevel@tonic-gate 	return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
11727c478bd9Sstevel@tonic-gate }
11737c478bd9Sstevel@tonic-gate 
11747c478bd9Sstevel@tonic-gate bool_t
11757c478bd9Sstevel@tonic-gate xdr_ACCESS3args(XDR *xdrs, ACCESS3args *objp)
11767c478bd9Sstevel@tonic-gate {
117727242a7cSthurlow 	switch (xdrs->x_op) {
117827242a7cSthurlow 	case XDR_FREE:
117927242a7cSthurlow 	case XDR_ENCODE:
11807c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, &objp->object))
11817c478bd9Sstevel@tonic-gate 			return (FALSE);
118227242a7cSthurlow 		break;
118327242a7cSthurlow 	case XDR_DECODE:
118427242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->object))
118527242a7cSthurlow 			return (FALSE);
118627242a7cSthurlow 		break;
118727242a7cSthurlow 	}
11887c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->access));
11897c478bd9Sstevel@tonic-gate }
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate 
11927c478bd9Sstevel@tonic-gate bool_t
11937c478bd9Sstevel@tonic-gate xdr_ACCESS3res(XDR *xdrs, ACCESS3res *objp)
11947c478bd9Sstevel@tonic-gate {
11957c478bd9Sstevel@tonic-gate 	ACCESS3resok *resokp;
11967c478bd9Sstevel@tonic-gate 
11977c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
11987c478bd9Sstevel@tonic-gate 		return (FALSE);
11997c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
12007c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
12017c478bd9Sstevel@tonic-gate 
12027c478bd9Sstevel@tonic-gate 	/* xdr_ACCESS3resok */
12037c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
12047c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
12057c478bd9Sstevel@tonic-gate 		return (FALSE);
12067c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &resokp->access));
12077c478bd9Sstevel@tonic-gate }
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate bool_t
12100a701b1eSRobert Gordon xdr_READLINK3args(XDR *xdrs,  READLINK3args *objp)
12110a701b1eSRobert Gordon {
12120a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
12130a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
12140a701b1eSRobert Gordon 
12150a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
12160a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
12170a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
12180a701b1eSRobert Gordon 		rci.rci_len = MAXPATHLEN;
12190a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
12200a701b1eSRobert Gordon 	}
12210a701b1eSRobert Gordon 	if (!xdr_nfs_fh3(xdrs, (nfs_fh3 *)objp))
12220a701b1eSRobert Gordon 		return (FALSE);
12230a701b1eSRobert Gordon 	return (TRUE);
12240a701b1eSRobert Gordon }
12250a701b1eSRobert Gordon 
12260a701b1eSRobert Gordon bool_t
12277c478bd9Sstevel@tonic-gate xdr_READLINK3res(XDR *xdrs, READLINK3res *objp)
12287c478bd9Sstevel@tonic-gate {
12297c478bd9Sstevel@tonic-gate 
12307c478bd9Sstevel@tonic-gate 	READLINK3resok *resokp;
12317c478bd9Sstevel@tonic-gate 
12327c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
12337c478bd9Sstevel@tonic-gate 		return (FALSE);
12347c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
12357c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs,
12367c478bd9Sstevel@tonic-gate 		    &objp->resfail.symlink_attributes));
12377c478bd9Sstevel@tonic-gate 
12387c478bd9Sstevel@tonic-gate 	/* xdr_READLINK3resok */
12397c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
12407c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->symlink_attributes))
12417c478bd9Sstevel@tonic-gate 		return (FALSE);
12427c478bd9Sstevel@tonic-gate 	return (xdr_string3(xdrs, &resokp->data, MAXPATHLEN));
12437c478bd9Sstevel@tonic-gate }
12447c478bd9Sstevel@tonic-gate 
12457c478bd9Sstevel@tonic-gate bool_t
12467c478bd9Sstevel@tonic-gate xdr_READ3args(XDR *xdrs, READ3args *objp)
12477c478bd9Sstevel@tonic-gate {
12480a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
12490a701b1eSRobert Gordon 	rdma_wlist_conn_info_t rwci;
12500a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
12510a701b1eSRobert Gordon 
125227242a7cSthurlow 	switch (xdrs->x_op) {
125327242a7cSthurlow 	case XDR_FREE:
125427242a7cSthurlow 	case XDR_ENCODE:
12557c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, &objp->file))
12567c478bd9Sstevel@tonic-gate 			return (FALSE);
125727242a7cSthurlow 		break;
125827242a7cSthurlow 	case XDR_DECODE:
125927242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
126027242a7cSthurlow 			return (FALSE);
126127242a7cSthurlow 		break;
126227242a7cSthurlow 	}
12637c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->offset))
12647c478bd9Sstevel@tonic-gate 		return (FALSE);
12650a701b1eSRobert Gordon 	if (!xdr_u_int(xdrs, &objp->count))
12660a701b1eSRobert Gordon 		return (FALSE);
12670a701b1eSRobert Gordon 
12680a701b1eSRobert Gordon 	DTRACE_PROBE1(xdr__i__read3_buf_len, int, objp->count);
12690a701b1eSRobert Gordon 
12700a701b1eSRobert Gordon 	objp->wlist = NULL;
12710a701b1eSRobert Gordon 
12720a701b1eSRobert Gordon 	/* if xdrrdma_sizeof in progress, then store the size */
12730a701b1eSRobert Gordon 	if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
12740a701b1eSRobert Gordon 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
12750a701b1eSRobert Gordon 		rci.rci_len = objp->count;
12760a701b1eSRobert Gordon 		(void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
12770a701b1eSRobert Gordon 	}
12780a701b1eSRobert Gordon 
12790a701b1eSRobert Gordon 	if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
12800a701b1eSRobert Gordon 		return (TRUE);
12810a701b1eSRobert Gordon 
12820a701b1eSRobert Gordon 	if (xdrs->x_op == XDR_ENCODE) {
12830a701b1eSRobert Gordon 
12840a701b1eSRobert Gordon 		if (objp->res_uiop != NULL) {
12850a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_UIO_CHUNK;
12860a701b1eSRobert Gordon 			rci.rci_a.rci_uiop = objp->res_uiop;
12870a701b1eSRobert Gordon 			rci.rci_len = objp->count;
12880a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
12890a701b1eSRobert Gordon 		} else {
12900a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_ADDR_CHUNK;
12910a701b1eSRobert Gordon 			rci.rci_a.rci_addr = objp->res_data_val_alt;
12920a701b1eSRobert Gordon 			rci.rci_len = objp->count;
12930a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
12940a701b1eSRobert Gordon 		}
12950a701b1eSRobert Gordon 
12960a701b1eSRobert Gordon 		return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
12970a701b1eSRobert Gordon 	}
12980a701b1eSRobert Gordon 
12990a701b1eSRobert Gordon 	/* XDR_DECODE case */
13000a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
13010a701b1eSRobert Gordon 	objp->wlist = rwci.rwci_wlist;
13020a701b1eSRobert Gordon 	objp->conn = rwci.rwci_conn;
13030a701b1eSRobert Gordon 
13040a701b1eSRobert Gordon 	return (TRUE);
13057c478bd9Sstevel@tonic-gate }
13067c478bd9Sstevel@tonic-gate 
13077c478bd9Sstevel@tonic-gate bool_t
13087c478bd9Sstevel@tonic-gate xdr_READ3res(XDR *xdrs, READ3res *objp)
13097c478bd9Sstevel@tonic-gate {
13107c478bd9Sstevel@tonic-gate 	READ3resok *resokp;
13117c478bd9Sstevel@tonic-gate 	bool_t ret;
13127c478bd9Sstevel@tonic-gate 	mblk_t *mp;
13137c478bd9Sstevel@tonic-gate 
13147c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
13157c478bd9Sstevel@tonic-gate 		return (FALSE);
13167c478bd9Sstevel@tonic-gate 
13177c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
13187c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.file_attributes));
13197c478bd9Sstevel@tonic-gate 
13207c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
13217c478bd9Sstevel@tonic-gate 
13227c478bd9Sstevel@tonic-gate 	if (xdr_post_op_attr(xdrs, &resokp->file_attributes) == FALSE ||
13237c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &resokp->count) == FALSE ||
13247c478bd9Sstevel@tonic-gate 	    xdr_bool(xdrs, &resokp->eof) == FALSE) {
13257c478bd9Sstevel@tonic-gate 		return (FALSE);
13267c478bd9Sstevel@tonic-gate 	}
13277c478bd9Sstevel@tonic-gate 
13287c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
13297c478bd9Sstevel@tonic-gate 
13307c478bd9Sstevel@tonic-gate 		mp = resokp->data.mp;
1331*e36d7b11SSebastien Roy 		if (mp != NULL) {
1332*e36d7b11SSebastien Roy 			if (xdrs->x_ops == &xdrmblk_ops) {
1333*e36d7b11SSebastien Roy 				if (xdrmblk_putmblk(xdrs, mp, resokp->count)) {
13347c478bd9Sstevel@tonic-gate 					resokp->data.mp = NULL;
13357c478bd9Sstevel@tonic-gate 					return (TRUE);
1336*e36d7b11SSebastien Roy 				} else {
1337*e36d7b11SSebastien Roy 					return (FALSE);
13387c478bd9Sstevel@tonic-gate 				}
1339*e36d7b11SSebastien Roy 			} else if (mp->b_cont != NULL) {
1340*e36d7b11SSebastien Roy 				/*
1341*e36d7b11SSebastien Roy 				 * We have read results in an mblk chain, but
1342*e36d7b11SSebastien Roy 				 * the encoding operations don't handle mblks
1343*e36d7b11SSebastien Roy 				 * (they'll operate on data.data_val rather
1344*e36d7b11SSebastien Roy 				 * than data.mp).  Because data_val can only
1345*e36d7b11SSebastien Roy 				 * point at a single data buffer, we need to
1346*e36d7b11SSebastien Roy 				 * pullup the read results into a single data
1347*e36d7b11SSebastien Roy 				 * block and reset data_val to point to it.
1348*e36d7b11SSebastien Roy 				 *
1349*e36d7b11SSebastien Roy 				 * This happens with RPC GSS where the wrapping
1350*e36d7b11SSebastien Roy 				 * function does XDR serialization into a
1351*e36d7b11SSebastien Roy 				 * temporary buffer prior to applying GSS.
1352*e36d7b11SSebastien Roy 				 * Because we're not in a performance sensitive
1353*e36d7b11SSebastien Roy 				 * path, the pullupmsg() here shouldn't hurt us
1354*e36d7b11SSebastien Roy 				 * too badly.
1355*e36d7b11SSebastien Roy 				 */
1356*e36d7b11SSebastien Roy 				if (pullupmsg(mp, -1) == 0)
1357*e36d7b11SSebastien Roy 					return (FALSE);
1358*e36d7b11SSebastien Roy 				resokp->data.data_val = (caddr_t)mp->b_rptr;
1359*e36d7b11SSebastien Roy 			}
1360*e36d7b11SSebastien Roy 		} else {
13610a701b1eSRobert Gordon 			if (xdr_u_int(xdrs, &resokp->count) == FALSE) {
13620a701b1eSRobert Gordon 				return (FALSE);
13630a701b1eSRobert Gordon 			}
13640a701b1eSRobert Gordon 			/*
13650a701b1eSRobert Gordon 			 * If read data sent by wlist (RDMA_WRITE), don't do
13660a701b1eSRobert Gordon 			 * xdr_bytes() below.   RDMA_WRITE transfers the data.
13670a701b1eSRobert Gordon 			 * Note: this is encode-only because the client code
13680a701b1eSRobert Gordon 			 * uses xdr_READ3vres/xdr_READ3uiores to decode results.
13690a701b1eSRobert Gordon 			 */
13700a701b1eSRobert Gordon 			if (resokp->wlist) {
13710a701b1eSRobert Gordon 				if (resokp->count != 0) {
13720a701b1eSRobert Gordon 					return (xdrrdma_send_read_data(
1373f837ee4aSSiddheshwar Mahesh 					    xdrs, resokp->count,
1374f837ee4aSSiddheshwar Mahesh 					    resokp->wlist));
13750a701b1eSRobert Gordon 				}
13760a701b1eSRobert Gordon 				return (TRUE);
13770a701b1eSRobert Gordon 			}
13787c478bd9Sstevel@tonic-gate 		}
13797c478bd9Sstevel@tonic-gate 		/*
13807c478bd9Sstevel@tonic-gate 		 * Fall thru for the xdr_bytes()
13817c478bd9Sstevel@tonic-gate 		 *
13827c478bd9Sstevel@tonic-gate 		 * note: the mblk will be freed in
13837c478bd9Sstevel@tonic-gate 		 * rfs3_read_free.
13847c478bd9Sstevel@tonic-gate 		 */
13857c478bd9Sstevel@tonic-gate 	}
13867c478bd9Sstevel@tonic-gate 
13870a701b1eSRobert Gordon 	/* no RDMA_WRITE transfer -- send data inline */
13880a701b1eSRobert Gordon 
13897c478bd9Sstevel@tonic-gate 	ret = xdr_bytes(xdrs, (char **)&resokp->data.data_val,
13907c478bd9Sstevel@tonic-gate 	    &resokp->data.data_len, nfs3tsize());
13917c478bd9Sstevel@tonic-gate 
13927c478bd9Sstevel@tonic-gate 	return (ret);
13937c478bd9Sstevel@tonic-gate }
13947c478bd9Sstevel@tonic-gate 
13957c478bd9Sstevel@tonic-gate bool_t
13967c478bd9Sstevel@tonic-gate xdr_READ3vres(XDR *xdrs, READ3vres *objp)
13977c478bd9Sstevel@tonic-gate {
13980a701b1eSRobert Gordon 	count3 ocount;
13997c478bd9Sstevel@tonic-gate 	/*
14007c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
14017c478bd9Sstevel@tonic-gate 	 */
14027c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
14037c478bd9Sstevel@tonic-gate 		return (TRUE);
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
14067c478bd9Sstevel@tonic-gate 		return (FALSE);
14077c478bd9Sstevel@tonic-gate 
14087c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
14097c478bd9Sstevel@tonic-gate 		return (FALSE);
14107c478bd9Sstevel@tonic-gate 
14117c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_vattr(xdrs, &objp->pov))
14127c478bd9Sstevel@tonic-gate 		return (FALSE);
14137c478bd9Sstevel@tonic-gate 
14147c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
14157c478bd9Sstevel@tonic-gate 		return (TRUE);
14167c478bd9Sstevel@tonic-gate 
14177c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->count))
14187c478bd9Sstevel@tonic-gate 		return (FALSE);
14197c478bd9Sstevel@tonic-gate 
14207c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->eof))
14217c478bd9Sstevel@tonic-gate 		return (FALSE);
14227c478bd9Sstevel@tonic-gate 
14230a701b1eSRobert Gordon 	/*
14240a701b1eSRobert Gordon 	 * If read data received via RDMA_WRITE, don't do xdr_bytes().
14250a701b1eSRobert Gordon 	 * RDMA_WRITE already moved the data so decode length of RDMA_WRITE.
14260a701b1eSRobert Gordon 	 */
14270a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops) {
14280a701b1eSRobert Gordon 		struct clist *cl;
14290a701b1eSRobert Gordon 
14300a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
14310a701b1eSRobert Gordon 
14320a701b1eSRobert Gordon 		if (cl) {
14330a701b1eSRobert Gordon 			if (!xdr_u_int(xdrs, &ocount)) {
14340a701b1eSRobert Gordon 				return (FALSE);
14350a701b1eSRobert Gordon 			}
14360a701b1eSRobert Gordon 			if (ocount != objp->count) {
14370a701b1eSRobert Gordon 				DTRACE_PROBE2(xdr__e__read3vres_fail,
14380a701b1eSRobert Gordon 				    int, ocount, int, objp->count);
1439f837ee4aSSiddheshwar Mahesh 				objp->wlist = NULL;
14400a701b1eSRobert Gordon 				return (FALSE);
14410a701b1eSRobert Gordon 			}
14420a701b1eSRobert Gordon 
1443f837ee4aSSiddheshwar Mahesh 			objp->wlist_len = clist_len(cl);
1444f837ee4aSSiddheshwar Mahesh 			objp->data.data_len = ocount;
1445f837ee4aSSiddheshwar Mahesh 
1446f837ee4aSSiddheshwar Mahesh 			if (objp->wlist_len !=
1447f837ee4aSSiddheshwar Mahesh 			    roundup(objp->data.data_len, BYTES_PER_XDR_UNIT)) {
1448f837ee4aSSiddheshwar Mahesh 				DTRACE_PROBE2(
1449f837ee4aSSiddheshwar Mahesh 				    xdr__e__read3vres_fail,
1450f837ee4aSSiddheshwar Mahesh 				    int, ocount,
1451f837ee4aSSiddheshwar Mahesh 				    int, objp->data.data_len);
1452f837ee4aSSiddheshwar Mahesh 				objp->wlist = NULL;
1453f837ee4aSSiddheshwar Mahesh 				return (FALSE);
1454f837ee4aSSiddheshwar Mahesh 			}
14550a701b1eSRobert Gordon 			return (TRUE);
14560a701b1eSRobert Gordon 		}
14570a701b1eSRobert Gordon 	}
14580a701b1eSRobert Gordon 
14597c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
14607c478bd9Sstevel@tonic-gate 	    &objp->data.data_len, nfs3tsize()));
14617c478bd9Sstevel@tonic-gate }
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate bool_t
14647c478bd9Sstevel@tonic-gate xdr_READ3uiores(XDR *xdrs, READ3uiores *objp)
14657c478bd9Sstevel@tonic-gate {
14660a701b1eSRobert Gordon 	count3 ocount;
14677c478bd9Sstevel@tonic-gate 	bool_t attributes;
14687c478bd9Sstevel@tonic-gate 	mblk_t *mp;
14697c478bd9Sstevel@tonic-gate 	size_t n;
14707c478bd9Sstevel@tonic-gate 	int error;
14717c478bd9Sstevel@tonic-gate 	int size = (int)objp->size;
14727c478bd9Sstevel@tonic-gate 	struct uio *uiop = objp->uiop;
14737c478bd9Sstevel@tonic-gate 	int32_t fattr3_len = NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
14747c478bd9Sstevel@tonic-gate 	int32_t *ptr;
14757c478bd9Sstevel@tonic-gate 
14767c478bd9Sstevel@tonic-gate 	/*
14777c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
14787c478bd9Sstevel@tonic-gate 	 */
14797c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
14807c478bd9Sstevel@tonic-gate 		return (TRUE);
14817c478bd9Sstevel@tonic-gate 
14827c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
14837c478bd9Sstevel@tonic-gate 		return (FALSE);
14847c478bd9Sstevel@tonic-gate 
14857c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
14867c478bd9Sstevel@tonic-gate 		return (FALSE);
14877c478bd9Sstevel@tonic-gate 
14887c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&attributes))
14897c478bd9Sstevel@tonic-gate 		return (FALSE);
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate 	/*
14927c478bd9Sstevel@tonic-gate 	 * For directio we just skip over attributes if present
14937c478bd9Sstevel@tonic-gate 	 */
14947c478bd9Sstevel@tonic-gate 	switch (attributes) {
14957c478bd9Sstevel@tonic-gate 	case TRUE:
14967c478bd9Sstevel@tonic-gate 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fattr3_len))
14977c478bd9Sstevel@tonic-gate 			return (FALSE);
14987c478bd9Sstevel@tonic-gate 		break;
14997c478bd9Sstevel@tonic-gate 	case FALSE:
15007c478bd9Sstevel@tonic-gate 		break;
15017c478bd9Sstevel@tonic-gate 	default:
15027c478bd9Sstevel@tonic-gate 		return (FALSE);
15037c478bd9Sstevel@tonic-gate 	}
15047c478bd9Sstevel@tonic-gate 
15057c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
15067c478bd9Sstevel@tonic-gate 		return (TRUE);
15077c478bd9Sstevel@tonic-gate 
15087c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->count))
15097c478bd9Sstevel@tonic-gate 		return (FALSE);
15107c478bd9Sstevel@tonic-gate 
15117c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
15127c478bd9Sstevel@tonic-gate 		return (FALSE);
15137c478bd9Sstevel@tonic-gate 
15147c478bd9Sstevel@tonic-gate 	if (xdrs->x_ops == &xdrmblk_ops) {
15157c478bd9Sstevel@tonic-gate 		if (!xdrmblk_getmblk(xdrs, &mp, &objp->size))
15167c478bd9Sstevel@tonic-gate 			return (FALSE);
15177c478bd9Sstevel@tonic-gate 
15187c478bd9Sstevel@tonic-gate 		if (objp->size == 0)
15197c478bd9Sstevel@tonic-gate 			return (TRUE);
15207c478bd9Sstevel@tonic-gate 
15217c478bd9Sstevel@tonic-gate 		if (objp->size > size)
15227c478bd9Sstevel@tonic-gate 			return (FALSE);
15237c478bd9Sstevel@tonic-gate 
15247c478bd9Sstevel@tonic-gate 		size = (int)objp->size;
15257c478bd9Sstevel@tonic-gate 		do {
15267c478bd9Sstevel@tonic-gate 			n = MIN(size, mp->b_wptr - mp->b_rptr);
15277c478bd9Sstevel@tonic-gate 			if ((n = MIN(uiop->uio_resid, n)) != 0) {
15287c478bd9Sstevel@tonic-gate 
15297c478bd9Sstevel@tonic-gate 				error = uiomove((char *)mp->b_rptr, n, UIO_READ,
15307c478bd9Sstevel@tonic-gate 				    uiop);
15317c478bd9Sstevel@tonic-gate 				if (error)
15327c478bd9Sstevel@tonic-gate 					return (FALSE);
15337c478bd9Sstevel@tonic-gate 				mp->b_rptr += n;
15347c478bd9Sstevel@tonic-gate 				size -= n;
15357c478bd9Sstevel@tonic-gate 			}
15367c478bd9Sstevel@tonic-gate 
15377c478bd9Sstevel@tonic-gate 			while (mp && (mp->b_rptr >= mp->b_wptr))
15387c478bd9Sstevel@tonic-gate 				mp = mp->b_cont;
15397c478bd9Sstevel@tonic-gate 		} while (mp && size > 0 && uiop->uio_resid > 0);
15407c478bd9Sstevel@tonic-gate 
15417c478bd9Sstevel@tonic-gate 		return (TRUE);
15427c478bd9Sstevel@tonic-gate 	}
15437c478bd9Sstevel@tonic-gate 
15440a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops) {
15450a701b1eSRobert Gordon 		struct clist *cl;
15460a701b1eSRobert Gordon 
15470a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
15480a701b1eSRobert Gordon 
15490a701b1eSRobert Gordon 		objp->wlist = cl;
15500a701b1eSRobert Gordon 
15510a701b1eSRobert Gordon 		if (objp->wlist) {
15520a701b1eSRobert Gordon 			if (!xdr_u_int(xdrs, &ocount)) {
15530a701b1eSRobert Gordon 				objp->wlist = NULL;
15540a701b1eSRobert Gordon 				return (FALSE);
15550a701b1eSRobert Gordon 			}
15560a701b1eSRobert Gordon 
15570a701b1eSRobert Gordon 			if (ocount != objp->count) {
15580a701b1eSRobert Gordon 				DTRACE_PROBE2(xdr__e__read3uiores_fail,
15590a701b1eSRobert Gordon 				    int, ocount, int, objp->count);
15600a701b1eSRobert Gordon 				objp->wlist = NULL;
15610a701b1eSRobert Gordon 				return (FALSE);
15620a701b1eSRobert Gordon 			}
15630a701b1eSRobert Gordon 
1564f837ee4aSSiddheshwar Mahesh 			objp->wlist_len = clist_len(cl);
15650a701b1eSRobert Gordon 
15660a701b1eSRobert Gordon 			uiop->uio_resid -= objp->count;
15670a701b1eSRobert Gordon 			uiop->uio_iov->iov_len -= objp->count;
15680a701b1eSRobert Gordon 			uiop->uio_iov->iov_base += objp->count;
15690a701b1eSRobert Gordon 			uiop->uio_loffset += objp->count;
15700a701b1eSRobert Gordon 
15717c478bd9Sstevel@tonic-gate 			/*
15720a701b1eSRobert Gordon 			 * XXX: Assume 1 iov, needs to be changed.
15730a701b1eSRobert Gordon 			 */
1574f837ee4aSSiddheshwar Mahesh 			objp->size = objp->count;
15750a701b1eSRobert Gordon 
15760a701b1eSRobert Gordon 			return (TRUE);
15770a701b1eSRobert Gordon 		}
15780a701b1eSRobert Gordon 	}
15790a701b1eSRobert Gordon 
15800a701b1eSRobert Gordon 	/*
15810a701b1eSRobert Gordon 	 * This isn't an xdrmblk stream nor RDMA.
15820a701b1eSRobert Gordon 	 * Handle the likely case that it can be
15830a701b1eSRobert Gordon 	 * inlined (ex. xdrmem).
15847c478bd9Sstevel@tonic-gate 	 */
15857c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->size))
15867c478bd9Sstevel@tonic-gate 		return (FALSE);
15877c478bd9Sstevel@tonic-gate 
15887c478bd9Sstevel@tonic-gate 	if (objp->size == 0)
15897c478bd9Sstevel@tonic-gate 		return (TRUE);
15907c478bd9Sstevel@tonic-gate 
15917c478bd9Sstevel@tonic-gate 	if (objp->size > size)
15927c478bd9Sstevel@tonic-gate 		return (FALSE);
15937c478bd9Sstevel@tonic-gate 
15947c478bd9Sstevel@tonic-gate 	size = (int)objp->size;
15957c478bd9Sstevel@tonic-gate 	if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
15967c478bd9Sstevel@tonic-gate 		return (uiomove(ptr, size, UIO_READ, uiop) ? FALSE : TRUE);
15977c478bd9Sstevel@tonic-gate 
15987c478bd9Sstevel@tonic-gate 	/*
15997c478bd9Sstevel@tonic-gate 	 * Handle some other (unlikely) stream type that will need a copy.
16007c478bd9Sstevel@tonic-gate 	 */
16017c478bd9Sstevel@tonic-gate 	if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
16027c478bd9Sstevel@tonic-gate 		return (FALSE);
16037c478bd9Sstevel@tonic-gate 
16047c478bd9Sstevel@tonic-gate 	if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
16057c478bd9Sstevel@tonic-gate 		kmem_free(ptr, size);
16067c478bd9Sstevel@tonic-gate 		return (FALSE);
16077c478bd9Sstevel@tonic-gate 	}
16087c478bd9Sstevel@tonic-gate 	error = uiomove(ptr, size, UIO_READ, uiop);
16097c478bd9Sstevel@tonic-gate 	kmem_free(ptr, size);
16107c478bd9Sstevel@tonic-gate 
16117c478bd9Sstevel@tonic-gate 	return (error ? FALSE : TRUE);
16127c478bd9Sstevel@tonic-gate }
16137c478bd9Sstevel@tonic-gate 
16147c478bd9Sstevel@tonic-gate bool_t
16157c478bd9Sstevel@tonic-gate xdr_WRITE3args(XDR *xdrs, WRITE3args *objp)
16167c478bd9Sstevel@tonic-gate {
161727242a7cSthurlow 	switch (xdrs->x_op) {
161827242a7cSthurlow 	case XDR_FREE:
161927242a7cSthurlow 	case XDR_ENCODE:
16207c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, &objp->file))
16217c478bd9Sstevel@tonic-gate 			return (FALSE);
162227242a7cSthurlow 		break;
162327242a7cSthurlow 	case XDR_DECODE:
162427242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
162527242a7cSthurlow 			return (FALSE);
162627242a7cSthurlow 		break;
162727242a7cSthurlow 	}
16287c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->offset))
16297c478bd9Sstevel@tonic-gate 		return (FALSE);
16307c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->count))
16317c478bd9Sstevel@tonic-gate 		return (FALSE);
16327c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->stable))
16337c478bd9Sstevel@tonic-gate 		return (FALSE);
16347c478bd9Sstevel@tonic-gate 
16357c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
16367c478bd9Sstevel@tonic-gate 		if (xdrs->x_ops == &xdrmblk_ops) {
16377c478bd9Sstevel@tonic-gate 			if (xdrmblk_getmblk(xdrs, &objp->mblk,
16387c478bd9Sstevel@tonic-gate 			    &objp->data.data_len) == TRUE) {
16397c478bd9Sstevel@tonic-gate 				objp->data.data_val = NULL;
16407c478bd9Sstevel@tonic-gate 				return (TRUE);
16417c478bd9Sstevel@tonic-gate 			}
16427c478bd9Sstevel@tonic-gate 		}
16437c478bd9Sstevel@tonic-gate 		objp->mblk = NULL;
16440a701b1eSRobert Gordon 
16450a701b1eSRobert Gordon 		if (xdrs->x_ops == &xdrrdmablk_ops) {
16460a701b1eSRobert Gordon 			if (xdrrdma_getrdmablk(xdrs, &objp->rlist,
16470a701b1eSRobert Gordon 			    &objp->data.data_len,
16480a701b1eSRobert Gordon 			    &objp->conn, nfs3tsize()) == TRUE) {
16490a701b1eSRobert Gordon 				objp->data.data_val = NULL;
16500a701b1eSRobert Gordon 				if (xdrrdma_read_from_client(
1651f837ee4aSSiddheshwar Mahesh 				    objp->rlist,
16520a701b1eSRobert Gordon 				    &objp->conn,
16530a701b1eSRobert Gordon 				    objp->count) == FALSE) {
16540a701b1eSRobert Gordon 					return (FALSE);
16550a701b1eSRobert Gordon 				}
16560a701b1eSRobert Gordon 				return (TRUE);
16570a701b1eSRobert Gordon 			}
16580a701b1eSRobert Gordon 		}
16590a701b1eSRobert Gordon 		objp->rlist = NULL;
16600a701b1eSRobert Gordon 
16617c478bd9Sstevel@tonic-gate 		/* Else fall thru for the xdr_bytes(). */
16627c478bd9Sstevel@tonic-gate 	}
16637c478bd9Sstevel@tonic-gate 
16640a701b1eSRobert Gordon 	if (xdrs->x_op == XDR_FREE) {
16650a701b1eSRobert Gordon 		if (objp->rlist != NULL) {
16660a701b1eSRobert Gordon 			(void) xdrrdma_free_clist(objp->conn, objp->rlist);
16670a701b1eSRobert Gordon 			objp->rlist = NULL;
16680a701b1eSRobert Gordon 			objp->data.data_val = NULL;
16690a701b1eSRobert Gordon 			return (TRUE);
16700a701b1eSRobert Gordon 		}
16710a701b1eSRobert Gordon 	}
16720a701b1eSRobert Gordon 
16730a701b1eSRobert Gordon 	DTRACE_PROBE1(xdr__i__write3_buf_len,
16740a701b1eSRobert Gordon 	    int, objp->data.data_len);
16750a701b1eSRobert Gordon 
16767c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
16777c478bd9Sstevel@tonic-gate 	    &objp->data.data_len, nfs3tsize()));
16787c478bd9Sstevel@tonic-gate }
16797c478bd9Sstevel@tonic-gate 
16807c478bd9Sstevel@tonic-gate bool_t
16817c478bd9Sstevel@tonic-gate xdr_WRITE3res(XDR *xdrs, WRITE3res *objp)
16827c478bd9Sstevel@tonic-gate {
16837c478bd9Sstevel@tonic-gate 	WRITE3resok *resokp;
16847c478bd9Sstevel@tonic-gate 
16857c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
16867c478bd9Sstevel@tonic-gate 		return (FALSE);
16877c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK) /* xdr_WRITE3resfail */
16887c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
16897c478bd9Sstevel@tonic-gate 
16907c478bd9Sstevel@tonic-gate 	/* xdr_WRITE3resok */
16917c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
16927c478bd9Sstevel@tonic-gate 	if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
16937c478bd9Sstevel@tonic-gate 		return (FALSE);
16947c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->count))
16957c478bd9Sstevel@tonic-gate 		return (FALSE);
16967c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&resokp->committed))
16977c478bd9Sstevel@tonic-gate 		return (FALSE);
16987c478bd9Sstevel@tonic-gate 	/*
16997c478bd9Sstevel@tonic-gate 	 * writeverf3 is really an opaque 8 byte
17007c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
17017c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
17027c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
17037c478bd9Sstevel@tonic-gate 	 */
17047c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, &resokp->verf));
17057c478bd9Sstevel@tonic-gate }
17067c478bd9Sstevel@tonic-gate 
17077c478bd9Sstevel@tonic-gate bool_t
17087c478bd9Sstevel@tonic-gate xdr_CREATE3args(XDR *xdrs, CREATE3args *objp)
17097c478bd9Sstevel@tonic-gate {
17107c478bd9Sstevel@tonic-gate 	createhow3 *howp;
17117c478bd9Sstevel@tonic-gate 
17127c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->where))
17137c478bd9Sstevel@tonic-gate 		return (FALSE);
17147c478bd9Sstevel@tonic-gate 
17157c478bd9Sstevel@tonic-gate 	/* xdr_createhow3 */
17167c478bd9Sstevel@tonic-gate 	howp = &objp->how;
17177c478bd9Sstevel@tonic-gate 
17187c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&howp->mode))
17197c478bd9Sstevel@tonic-gate 		return (FALSE);
17207c478bd9Sstevel@tonic-gate 	switch (howp->mode) {
17217c478bd9Sstevel@tonic-gate 	case UNCHECKED:
17227c478bd9Sstevel@tonic-gate 	case GUARDED:
17237c478bd9Sstevel@tonic-gate 		return (xdr_sattr3(xdrs, &howp->createhow3_u.obj_attributes));
17247c478bd9Sstevel@tonic-gate 	case EXCLUSIVE:
17257c478bd9Sstevel@tonic-gate 		/*
17267c478bd9Sstevel@tonic-gate 		 * createverf3 is really an opaque 8 byte
17277c478bd9Sstevel@tonic-gate 		 * quantity, but we will treat it as a
17287c478bd9Sstevel@tonic-gate 		 * hyper for efficiency, the cost of
17297c478bd9Sstevel@tonic-gate 		 * a byteswap here saves bcopys elsewhere
17307c478bd9Sstevel@tonic-gate 		 */
17317c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs, &howp->createhow3_u.verf));
17327c478bd9Sstevel@tonic-gate 	default:
17337c478bd9Sstevel@tonic-gate 		return (FALSE);
17347c478bd9Sstevel@tonic-gate 	}
17357c478bd9Sstevel@tonic-gate }
17367c478bd9Sstevel@tonic-gate 
17377c478bd9Sstevel@tonic-gate bool_t
17387c478bd9Sstevel@tonic-gate xdr_CREATE3res(XDR *xdrs, CREATE3res *objp)
17397c478bd9Sstevel@tonic-gate {
17407c478bd9Sstevel@tonic-gate 	CREATE3resok *resokp;
17417c478bd9Sstevel@tonic-gate 
17427c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
17437c478bd9Sstevel@tonic-gate 		return (FALSE);
17447c478bd9Sstevel@tonic-gate 	switch (objp->status) {
17457c478bd9Sstevel@tonic-gate 	case NFS3_OK:
17467c478bd9Sstevel@tonic-gate 		/* xdr_CREATE3resok */
17477c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
17487c478bd9Sstevel@tonic-gate 
17497c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
17507c478bd9Sstevel@tonic-gate 			return (FALSE);
17517c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
17527c478bd9Sstevel@tonic-gate 			return (FALSE);
17537c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
17547c478bd9Sstevel@tonic-gate 	default:
17557c478bd9Sstevel@tonic-gate 		/* xdr_CREATE3resfail */
17567c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
17577c478bd9Sstevel@tonic-gate 	}
17587c478bd9Sstevel@tonic-gate }
17597c478bd9Sstevel@tonic-gate 
17607c478bd9Sstevel@tonic-gate bool_t
17617c478bd9Sstevel@tonic-gate xdr_MKDIR3args(XDR *xdrs, MKDIR3args *objp)
17627c478bd9Sstevel@tonic-gate {
17637c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->where))
17647c478bd9Sstevel@tonic-gate 		return (FALSE);
17657c478bd9Sstevel@tonic-gate 	return (xdr_sattr3(xdrs, &objp->attributes));
17667c478bd9Sstevel@tonic-gate }
17677c478bd9Sstevel@tonic-gate 
17687c478bd9Sstevel@tonic-gate bool_t
17697c478bd9Sstevel@tonic-gate xdr_MKDIR3res(XDR *xdrs, MKDIR3res *objp)
17707c478bd9Sstevel@tonic-gate {
17717c478bd9Sstevel@tonic-gate 	MKDIR3resok *resokp;
17727c478bd9Sstevel@tonic-gate 
17737c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
17747c478bd9Sstevel@tonic-gate 		return (FALSE);
17757c478bd9Sstevel@tonic-gate 	switch (objp->status) {
17767c478bd9Sstevel@tonic-gate 	case NFS3_OK:
17777c478bd9Sstevel@tonic-gate 		/* xdr_MKDIR3resok */
17787c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
17797c478bd9Sstevel@tonic-gate 
17807c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
17817c478bd9Sstevel@tonic-gate 			return (FALSE);
17827c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
17837c478bd9Sstevel@tonic-gate 			return (FALSE);
17847c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
17857c478bd9Sstevel@tonic-gate 	default:
17867c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
17877c478bd9Sstevel@tonic-gate 	}
17887c478bd9Sstevel@tonic-gate }
17897c478bd9Sstevel@tonic-gate 
17907c478bd9Sstevel@tonic-gate bool_t
17917c478bd9Sstevel@tonic-gate xdr_SYMLINK3args(XDR *xdrs, SYMLINK3args *objp)
17927c478bd9Sstevel@tonic-gate {
17937c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->where))
17947c478bd9Sstevel@tonic-gate 		return (FALSE);
17957c478bd9Sstevel@tonic-gate 	if (!xdr_sattr3(xdrs, &objp->symlink.symlink_attributes))
17967c478bd9Sstevel@tonic-gate 		return (FALSE);
17977c478bd9Sstevel@tonic-gate 	return (xdr_string3(xdrs, &objp->symlink.symlink_data, MAXPATHLEN));
17987c478bd9Sstevel@tonic-gate }
17997c478bd9Sstevel@tonic-gate 
18007c478bd9Sstevel@tonic-gate bool_t
18017c478bd9Sstevel@tonic-gate xdr_SYMLINK3res(XDR *xdrs, SYMLINK3res *objp)
18027c478bd9Sstevel@tonic-gate {
18037c478bd9Sstevel@tonic-gate 	SYMLINK3resok *resokp;
18047c478bd9Sstevel@tonic-gate 
18057c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
18067c478bd9Sstevel@tonic-gate 		return (FALSE);
18077c478bd9Sstevel@tonic-gate 	switch (objp->status) {
18087c478bd9Sstevel@tonic-gate 	case NFS3_OK:
18097c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
18107c478bd9Sstevel@tonic-gate 		/* xdr_SYMLINK3resok */
18117c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
18127c478bd9Sstevel@tonic-gate 			return (FALSE);
18137c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
18147c478bd9Sstevel@tonic-gate 			return (FALSE);
18157c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
18167c478bd9Sstevel@tonic-gate 	default:
18177c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
18187c478bd9Sstevel@tonic-gate 	}
18197c478bd9Sstevel@tonic-gate }
18207c478bd9Sstevel@tonic-gate 
18217c478bd9Sstevel@tonic-gate bool_t
18227c478bd9Sstevel@tonic-gate xdr_MKNOD3args(XDR *xdrs, MKNOD3args *objp)
18237c478bd9Sstevel@tonic-gate {
18247c478bd9Sstevel@tonic-gate 	mknoddata3 *whatp;
18257c478bd9Sstevel@tonic-gate 	devicedata3 *nod_objp;
18267c478bd9Sstevel@tonic-gate 
18277c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->where))
18287c478bd9Sstevel@tonic-gate 		return (FALSE);
18297c478bd9Sstevel@tonic-gate 
18307c478bd9Sstevel@tonic-gate 	whatp = &objp->what;
18317c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&whatp->type))
18327c478bd9Sstevel@tonic-gate 		return (FALSE);
18337c478bd9Sstevel@tonic-gate 	switch (whatp->type) {
18347c478bd9Sstevel@tonic-gate 	case NF3CHR:
18357c478bd9Sstevel@tonic-gate 	case NF3BLK:
18367c478bd9Sstevel@tonic-gate 		/* xdr_devicedata3 */
18377c478bd9Sstevel@tonic-gate 		nod_objp = &whatp->mknoddata3_u.device;
18387c478bd9Sstevel@tonic-gate 		if (!xdr_sattr3(xdrs, &nod_objp->dev_attributes))
18397c478bd9Sstevel@tonic-gate 			return (FALSE);
18407c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &nod_objp->spec.specdata1))
18417c478bd9Sstevel@tonic-gate 			return (FALSE);
18427c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &nod_objp->spec.specdata2));
18437c478bd9Sstevel@tonic-gate 	case NF3SOCK:
18447c478bd9Sstevel@tonic-gate 	case NF3FIFO:
18457c478bd9Sstevel@tonic-gate 		return (xdr_sattr3(xdrs, &whatp->mknoddata3_u.pipe_attributes));
18467c478bd9Sstevel@tonic-gate 	default:
18477c478bd9Sstevel@tonic-gate 		break;
18487c478bd9Sstevel@tonic-gate 	}
18497c478bd9Sstevel@tonic-gate 	return (TRUE);
18507c478bd9Sstevel@tonic-gate }
18517c478bd9Sstevel@tonic-gate 
18527c478bd9Sstevel@tonic-gate bool_t
18537c478bd9Sstevel@tonic-gate xdr_MKNOD3res(XDR *xdrs, MKNOD3res *objp)
18547c478bd9Sstevel@tonic-gate {
18557c478bd9Sstevel@tonic-gate 	MKNOD3resok *resokp;
18567c478bd9Sstevel@tonic-gate 
18577c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
18587c478bd9Sstevel@tonic-gate 		return (FALSE);
18597c478bd9Sstevel@tonic-gate 	switch (objp->status) {
18607c478bd9Sstevel@tonic-gate 	case NFS3_OK:
18617c478bd9Sstevel@tonic-gate 		/* xdr_MKNOD3resok */
18627c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
18637c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
18647c478bd9Sstevel@tonic-gate 			return (FALSE);
18657c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
18667c478bd9Sstevel@tonic-gate 			return (FALSE);
18677c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
18687c478bd9Sstevel@tonic-gate 	default:
18697c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
18707c478bd9Sstevel@tonic-gate 	}
18717c478bd9Sstevel@tonic-gate }
18727c478bd9Sstevel@tonic-gate 
18737c478bd9Sstevel@tonic-gate bool_t
18747c478bd9Sstevel@tonic-gate xdr_REMOVE3res(XDR *xdrs, REMOVE3res *objp)
18757c478bd9Sstevel@tonic-gate {
18767c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
18777c478bd9Sstevel@tonic-gate 		return (FALSE);
18787c478bd9Sstevel@tonic-gate 	switch (objp->status) {
18797c478bd9Sstevel@tonic-gate 	case NFS3_OK:
18807c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
18817c478bd9Sstevel@tonic-gate 	default:
18827c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
18837c478bd9Sstevel@tonic-gate 	}
18847c478bd9Sstevel@tonic-gate }
18857c478bd9Sstevel@tonic-gate 
18867c478bd9Sstevel@tonic-gate bool_t
18877c478bd9Sstevel@tonic-gate xdr_RMDIR3res(XDR *xdrs, RMDIR3res *objp)
18887c478bd9Sstevel@tonic-gate {
18897c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
18907c478bd9Sstevel@tonic-gate 		return (FALSE);
18917c478bd9Sstevel@tonic-gate 	switch (objp->status) {
18927c478bd9Sstevel@tonic-gate 	case NFS3_OK:
18937c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
18947c478bd9Sstevel@tonic-gate 	default:
18957c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
18967c478bd9Sstevel@tonic-gate 	}
18977c478bd9Sstevel@tonic-gate }
18987c478bd9Sstevel@tonic-gate 
18997c478bd9Sstevel@tonic-gate bool_t
19007c478bd9Sstevel@tonic-gate xdr_RENAME3args(XDR *xdrs, RENAME3args *objp)
19017c478bd9Sstevel@tonic-gate {
19027c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->from))
19037c478bd9Sstevel@tonic-gate 		return (FALSE);
19047c478bd9Sstevel@tonic-gate 	return (xdr_diropargs3(xdrs, &objp->to));
19057c478bd9Sstevel@tonic-gate }
19067c478bd9Sstevel@tonic-gate 
19077c478bd9Sstevel@tonic-gate bool_t
19087c478bd9Sstevel@tonic-gate xdr_RENAME3res(XDR *xdrs, RENAME3res *objp)
19097c478bd9Sstevel@tonic-gate {
19107c478bd9Sstevel@tonic-gate 	RENAME3resok *resokp;
19117c478bd9Sstevel@tonic-gate 	RENAME3resfail *resfailp;
19127c478bd9Sstevel@tonic-gate 
19137c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
19147c478bd9Sstevel@tonic-gate 		return (FALSE);
19157c478bd9Sstevel@tonic-gate 	switch (objp->status) {
19167c478bd9Sstevel@tonic-gate 	case NFS3_OK:
19177c478bd9Sstevel@tonic-gate 		/* xdr_RENAME3resok */
19187c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
19197c478bd9Sstevel@tonic-gate 
19207c478bd9Sstevel@tonic-gate 		if (!xdr_wcc_data(xdrs, &resokp->fromdir_wcc))
19217c478bd9Sstevel@tonic-gate 			return (FALSE);
19227c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->todir_wcc));
19237c478bd9Sstevel@tonic-gate 	default:
19247c478bd9Sstevel@tonic-gate 		/* xdr_RENAME3resfail */
19257c478bd9Sstevel@tonic-gate 		resfailp = &objp->resfail;
19267c478bd9Sstevel@tonic-gate 		if (!xdr_wcc_data(xdrs, &resfailp->fromdir_wcc))
19277c478bd9Sstevel@tonic-gate 			return (FALSE);
19287c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resfailp->todir_wcc));
19297c478bd9Sstevel@tonic-gate 	}
19307c478bd9Sstevel@tonic-gate }
19317c478bd9Sstevel@tonic-gate 
19327c478bd9Sstevel@tonic-gate bool_t
19337c478bd9Sstevel@tonic-gate xdr_LINK3args(XDR *xdrs, LINK3args *objp)
19347c478bd9Sstevel@tonic-gate {
193527242a7cSthurlow 	switch (xdrs->x_op) {
193627242a7cSthurlow 	case XDR_FREE:
193727242a7cSthurlow 	case XDR_ENCODE:
19387c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, &objp->file))
19397c478bd9Sstevel@tonic-gate 			return (FALSE);
194027242a7cSthurlow 		break;
194127242a7cSthurlow 	case XDR_DECODE:
194227242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
194327242a7cSthurlow 			return (FALSE);
194427242a7cSthurlow 		break;
194527242a7cSthurlow 	}
19467c478bd9Sstevel@tonic-gate 	return (xdr_diropargs3(xdrs, &objp->link));
19477c478bd9Sstevel@tonic-gate }
19487c478bd9Sstevel@tonic-gate 
19497c478bd9Sstevel@tonic-gate bool_t
19507c478bd9Sstevel@tonic-gate xdr_LINK3res(XDR *xdrs, LINK3res *objp)
19517c478bd9Sstevel@tonic-gate {
19527c478bd9Sstevel@tonic-gate 	LINK3resok *resokp;
19537c478bd9Sstevel@tonic-gate 	LINK3resfail *resfailp;
19547c478bd9Sstevel@tonic-gate 
19557c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
19567c478bd9Sstevel@tonic-gate 		return (FALSE);
19577c478bd9Sstevel@tonic-gate 	switch (objp->status) {
19587c478bd9Sstevel@tonic-gate 	case NFS3_OK:
19597c478bd9Sstevel@tonic-gate 		/* xdr_LINK3resok */
19607c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
19617c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->file_attributes))
19627c478bd9Sstevel@tonic-gate 			return (FALSE);
19637c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->linkdir_wcc));
19647c478bd9Sstevel@tonic-gate 	default:
19657c478bd9Sstevel@tonic-gate 		/* xdr_LINK3resfail */
19667c478bd9Sstevel@tonic-gate 		resfailp = &objp->resfail;
19677c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resfailp->file_attributes))
19687c478bd9Sstevel@tonic-gate 			return (FALSE);
19697c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resfailp->linkdir_wcc));
19707c478bd9Sstevel@tonic-gate 	}
19717c478bd9Sstevel@tonic-gate }
19727c478bd9Sstevel@tonic-gate 
19737c478bd9Sstevel@tonic-gate bool_t
19747c478bd9Sstevel@tonic-gate xdr_READDIR3args(XDR *xdrs, READDIR3args *objp)
19757c478bd9Sstevel@tonic-gate {
19760a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
19770a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
19780a701b1eSRobert Gordon 
19797c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
19807c478bd9Sstevel@tonic-gate 		return (TRUE);
19817c478bd9Sstevel@tonic-gate 
198227242a7cSthurlow 	switch (xdrs->x_op) {
198327242a7cSthurlow 	case XDR_FREE:
198427242a7cSthurlow 	case XDR_ENCODE:
19857c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, &objp->dir))
19867c478bd9Sstevel@tonic-gate 			return (FALSE);
198727242a7cSthurlow 		break;
198827242a7cSthurlow 	case XDR_DECODE:
198927242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
199027242a7cSthurlow 			return (FALSE);
199127242a7cSthurlow 		break;
199227242a7cSthurlow 	}
19930a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
19940a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
19950a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
19960a701b1eSRobert Gordon 		rci.rci_len = objp->count;
19970a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
19980a701b1eSRobert Gordon 	}
19990a701b1eSRobert Gordon 
20007c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookie))
20017c478bd9Sstevel@tonic-gate 		return (FALSE);
20027c478bd9Sstevel@tonic-gate 	/*
20037c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
20047c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
20057c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
20067c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
20077c478bd9Sstevel@tonic-gate 	 */
20087c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
20097c478bd9Sstevel@tonic-gate 		return (FALSE);
20107c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->count));
20117c478bd9Sstevel@tonic-gate }
20127c478bd9Sstevel@tonic-gate 
20137c478bd9Sstevel@tonic-gate #ifdef	nextdp
20147c478bd9Sstevel@tonic-gate #undef	nextdp
20157c478bd9Sstevel@tonic-gate #endif
20167c478bd9Sstevel@tonic-gate #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
20177c478bd9Sstevel@tonic-gate #ifdef	roundup
20187c478bd9Sstevel@tonic-gate #undef	roundup
20197c478bd9Sstevel@tonic-gate #endif
20207c478bd9Sstevel@tonic-gate #define	roundup(x, y)	((((x) + ((y) - 1)) / (y)) * (y))
20217c478bd9Sstevel@tonic-gate 
20227c478bd9Sstevel@tonic-gate /*
20237c478bd9Sstevel@tonic-gate  * ENCODE ONLY
20247c478bd9Sstevel@tonic-gate  */
20257c478bd9Sstevel@tonic-gate static bool_t
20267c478bd9Sstevel@tonic-gate xdr_putdirlist(XDR *xdrs, READDIR3resok *objp)
20277c478bd9Sstevel@tonic-gate {
20287c478bd9Sstevel@tonic-gate 	struct dirent64 *dp;
20297c478bd9Sstevel@tonic-gate 	char *name;
20307c478bd9Sstevel@tonic-gate 	int size;
20317c478bd9Sstevel@tonic-gate 	int bufsize;
20327c478bd9Sstevel@tonic-gate 	uint_t namlen;
20337c478bd9Sstevel@tonic-gate 	bool_t true = TRUE;
20347c478bd9Sstevel@tonic-gate 	bool_t false = FALSE;
20357c478bd9Sstevel@tonic-gate 	int entrysz;
20367c478bd9Sstevel@tonic-gate 	int tofit;
20377c478bd9Sstevel@tonic-gate 	fileid3 fileid;
20387c478bd9Sstevel@tonic-gate 	cookie3 cookie;
20397c478bd9Sstevel@tonic-gate 
20407c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_ENCODE)
20417c478bd9Sstevel@tonic-gate 		return (FALSE);
20427c478bd9Sstevel@tonic-gate 
20437c478bd9Sstevel@tonic-gate 	/*
20447c478bd9Sstevel@tonic-gate 	 * bufsize is used to keep track of the size of the response.
20457c478bd9Sstevel@tonic-gate 	 * It is primed with:
20467c478bd9Sstevel@tonic-gate 	 *	1 for the status +
20477c478bd9Sstevel@tonic-gate 	 *	1 for the dir_attributes.attributes boolean +
20487c478bd9Sstevel@tonic-gate 	 *	2 for the cookie verifier
20497c478bd9Sstevel@tonic-gate 	 * all times BYTES_PER_XDR_UNIT to convert from XDR units
20507c478bd9Sstevel@tonic-gate 	 * to bytes.  If there are directory attributes to be
20517c478bd9Sstevel@tonic-gate 	 * returned, then:
20527c478bd9Sstevel@tonic-gate 	 *	NFS3_SIZEOF_FATTR3 for the dir_attributes.attr fattr3
20537c478bd9Sstevel@tonic-gate 	 * time BYTES_PER_XDR_UNIT is added to account for them.
20547c478bd9Sstevel@tonic-gate 	 */
20557c478bd9Sstevel@tonic-gate 	bufsize = (1 + 1 + 2) * BYTES_PER_XDR_UNIT;
20567c478bd9Sstevel@tonic-gate 	if (objp->dir_attributes.attributes)
20577c478bd9Sstevel@tonic-gate 		bufsize += NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
20587c478bd9Sstevel@tonic-gate 	for (size = objp->size, dp = (struct dirent64 *)objp->reply.entries;
20597c478bd9Sstevel@tonic-gate 	    size > 0;
20607c478bd9Sstevel@tonic-gate 	    size -= dp->d_reclen, dp = nextdp(dp)) {
20617c478bd9Sstevel@tonic-gate 		if (dp->d_reclen == 0)
20627c478bd9Sstevel@tonic-gate 			return (FALSE);
20637c478bd9Sstevel@tonic-gate 		if (dp->d_ino == 0)
20647c478bd9Sstevel@tonic-gate 			continue;
20657c478bd9Sstevel@tonic-gate 		name = dp->d_name;
20667c478bd9Sstevel@tonic-gate 		namlen = (uint_t)strlen(dp->d_name);
20677c478bd9Sstevel@tonic-gate 		/*
20687c478bd9Sstevel@tonic-gate 		 * An entry is composed of:
20697c478bd9Sstevel@tonic-gate 		 *	1 for the true/false list indicator +
20707c478bd9Sstevel@tonic-gate 		 *	2 for the fileid +
20717c478bd9Sstevel@tonic-gate 		 *	1 for the length of the name +
20727c478bd9Sstevel@tonic-gate 		 *	2 for the cookie +
20737c478bd9Sstevel@tonic-gate 		 * all times BYTES_PER_XDR_UNIT to convert from
20747c478bd9Sstevel@tonic-gate 		 * XDR units to bytes, plus the length of the name
20757c478bd9Sstevel@tonic-gate 		 * rounded up to the nearest BYTES_PER_XDR_UNIT.
20767c478bd9Sstevel@tonic-gate 		 */
20777c478bd9Sstevel@tonic-gate 		entrysz = (1 + 2 + 1 + 2) * BYTES_PER_XDR_UNIT +
20787c478bd9Sstevel@tonic-gate 		    roundup(namlen, BYTES_PER_XDR_UNIT);
20797c478bd9Sstevel@tonic-gate 		/*
20807c478bd9Sstevel@tonic-gate 		 * We need to check to see if the number of bytes left
20817c478bd9Sstevel@tonic-gate 		 * to go into the buffer will actually fit into the
20827c478bd9Sstevel@tonic-gate 		 * buffer.  This is calculated as the size of this
20837c478bd9Sstevel@tonic-gate 		 * entry plus:
20847c478bd9Sstevel@tonic-gate 		 *	1 for the true/false list indicator +
20857c478bd9Sstevel@tonic-gate 		 *	1 for the eof indicator
20867c478bd9Sstevel@tonic-gate 		 * times BYTES_PER_XDR_UNIT to convert from from
20877c478bd9Sstevel@tonic-gate 		 * XDR units to bytes.
20887c478bd9Sstevel@tonic-gate 		 */
20897c478bd9Sstevel@tonic-gate 		tofit = entrysz + (1 + 1) * BYTES_PER_XDR_UNIT;
20907c478bd9Sstevel@tonic-gate 		if (bufsize + tofit > objp->count) {
20917c478bd9Sstevel@tonic-gate 			objp->reply.eof = FALSE;
20927c478bd9Sstevel@tonic-gate 			break;
20937c478bd9Sstevel@tonic-gate 		}
20947c478bd9Sstevel@tonic-gate 		fileid = (fileid3)(dp->d_ino);
20957c478bd9Sstevel@tonic-gate 		cookie = (cookie3)(dp->d_off);
20967c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &true) ||
20977c478bd9Sstevel@tonic-gate 		    !xdr_u_longlong_t(xdrs, &fileid) ||
20987c478bd9Sstevel@tonic-gate 		    !xdr_bytes(xdrs, &name, &namlen, ~0) ||
20997c478bd9Sstevel@tonic-gate 		    !xdr_u_longlong_t(xdrs, &cookie)) {
21007c478bd9Sstevel@tonic-gate 			return (FALSE);
21017c478bd9Sstevel@tonic-gate 		}
21027c478bd9Sstevel@tonic-gate 		bufsize += entrysz;
21037c478bd9Sstevel@tonic-gate 	}
21047c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &false))
21057c478bd9Sstevel@tonic-gate 		return (FALSE);
21067c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->reply.eof))
21077c478bd9Sstevel@tonic-gate 		return (FALSE);
21087c478bd9Sstevel@tonic-gate 	return (TRUE);
21097c478bd9Sstevel@tonic-gate }
21107c478bd9Sstevel@tonic-gate 
21117c478bd9Sstevel@tonic-gate bool_t
21127c478bd9Sstevel@tonic-gate xdr_READDIR3res(XDR *xdrs, READDIR3res *objp)
21137c478bd9Sstevel@tonic-gate {
21147c478bd9Sstevel@tonic-gate 	READDIR3resok *resokp;
21157c478bd9Sstevel@tonic-gate 
21167c478bd9Sstevel@tonic-gate 	/*
21177c478bd9Sstevel@tonic-gate 	 * ENCODE or FREE only
21187c478bd9Sstevel@tonic-gate 	 */
21197c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
21207c478bd9Sstevel@tonic-gate 		return (FALSE);
21217c478bd9Sstevel@tonic-gate 
21227c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
21237c478bd9Sstevel@tonic-gate 		return (FALSE);
21247c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
21257c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
21267c478bd9Sstevel@tonic-gate 
21277c478bd9Sstevel@tonic-gate 	/* xdr_READDIR3resok */
21287c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
21297c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
21307c478bd9Sstevel@tonic-gate 		return (FALSE);
21317c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_ENCODE)
21327c478bd9Sstevel@tonic-gate 		return (TRUE);
21337c478bd9Sstevel@tonic-gate 	/*
21347c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
21357c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
21367c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
21377c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
21387c478bd9Sstevel@tonic-gate 	 */
21397c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
21407c478bd9Sstevel@tonic-gate 		return (FALSE);
21417c478bd9Sstevel@tonic-gate 	return (xdr_putdirlist(xdrs, resokp));
21427c478bd9Sstevel@tonic-gate }
21437c478bd9Sstevel@tonic-gate 
21447c478bd9Sstevel@tonic-gate bool_t
21457c478bd9Sstevel@tonic-gate xdr_READDIR3vres(XDR *xdrs, READDIR3vres *objp)
21467c478bd9Sstevel@tonic-gate {
21477c478bd9Sstevel@tonic-gate 	dirent64_t *dp;
21487c478bd9Sstevel@tonic-gate 	uint_t entries_size;
21497c478bd9Sstevel@tonic-gate 	int outcount = 0;
21507c478bd9Sstevel@tonic-gate 
21517c478bd9Sstevel@tonic-gate 	/*
21527c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
21537c478bd9Sstevel@tonic-gate 	 */
21547c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
21557c478bd9Sstevel@tonic-gate 		return (TRUE);
21567c478bd9Sstevel@tonic-gate 
21577c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
21587c478bd9Sstevel@tonic-gate 		return (FALSE);
21597c478bd9Sstevel@tonic-gate 
21607c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
21617c478bd9Sstevel@tonic-gate 		return (FALSE);
21627c478bd9Sstevel@tonic-gate 
21637c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
21647c478bd9Sstevel@tonic-gate 		return (FALSE);
21657c478bd9Sstevel@tonic-gate 
21667c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
21677c478bd9Sstevel@tonic-gate 		return (TRUE);
21687c478bd9Sstevel@tonic-gate 
21697c478bd9Sstevel@tonic-gate 	/*
21707c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
21717c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
21727c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
21737c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
21747c478bd9Sstevel@tonic-gate 	 */
21757c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
21767c478bd9Sstevel@tonic-gate 		return (FALSE);
21777c478bd9Sstevel@tonic-gate 
21787c478bd9Sstevel@tonic-gate 	entries_size = objp->entries_size;
21797c478bd9Sstevel@tonic-gate 	dp = objp->entries;
21807c478bd9Sstevel@tonic-gate 
21817c478bd9Sstevel@tonic-gate 	for (;;) {
21827c478bd9Sstevel@tonic-gate 		uint_t this_reclen;
21837c478bd9Sstevel@tonic-gate 		bool_t valid;
21847c478bd9Sstevel@tonic-gate 		uint_t namlen;
21857c478bd9Sstevel@tonic-gate 		ino64_t fileid;
21867c478bd9Sstevel@tonic-gate 
21877c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
21887c478bd9Sstevel@tonic-gate 			return (FALSE);
21897c478bd9Sstevel@tonic-gate 		if (!valid) {
21907c478bd9Sstevel@tonic-gate 			/*
21917c478bd9Sstevel@tonic-gate 			 * We have run out of entries, decode eof.
21927c478bd9Sstevel@tonic-gate 			 */
21937c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
21947c478bd9Sstevel@tonic-gate 				return (FALSE);
21957c478bd9Sstevel@tonic-gate 
21967c478bd9Sstevel@tonic-gate 			break;
21977c478bd9Sstevel@tonic-gate 		}
21987c478bd9Sstevel@tonic-gate 
21997c478bd9Sstevel@tonic-gate 		/*
22007c478bd9Sstevel@tonic-gate 		 * fileid3 fileid
22017c478bd9Sstevel@tonic-gate 		 */
22027c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
22037c478bd9Sstevel@tonic-gate 			return (FALSE);
22047c478bd9Sstevel@tonic-gate 
22057c478bd9Sstevel@tonic-gate 		/*
22067c478bd9Sstevel@tonic-gate 		 * filename3 name
22077c478bd9Sstevel@tonic-gate 		 */
22087c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
22097c478bd9Sstevel@tonic-gate 			return (FALSE);
22107c478bd9Sstevel@tonic-gate 		this_reclen = DIRENT64_RECLEN(namlen);
22117c478bd9Sstevel@tonic-gate 
22127c478bd9Sstevel@tonic-gate 		/*
22137c478bd9Sstevel@tonic-gate 		 * If this will overflow buffer, stop decoding
22147c478bd9Sstevel@tonic-gate 		 */
22157c478bd9Sstevel@tonic-gate 		if ((outcount + this_reclen) > entries_size) {
22167c478bd9Sstevel@tonic-gate 			objp->eof = FALSE;
22177c478bd9Sstevel@tonic-gate 			break;
22187c478bd9Sstevel@tonic-gate 		}
22197c478bd9Sstevel@tonic-gate 		dp->d_reclen = this_reclen;
22207c478bd9Sstevel@tonic-gate 		dp->d_ino = fileid;
22217c478bd9Sstevel@tonic-gate 
22227c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, dp->d_name, namlen))
22237c478bd9Sstevel@tonic-gate 			return (FALSE);
22247c478bd9Sstevel@tonic-gate 		bzero(&dp->d_name[namlen],
22257c478bd9Sstevel@tonic-gate 		    DIRENT64_NAMELEN(this_reclen) - namlen);
22267c478bd9Sstevel@tonic-gate 
22277c478bd9Sstevel@tonic-gate 		/*
22287c478bd9Sstevel@tonic-gate 		 * cookie3 cookie
22297c478bd9Sstevel@tonic-gate 		 */
22307c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
22317c478bd9Sstevel@tonic-gate 			return (FALSE);
22327c478bd9Sstevel@tonic-gate 		objp->loff = dp->d_off;
22337c478bd9Sstevel@tonic-gate 
22347c478bd9Sstevel@tonic-gate 		outcount += this_reclen;
22357c478bd9Sstevel@tonic-gate 		dp = (dirent64_t *)((intptr_t)dp + this_reclen);
22367c478bd9Sstevel@tonic-gate 	}
22377c478bd9Sstevel@tonic-gate 
22387c478bd9Sstevel@tonic-gate 	objp->size = outcount;
22397c478bd9Sstevel@tonic-gate 	return (TRUE);
22407c478bd9Sstevel@tonic-gate }
22417c478bd9Sstevel@tonic-gate 
22427c478bd9Sstevel@tonic-gate bool_t
22437c478bd9Sstevel@tonic-gate xdr_READDIRPLUS3args(XDR *xdrs, READDIRPLUS3args *objp)
22447c478bd9Sstevel@tonic-gate {
22450a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
22460a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
22470a701b1eSRobert Gordon 
22487c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
22497c478bd9Sstevel@tonic-gate 		return (TRUE);
22507c478bd9Sstevel@tonic-gate 
225127242a7cSthurlow 	switch (xdrs->x_op) {
225227242a7cSthurlow 	case XDR_FREE:
225327242a7cSthurlow 	case XDR_ENCODE:
22547c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, &objp->dir))
22557c478bd9Sstevel@tonic-gate 			return (FALSE);
225627242a7cSthurlow 		break;
225727242a7cSthurlow 	case XDR_DECODE:
225827242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
225927242a7cSthurlow 			return (FALSE);
226027242a7cSthurlow 		break;
226127242a7cSthurlow 	}
22620a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
22630a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
22640a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
22650a701b1eSRobert Gordon 		rci.rci_len = objp->maxcount;
22660a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
22670a701b1eSRobert Gordon 	}
22680a701b1eSRobert Gordon 
22697c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookie))
22707c478bd9Sstevel@tonic-gate 		return (FALSE);
22717c478bd9Sstevel@tonic-gate 	/*
22727c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
22737c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
22747c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
22757c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
22767c478bd9Sstevel@tonic-gate 	 */
22777c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
22787c478bd9Sstevel@tonic-gate 		return (FALSE);
22797c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->dircount))
22807c478bd9Sstevel@tonic-gate 		return (FALSE);
22817c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->maxcount));
22827c478bd9Sstevel@tonic-gate }
22837c478bd9Sstevel@tonic-gate 
22847c478bd9Sstevel@tonic-gate /*
22857c478bd9Sstevel@tonic-gate  * ENCODE ONLY
22867c478bd9Sstevel@tonic-gate  */
22877c478bd9Sstevel@tonic-gate static bool_t
22887c478bd9Sstevel@tonic-gate xdr_putdirpluslist(XDR *xdrs, READDIRPLUS3resok *objp)
22897c478bd9Sstevel@tonic-gate {
22907c478bd9Sstevel@tonic-gate 	struct dirent64 *dp;
22917c478bd9Sstevel@tonic-gate 	char *name;
22927c478bd9Sstevel@tonic-gate 	int nents;
22937c478bd9Sstevel@tonic-gate 	bool_t true = TRUE;
22947c478bd9Sstevel@tonic-gate 	bool_t false = FALSE;
22957c478bd9Sstevel@tonic-gate 	fileid3 fileid;
22967c478bd9Sstevel@tonic-gate 	cookie3 cookie;
22977c478bd9Sstevel@tonic-gate 	entryplus3_info *infop;
22987c478bd9Sstevel@tonic-gate 
22997c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_ENCODE)
23007c478bd9Sstevel@tonic-gate 		return (FALSE);
23017c478bd9Sstevel@tonic-gate 
23027c478bd9Sstevel@tonic-gate 	dp = (struct dirent64 *)objp->reply.entries;
23037c478bd9Sstevel@tonic-gate 	nents = objp->size;
23047c478bd9Sstevel@tonic-gate 	infop = objp->infop;
23057c478bd9Sstevel@tonic-gate 
23067c478bd9Sstevel@tonic-gate 	while (nents > 0) {
23077c478bd9Sstevel@tonic-gate 		if (dp->d_reclen == 0)
23087c478bd9Sstevel@tonic-gate 			return (FALSE);
23097c478bd9Sstevel@tonic-gate 		if (dp->d_ino != 0) {
23107c478bd9Sstevel@tonic-gate 			name = dp->d_name;
23117c478bd9Sstevel@tonic-gate 			fileid = (fileid3)(dp->d_ino);
23127c478bd9Sstevel@tonic-gate 			cookie = (cookie3)(dp->d_off);
23137c478bd9Sstevel@tonic-gate 			if (!xdr_bool(xdrs, &true) ||
23147c478bd9Sstevel@tonic-gate 			    !xdr_u_longlong_t(xdrs, &fileid) ||
23157c478bd9Sstevel@tonic-gate 			    !xdr_bytes(xdrs, &name, &infop->namelen, ~0) ||
23167c478bd9Sstevel@tonic-gate 			    !xdr_u_longlong_t(xdrs, &cookie) ||
23177c478bd9Sstevel@tonic-gate 			    !xdr_post_op_attr(xdrs, &infop->attr) ||
23187c478bd9Sstevel@tonic-gate 			    !xdr_post_op_fh3(xdrs, &infop->fh)) {
23197c478bd9Sstevel@tonic-gate 				return (FALSE);
23207c478bd9Sstevel@tonic-gate 			}
23217c478bd9Sstevel@tonic-gate 		}
23227c478bd9Sstevel@tonic-gate 		dp = nextdp(dp);
23237c478bd9Sstevel@tonic-gate 		infop++;
23247c478bd9Sstevel@tonic-gate 		nents--;
23257c478bd9Sstevel@tonic-gate 	}
23267c478bd9Sstevel@tonic-gate 
23277c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &false))
23287c478bd9Sstevel@tonic-gate 		return (FALSE);
23297c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->reply.eof))
23307c478bd9Sstevel@tonic-gate 		return (FALSE);
23317c478bd9Sstevel@tonic-gate 	return (TRUE);
23327c478bd9Sstevel@tonic-gate }
23337c478bd9Sstevel@tonic-gate 
23347c478bd9Sstevel@tonic-gate bool_t
23357c478bd9Sstevel@tonic-gate xdr_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
23367c478bd9Sstevel@tonic-gate {
23377c478bd9Sstevel@tonic-gate 	READDIRPLUS3resok *resokp;
23387c478bd9Sstevel@tonic-gate 
23397c478bd9Sstevel@tonic-gate 	/*
23407c478bd9Sstevel@tonic-gate 	 * ENCODE or FREE only
23417c478bd9Sstevel@tonic-gate 	 */
23427c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
23437c478bd9Sstevel@tonic-gate 		return (FALSE);
23447c478bd9Sstevel@tonic-gate 
23457c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
23467c478bd9Sstevel@tonic-gate 		return (FALSE);
23477c478bd9Sstevel@tonic-gate 	switch (objp->status) {
23487c478bd9Sstevel@tonic-gate 	case NFS3_OK:
23497c478bd9Sstevel@tonic-gate 		/* xdr_READDIRPLUS3resok */
23507c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
23517c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
23527c478bd9Sstevel@tonic-gate 			return (FALSE);
23537c478bd9Sstevel@tonic-gate 		/*
23547c478bd9Sstevel@tonic-gate 		 * cookieverf is really an opaque 8 byte
23557c478bd9Sstevel@tonic-gate 		 * quantity, but we will treat it as a
23567c478bd9Sstevel@tonic-gate 		 * hyper for efficiency, the cost of
23577c478bd9Sstevel@tonic-gate 		 * a byteswap here saves bcopys elsewhere
23587c478bd9Sstevel@tonic-gate 		 */
23597c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
23607c478bd9Sstevel@tonic-gate 			return (FALSE);
23617c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_ENCODE) {
23627c478bd9Sstevel@tonic-gate 			if (!xdr_putdirpluslist(xdrs, resokp))
23637c478bd9Sstevel@tonic-gate 				return (FALSE);
23647c478bd9Sstevel@tonic-gate 		}
23657c478bd9Sstevel@tonic-gate 		break;
23667c478bd9Sstevel@tonic-gate 	default:
23677c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
23687c478bd9Sstevel@tonic-gate 	}
23697c478bd9Sstevel@tonic-gate 	return (TRUE);
23707c478bd9Sstevel@tonic-gate }
23717c478bd9Sstevel@tonic-gate 
23727c478bd9Sstevel@tonic-gate /*
23737c478bd9Sstevel@tonic-gate  * Decode readdirplus directly into a dirent64_t and do the DNLC caching.
23747c478bd9Sstevel@tonic-gate  */
23757c478bd9Sstevel@tonic-gate bool_t
23767c478bd9Sstevel@tonic-gate xdr_READDIRPLUS3vres(XDR *xdrs, READDIRPLUS3vres *objp)
23777c478bd9Sstevel@tonic-gate {
23787c478bd9Sstevel@tonic-gate 	dirent64_t *dp;
23797c478bd9Sstevel@tonic-gate 	vnode_t *dvp;
23807c478bd9Sstevel@tonic-gate 	uint_t entries_size;
23817c478bd9Sstevel@tonic-gate 	int outcount = 0;
23827c478bd9Sstevel@tonic-gate 	vnode_t *nvp;
23837c478bd9Sstevel@tonic-gate 	rnode_t *rp;
23847c478bd9Sstevel@tonic-gate 	post_op_vattr pov;
23857c478bd9Sstevel@tonic-gate 	vattr_t va;
23867c478bd9Sstevel@tonic-gate 
23877c478bd9Sstevel@tonic-gate 	/*
23887c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
23897c478bd9Sstevel@tonic-gate 	 */
23907c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
23917c478bd9Sstevel@tonic-gate 		return (TRUE);
23927c478bd9Sstevel@tonic-gate 
23937c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
23947c478bd9Sstevel@tonic-gate 		return (FALSE);
23957c478bd9Sstevel@tonic-gate 
23967c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
23977c478bd9Sstevel@tonic-gate 		return (FALSE);
23987c478bd9Sstevel@tonic-gate 
23997c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
24007c478bd9Sstevel@tonic-gate 		return (FALSE);
24017c478bd9Sstevel@tonic-gate 
24027c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
24037c478bd9Sstevel@tonic-gate 		return (TRUE);
24047c478bd9Sstevel@tonic-gate 
24057c478bd9Sstevel@tonic-gate 	/*
24067c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
24077c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
24087c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
24097c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
24107c478bd9Sstevel@tonic-gate 	 */
24117c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
24127c478bd9Sstevel@tonic-gate 		return (FALSE);
24137c478bd9Sstevel@tonic-gate 
24147c478bd9Sstevel@tonic-gate 	dvp = objp->dir_attributes.fres.vp;
24157c478bd9Sstevel@tonic-gate 	rp = VTOR(dvp);
24167c478bd9Sstevel@tonic-gate 
24177c478bd9Sstevel@tonic-gate 	pov.fres.vap = &va;
24187c478bd9Sstevel@tonic-gate 	pov.fres.vp = dvp;
24197c478bd9Sstevel@tonic-gate 
24207c478bd9Sstevel@tonic-gate 	entries_size = objp->entries_size;
24217c478bd9Sstevel@tonic-gate 	dp = objp->entries;
24227c478bd9Sstevel@tonic-gate 
24237c478bd9Sstevel@tonic-gate 	for (;;) {
24247c478bd9Sstevel@tonic-gate 		uint_t this_reclen;
24257c478bd9Sstevel@tonic-gate 		bool_t valid;
24267c478bd9Sstevel@tonic-gate 		uint_t namlen;
24277c478bd9Sstevel@tonic-gate 		nfs_fh3 fh;
24287c478bd9Sstevel@tonic-gate 		int va_valid;
24297c478bd9Sstevel@tonic-gate 		int fh_valid;
24307c478bd9Sstevel@tonic-gate 		ino64_t fileid;
24317c478bd9Sstevel@tonic-gate 
24327c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
24337c478bd9Sstevel@tonic-gate 			return (FALSE);
24347c478bd9Sstevel@tonic-gate 		if (!valid) {
24357c478bd9Sstevel@tonic-gate 			/*
24367c478bd9Sstevel@tonic-gate 			 * We have run out of entries, decode eof.
24377c478bd9Sstevel@tonic-gate 			 */
24387c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
24397c478bd9Sstevel@tonic-gate 				return (FALSE);
24407c478bd9Sstevel@tonic-gate 
24417c478bd9Sstevel@tonic-gate 			break;
24427c478bd9Sstevel@tonic-gate 		}
24437c478bd9Sstevel@tonic-gate 
24447c478bd9Sstevel@tonic-gate 		/*
24457c478bd9Sstevel@tonic-gate 		 * fileid3 fileid
24467c478bd9Sstevel@tonic-gate 		 */
24477c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
24487c478bd9Sstevel@tonic-gate 			return (FALSE);
24497c478bd9Sstevel@tonic-gate 
24507c478bd9Sstevel@tonic-gate 		/*
24517c478bd9Sstevel@tonic-gate 		 * filename3 name
24527c478bd9Sstevel@tonic-gate 		 */
24537c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
24547c478bd9Sstevel@tonic-gate 			return (FALSE);
24557c478bd9Sstevel@tonic-gate 		this_reclen = DIRENT64_RECLEN(namlen);
24567c478bd9Sstevel@tonic-gate 
24577c478bd9Sstevel@tonic-gate 		/*
24587c478bd9Sstevel@tonic-gate 		 * If this will overflow buffer, stop decoding
24597c478bd9Sstevel@tonic-gate 		 */
24607c478bd9Sstevel@tonic-gate 		if ((outcount + this_reclen) > entries_size) {
24617c478bd9Sstevel@tonic-gate 			objp->eof = FALSE;
24627c478bd9Sstevel@tonic-gate 			break;
24637c478bd9Sstevel@tonic-gate 		}
24647c478bd9Sstevel@tonic-gate 		dp->d_reclen = this_reclen;
24657c478bd9Sstevel@tonic-gate 		dp->d_ino = fileid;
24667c478bd9Sstevel@tonic-gate 
24677c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, dp->d_name, namlen))
24687c478bd9Sstevel@tonic-gate 			return (FALSE);
24697c478bd9Sstevel@tonic-gate 		bzero(&dp->d_name[namlen],
24707c478bd9Sstevel@tonic-gate 		    DIRENT64_NAMELEN(this_reclen) - namlen);
24717c478bd9Sstevel@tonic-gate 
24727c478bd9Sstevel@tonic-gate 		/*
24737c478bd9Sstevel@tonic-gate 		 * cookie3 cookie
24747c478bd9Sstevel@tonic-gate 		 */
24757c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
24767c478bd9Sstevel@tonic-gate 			return (FALSE);
24777c478bd9Sstevel@tonic-gate 		objp->loff = dp->d_off;
24787c478bd9Sstevel@tonic-gate 
24797c478bd9Sstevel@tonic-gate 		/*
24807c478bd9Sstevel@tonic-gate 		 * post_op_attr name_attributes
24817c478bd9Sstevel@tonic-gate 		 */
24827c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_vattr(xdrs, &pov))
24837c478bd9Sstevel@tonic-gate 			return (FALSE);
24847c478bd9Sstevel@tonic-gate 
24857c478bd9Sstevel@tonic-gate 		if (pov.attributes == TRUE &&
24867c478bd9Sstevel@tonic-gate 		    pov.fres.status == NFS3_OK)
24877c478bd9Sstevel@tonic-gate 			va_valid = TRUE;
24887c478bd9Sstevel@tonic-gate 		else
24897c478bd9Sstevel@tonic-gate 			va_valid = FALSE;
24907c478bd9Sstevel@tonic-gate 
24917c478bd9Sstevel@tonic-gate 		/*
24927c478bd9Sstevel@tonic-gate 		 * post_op_fh3 name_handle
24937c478bd9Sstevel@tonic-gate 		 */
24947c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&fh_valid))
24957c478bd9Sstevel@tonic-gate 			return (FALSE);
24967c478bd9Sstevel@tonic-gate 
24977c478bd9Sstevel@tonic-gate 		/*
24987c478bd9Sstevel@tonic-gate 		 * By definition of the standard fh_valid can be 0 (FALSE) or
24997c478bd9Sstevel@tonic-gate 		 * 1 (TRUE), but we have to account for it being anything else
25007c478bd9Sstevel@tonic-gate 		 * in case some other system didn't follow the standard.  Note
25017c478bd9Sstevel@tonic-gate 		 * that this is why the else checks if the fh_valid variable
25027c478bd9Sstevel@tonic-gate 		 * is != FALSE.
25037c478bd9Sstevel@tonic-gate 		 */
25047c478bd9Sstevel@tonic-gate 		if (fh_valid == TRUE) {
25057c478bd9Sstevel@tonic-gate 			if (!xdr_nfs_fh3(xdrs, &fh))
25067c478bd9Sstevel@tonic-gate 				return (FALSE);
25077c478bd9Sstevel@tonic-gate 		} else {
25087c478bd9Sstevel@tonic-gate 			if (fh_valid != FALSE)
25097c478bd9Sstevel@tonic-gate 				return (FALSE);
25107c478bd9Sstevel@tonic-gate 		}
25117c478bd9Sstevel@tonic-gate 
25127c478bd9Sstevel@tonic-gate 		/*
25137c478bd9Sstevel@tonic-gate 		 * If the name is "." or there are no attributes,
25147c478bd9Sstevel@tonic-gate 		 * don't polute the DNLC with "." entries or files
25157c478bd9Sstevel@tonic-gate 		 * we cannot determine the type for.
25167c478bd9Sstevel@tonic-gate 		 */
25177c478bd9Sstevel@tonic-gate 		if (!(namlen == 1 && dp->d_name[0] == '.') &&
25187c478bd9Sstevel@tonic-gate 		    va_valid && fh_valid) {
25197c478bd9Sstevel@tonic-gate 
25207c478bd9Sstevel@tonic-gate 			/*
25217c478bd9Sstevel@tonic-gate 			 * Do the DNLC caching
25227c478bd9Sstevel@tonic-gate 			 */
25237c478bd9Sstevel@tonic-gate 			nvp = makenfs3node_va(&fh, &va, dvp->v_vfsp,
25247c478bd9Sstevel@tonic-gate 			    objp->time, objp->credentials,
25257c478bd9Sstevel@tonic-gate 			    rp->r_path, dp->d_name);
25267c478bd9Sstevel@tonic-gate 			dnlc_update(dvp, dp->d_name, nvp);
25277c478bd9Sstevel@tonic-gate 			VN_RELE(nvp);
25287c478bd9Sstevel@tonic-gate 		}
25297c478bd9Sstevel@tonic-gate 
25307c478bd9Sstevel@tonic-gate 		outcount += this_reclen;
25317c478bd9Sstevel@tonic-gate 		dp = (dirent64_t *)((intptr_t)dp + this_reclen);
25327c478bd9Sstevel@tonic-gate 	}
25337c478bd9Sstevel@tonic-gate 
25347c478bd9Sstevel@tonic-gate 	objp->size = outcount;
25357c478bd9Sstevel@tonic-gate 	return (TRUE);
25367c478bd9Sstevel@tonic-gate }
25377c478bd9Sstevel@tonic-gate 
25387c478bd9Sstevel@tonic-gate bool_t
25397c478bd9Sstevel@tonic-gate xdr_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp)
25407c478bd9Sstevel@tonic-gate {
25417c478bd9Sstevel@tonic-gate 	FSSTAT3resok *resokp;
25427c478bd9Sstevel@tonic-gate 
25437c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
25447c478bd9Sstevel@tonic-gate 		return (FALSE);
25457c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
25467c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
25477c478bd9Sstevel@tonic-gate 
25487c478bd9Sstevel@tonic-gate 	/* xdr_FSSTAT3resok */
25497c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
25507c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
25517c478bd9Sstevel@tonic-gate 		return (FALSE);
25527c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->tbytes))
25537c478bd9Sstevel@tonic-gate 		return (FALSE);
25547c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->fbytes))
25557c478bd9Sstevel@tonic-gate 		return (FALSE);
25567c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->abytes))
25577c478bd9Sstevel@tonic-gate 		return (FALSE);
25587c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->tfiles))
25597c478bd9Sstevel@tonic-gate 		return (FALSE);
25607c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->ffiles))
25617c478bd9Sstevel@tonic-gate 		return (FALSE);
25627c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->afiles))
25637c478bd9Sstevel@tonic-gate 		return (FALSE);
25647c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &resokp->invarsec));
25657c478bd9Sstevel@tonic-gate }
25667c478bd9Sstevel@tonic-gate 
25677c478bd9Sstevel@tonic-gate bool_t
25687c478bd9Sstevel@tonic-gate xdr_FSINFO3res(XDR *xdrs, FSINFO3res *objp)
25697c478bd9Sstevel@tonic-gate {
25707c478bd9Sstevel@tonic-gate 	FSINFO3resok *resokp;
25717c478bd9Sstevel@tonic-gate 
25727c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
25737c478bd9Sstevel@tonic-gate 		return (FALSE);
25747c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK) /* xdr_FSSTAT3resfail */
25757c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
25767c478bd9Sstevel@tonic-gate 
25777c478bd9Sstevel@tonic-gate 	/* xdr_FSINFO3resok */
25787c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
25797c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
25807c478bd9Sstevel@tonic-gate 		return (FALSE);
25817c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->rtmax))
25827c478bd9Sstevel@tonic-gate 		return (FALSE);
25837c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->rtpref))
25847c478bd9Sstevel@tonic-gate 		return (FALSE);
25857c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->rtmult))
25867c478bd9Sstevel@tonic-gate 		return (FALSE);
25877c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->wtmax))
25887c478bd9Sstevel@tonic-gate 		return (FALSE);
25897c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->wtpref))
25907c478bd9Sstevel@tonic-gate 		return (FALSE);
25917c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->wtmult))
25927c478bd9Sstevel@tonic-gate 		return (FALSE);
25937c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->dtpref))
25947c478bd9Sstevel@tonic-gate 		return (FALSE);
25957c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->maxfilesize))
25967c478bd9Sstevel@tonic-gate 		return (FALSE);
25977c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->time_delta.seconds))
25987c478bd9Sstevel@tonic-gate 		return (FALSE);
25997c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->time_delta.nseconds))
26007c478bd9Sstevel@tonic-gate 		return (FALSE);
26017c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &resokp->properties));
26027c478bd9Sstevel@tonic-gate }
26037c478bd9Sstevel@tonic-gate 
26047c478bd9Sstevel@tonic-gate bool_t
26057c478bd9Sstevel@tonic-gate xdr_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp)
26067c478bd9Sstevel@tonic-gate {
26077c478bd9Sstevel@tonic-gate 	PATHCONF3resok *resokp;
26087c478bd9Sstevel@tonic-gate 
26097c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
26107c478bd9Sstevel@tonic-gate 		return (FALSE);
26117c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
26127c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
26137c478bd9Sstevel@tonic-gate 
26147c478bd9Sstevel@tonic-gate 	/* xdr_PATHCONF3resok */
26157c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
26167c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
26177c478bd9Sstevel@tonic-gate 		return (FALSE);
26187c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->info.link_max))
26197c478bd9Sstevel@tonic-gate 		return (FALSE);
26207c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->info.name_max))
26217c478bd9Sstevel@tonic-gate 		return (FALSE);
26227c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &resokp->info.no_trunc))
26237c478bd9Sstevel@tonic-gate 		return (FALSE);
26247c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &resokp->info.chown_restricted))
26257c478bd9Sstevel@tonic-gate 		return (FALSE);
26267c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &resokp->info.case_insensitive))
26277c478bd9Sstevel@tonic-gate 		return (FALSE);
26287c478bd9Sstevel@tonic-gate 	return (xdr_bool(xdrs, &resokp->info.case_preserving));
26297c478bd9Sstevel@tonic-gate }
26307c478bd9Sstevel@tonic-gate 
26317c478bd9Sstevel@tonic-gate bool_t
26327c478bd9Sstevel@tonic-gate xdr_COMMIT3args(XDR *xdrs, COMMIT3args *objp)
26337c478bd9Sstevel@tonic-gate {
26347c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
26357c478bd9Sstevel@tonic-gate 		return (TRUE);
26367c478bd9Sstevel@tonic-gate 
263727242a7cSthurlow 	switch (xdrs->x_op) {
263827242a7cSthurlow 	case XDR_FREE:
263927242a7cSthurlow 	case XDR_ENCODE:
26407c478bd9Sstevel@tonic-gate 		if (!xdr_nfs_fh3(xdrs, &objp->file))
26417c478bd9Sstevel@tonic-gate 			return (FALSE);
264227242a7cSthurlow 		break;
264327242a7cSthurlow 	case XDR_DECODE:
264427242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
264527242a7cSthurlow 			return (FALSE);
264627242a7cSthurlow 		break;
264727242a7cSthurlow 	}
26487c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->offset))
26497c478bd9Sstevel@tonic-gate 		return (FALSE);
26507c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->count));
26517c478bd9Sstevel@tonic-gate }
26527c478bd9Sstevel@tonic-gate 
26537c478bd9Sstevel@tonic-gate bool_t
26547c478bd9Sstevel@tonic-gate xdr_COMMIT3res(XDR *xdrs, COMMIT3res *objp)
26557c478bd9Sstevel@tonic-gate {
26567c478bd9Sstevel@tonic-gate 	COMMIT3resok *resokp;
26577c478bd9Sstevel@tonic-gate 
26587c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
26597c478bd9Sstevel@tonic-gate 		return (FALSE);
26607c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
26617c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
26627c478bd9Sstevel@tonic-gate 
26637c478bd9Sstevel@tonic-gate 	/* xdr_COMMIT3resok */
26647c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
26657c478bd9Sstevel@tonic-gate 	if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
26667c478bd9Sstevel@tonic-gate 		return (FALSE);
26677c478bd9Sstevel@tonic-gate 	/*
26687c478bd9Sstevel@tonic-gate 	 * writeverf3 is really an opaque 8 byte
26697c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
26707c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
26717c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
26727c478bd9Sstevel@tonic-gate 	 */
26737c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, &resokp->verf));
26747c478bd9Sstevel@tonic-gate }
2675