xref: /illumos-gate/usr/src/uts/common/fs/nfs/nfs3_xdr.c (revision a494169a)
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 
29e36d7b11SSebastien Roy /*
30e36d7b11SSebastien Roy  * Copyright (c) 2013 by Delphix. All rights reserved.
31e36d7b11SSebastien Roy  */
32e36d7b11SSebastien 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
xdr_string3(XDR * xdrs,char ** cpp,uint_t maxsize)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
xdr_inline_decode_nfs_fh3(uint32_t * ptr,nfs_fh3 * fhp,uint32_t fhsize)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;
16427242a7cSthurlow 
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);
17527242a7cSthurlow 	}
17627242a7cSthurlow 
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);
2177c478bd9Sstevel@tonic-gate 
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);
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate 
24827242a7cSthurlow static bool_t
xdr_decode_nfs_fh3(XDR * xdrs,nfs_fh3 * objp)24927242a7cSthurlow xdr_decode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
2507c478bd9Sstevel@tonic-gate {
25127242a7cSthurlow 	uint32_t fhsize;		/* filehandle size */
25227242a7cSthurlow 	uint32_t bufsize;
25327242a7cSthurlow 	rpc_inline_t *ptr;
25427242a7cSthurlow 	uchar_t *bp;
2557c478bd9Sstevel@tonic-gate 
25627242a7cSthurlow 	ASSERT(xdrs->x_op == XDR_DECODE);
2577c478bd9Sstevel@tonic-gate 
25827242a7cSthurlow 	/*
25927242a7cSthurlow 	 * Retrieve the filehandle length.
26027242a7cSthurlow 	 */
26127242a7cSthurlow 	if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
26227242a7cSthurlow 		return (FALSE);
2637c478bd9Sstevel@tonic-gate 
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);
2927c478bd9Sstevel@tonic-gate 		}
2937c478bd9Sstevel@tonic-gate 	}
2947c478bd9Sstevel@tonic-gate 
29527242a7cSthurlow 	objp->fh3_length = sizeof (fhandle3_t);
2967c478bd9Sstevel@tonic-gate 
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 	}
3077c478bd9Sstevel@tonic-gate 
30827242a7cSthurlow 	if (ptr == NULL)
30927242a7cSthurlow 		kmem_free(bp, bufsize);
31027242a7cSthurlow 	return (TRUE);
3117c478bd9Sstevel@tonic-gate }
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate /*
31427242a7cSthurlow  * XDR_INLINE encode a filehandle.
3157c478bd9Sstevel@tonic-gate  */
3167c478bd9Sstevel@tonic-gate bool_t
xdr_inline_encode_nfs_fh3(uint32_t ** ptrp,uint32_t * ptr_redzone,nfs_fh3 * fhp)31727242a7cSthurlow xdr_inline_encode_nfs_fh3(uint32_t **ptrp, uint32_t *ptr_redzone,
318*a494169aSToomas Soome     nfs_fh3 *fhp)
3197c478bd9Sstevel@tonic-gate {
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;
3247c478bd9Sstevel@tonic-gate 
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)
3457c478bd9Sstevel@tonic-gate 		return (FALSE);
3467c478bd9Sstevel@tonic-gate 
34727242a7cSthurlow 	/*
34827242a7cSthurlow 	 * Zero out the pading.
34927242a7cSthurlow 	 */
35027242a7cSthurlow 	ptr[padword] = 0;
3517c478bd9Sstevel@tonic-gate 
35227242a7cSthurlow 	IXDR_PUT_U_INT32(ptr, otw_len);
3537c478bd9Sstevel@tonic-gate 
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);
3877c478bd9Sstevel@tonic-gate }
3887c478bd9Sstevel@tonic-gate 
38927242a7cSthurlow static bool_t
xdr_encode_nfs_fh3(XDR * xdrs,nfs_fh3 * objp)39027242a7cSthurlow xdr_encode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
3917c478bd9Sstevel@tonic-gate {
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;
3977c478bd9Sstevel@tonic-gate 
39827242a7cSthurlow 	ASSERT(xdrs->x_op == XDR_ENCODE);
3997c478bd9Sstevel@tonic-gate 
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);
4327c478bd9Sstevel@tonic-gate 	}
43327242a7cSthurlow 	return (ret);
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate 
43627242a7cSthurlow /*
43727242a7cSthurlow  * XDR a NFSv3 filehandle the naive way.
43827242a7cSthurlow  */
4397c478bd9Sstevel@tonic-gate bool_t
xdr_nfs_fh3(XDR * xdrs,nfs_fh3 * objp)44027242a7cSthurlow xdr_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
4417c478bd9Sstevel@tonic-gate {
44227242a7cSthurlow 	if (xdrs->x_op == XDR_FREE)
44327242a7cSthurlow 		return (TRUE);
4447c478bd9Sstevel@tonic-gate 
44527242a7cSthurlow 	if (!xdr_u_int(xdrs, &objp->fh3_length))
4467c478bd9Sstevel@tonic-gate 		return (FALSE);
4477c478bd9Sstevel@tonic-gate 
44827242a7cSthurlow 	if (objp->fh3_length > NFS3_FHSIZE)
44927242a7cSthurlow 		return (FALSE);
4507c478bd9Sstevel@tonic-gate 
45127242a7cSthurlow 	return (xdr_opaque(xdrs, objp->fh3_u.data, objp->fh3_length));
45227242a7cSthurlow }
4537c478bd9Sstevel@tonic-gate 
45427242a7cSthurlow /*
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.
45827242a7cSthurlow  */
45927242a7cSthurlow bool_t
xdr_nfs_fh3_server(XDR * xdrs,nfs_fh3 * objp)46027242a7cSthurlow xdr_nfs_fh3_server(XDR *xdrs, nfs_fh3 *objp)
46127242a7cSthurlow {
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
4676a8ebdc3Sthurlow 			return (xdr_encode_nfs_fh3(xdrs, objp));
46827242a7cSthurlow 	case XDR_DECODE:
46927242a7cSthurlow 		return (xdr_decode_nfs_fh3(xdrs, objp));
47027242a7cSthurlow 	case XDR_FREE:
471*a494169aSToomas Soome 		bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
47227242a7cSthurlow 		return (TRUE);
4737c478bd9Sstevel@tonic-gate 	}
4747c478bd9Sstevel@tonic-gate 	return (FALSE);
4757c478bd9Sstevel@tonic-gate }
4767c478bd9Sstevel@tonic-gate 
47727242a7cSthurlow bool_t
xdr_diropargs3(XDR * xdrs,diropargs3 * objp)47827242a7cSthurlow xdr_diropargs3(XDR *xdrs, diropargs3 *objp)
47927242a7cSthurlow {
48027242a7cSthurlow 	switch (xdrs->x_op) {
48127242a7cSthurlow 	case XDR_FREE:
48227242a7cSthurlow 	case XDR_ENCODE:
48327242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, objp->dirp))
48427242a7cSthurlow 			return (FALSE);
48527242a7cSthurlow 		break;
48627242a7cSthurlow 	case XDR_DECODE:
48727242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
48827242a7cSthurlow 			return (FALSE);
48927242a7cSthurlow 		break;
49027242a7cSthurlow 	}
49127242a7cSthurlow 	return (xdr_string3(xdrs, &objp->name, MAXNAMELEN));
49227242a7cSthurlow }
49327242a7cSthurlow 
4947c478bd9Sstevel@tonic-gate static bool_t
xdr_fattr3(XDR * xdrs,fattr3 * na)4957c478bd9Sstevel@tonic-gate xdr_fattr3(XDR *xdrs, fattr3 *na)
4967c478bd9Sstevel@tonic-gate {
4977c478bd9Sstevel@tonic-gate 	int32_t *ptr;
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
5007c478bd9Sstevel@tonic-gate 		return (TRUE);
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
5037c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
5047c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
5057c478bd9Sstevel@tonic-gate 			na->type = IXDR_GET_ENUM(ptr, enum ftype3);
5067c478bd9Sstevel@tonic-gate 			na->mode = IXDR_GET_U_INT32(ptr);
5077c478bd9Sstevel@tonic-gate 			na->nlink = IXDR_GET_U_INT32(ptr);
5087c478bd9Sstevel@tonic-gate 			na->uid = IXDR_GET_U_INT32(ptr);
5097c478bd9Sstevel@tonic-gate 			na->gid = IXDR_GET_U_INT32(ptr);
5107c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, na->size);
5117c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, na->used);
5127c478bd9Sstevel@tonic-gate 			na->rdev.specdata1 = IXDR_GET_U_INT32(ptr);
5137c478bd9Sstevel@tonic-gate 			na->rdev.specdata2 = IXDR_GET_U_INT32(ptr);
5147c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, na->fsid);
5157c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, na->fileid);
5167c478bd9Sstevel@tonic-gate 			na->atime.seconds = IXDR_GET_U_INT32(ptr);
5177c478bd9Sstevel@tonic-gate 			na->atime.nseconds = IXDR_GET_U_INT32(ptr);
5187c478bd9Sstevel@tonic-gate 			na->mtime.seconds = IXDR_GET_U_INT32(ptr);
5197c478bd9Sstevel@tonic-gate 			na->mtime.nseconds = IXDR_GET_U_INT32(ptr);
5207c478bd9Sstevel@tonic-gate 			na->ctime.seconds = IXDR_GET_U_INT32(ptr);
5217c478bd9Sstevel@tonic-gate 			na->ctime.nseconds = IXDR_GET_U_INT32(ptr);
5227c478bd9Sstevel@tonic-gate 		} else {
5237c478bd9Sstevel@tonic-gate 			IXDR_PUT_ENUM(ptr, na->type);
5247c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->mode);
5257c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->nlink);
5267c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->uid);
5277c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->gid);
5287c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_HYPER(ptr, na->size);
5297c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_HYPER(ptr, na->used);
5307c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->rdev.specdata1);
5317c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->rdev.specdata2);
5327c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_HYPER(ptr, na->fsid);
5337c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_HYPER(ptr, na->fileid);
5347c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->atime.seconds);
5357c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->atime.nseconds);
5367c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->mtime.seconds);
5377c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->mtime.nseconds);
5387c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->ctime.seconds);
5397c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, na->ctime.nseconds);
5407c478bd9Sstevel@tonic-gate 		}
5417c478bd9Sstevel@tonic-gate 		return (TRUE);
5427c478bd9Sstevel@tonic-gate 	}
5437c478bd9Sstevel@tonic-gate 	if (!(xdr_enum(xdrs, (enum_t *)&na->type) &&
5440a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->mode) &&
5450a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->nlink) &&
5460a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->uid) &&
5470a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->gid) &&
5480a701b1eSRobert Gordon 	    xdr_u_longlong_t(xdrs, &na->size) &&
5490a701b1eSRobert Gordon 	    xdr_u_longlong_t(xdrs, &na->used) &&
5500a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->rdev.specdata1) &&
5510a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->rdev.specdata2) &&
5520a701b1eSRobert Gordon 	    xdr_u_longlong_t(xdrs, &na->fsid) &&
5530a701b1eSRobert Gordon 	    xdr_u_longlong_t(xdrs, &na->fileid) &&
5540a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->atime.seconds) &&
5550a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->atime.nseconds) &&
5560a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->mtime.seconds) &&
5570a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->mtime.nseconds) &&
5580a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->ctime.seconds) &&
5590a701b1eSRobert Gordon 	    xdr_u_int(xdrs, &na->ctime.nseconds)))
560*a494169aSToomas Soome 		return (FALSE);
5617c478bd9Sstevel@tonic-gate 	return (TRUE);
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate /*
5657c478bd9Sstevel@tonic-gate  * Fast decode of an fattr3 to a vattr
5667c478bd9Sstevel@tonic-gate  * Only return FALSE on decode error, all other fattr to vattr translation
5677c478bd9Sstevel@tonic-gate  * failures set status.
5687c478bd9Sstevel@tonic-gate  *
5697c478bd9Sstevel@tonic-gate  * Callers must catch the following errors:
5707c478bd9Sstevel@tonic-gate  *	EFBIG - file size will not fit in va_size
5717c478bd9Sstevel@tonic-gate  *	EOVERFLOW - time will not fit in va_*time
5727c478bd9Sstevel@tonic-gate  */
5737c478bd9Sstevel@tonic-gate static bool_t
xdr_fattr3_to_vattr(XDR * xdrs,fattr3_res * objp)5747c478bd9Sstevel@tonic-gate xdr_fattr3_to_vattr(XDR *xdrs, fattr3_res *objp)
5757c478bd9Sstevel@tonic-gate {
5767c478bd9Sstevel@tonic-gate 	int32_t *ptr;
5777c478bd9Sstevel@tonic-gate 	size3 used;
5787c478bd9Sstevel@tonic-gate 	specdata3 rdev;
5797c478bd9Sstevel@tonic-gate 	uint32_t ntime;
5807c478bd9Sstevel@tonic-gate 	vattr_t *vap = objp->vap;
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 	/*
5837c478bd9Sstevel@tonic-gate 	 * DECODE only
5847c478bd9Sstevel@tonic-gate 	 */
5857c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
5867c478bd9Sstevel@tonic-gate 
5871e96f9d6SRich Brown 	/* On success, all attributes will be decoded */
5881e96f9d6SRich Brown 	vap->va_mask = AT_ALL;
5891e96f9d6SRich Brown 
5907c478bd9Sstevel@tonic-gate 	objp->status = 0;
5917c478bd9Sstevel@tonic-gate 	ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
5927c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
5937c478bd9Sstevel@tonic-gate 		/*
5947c478bd9Sstevel@tonic-gate 		 * Common case
5957c478bd9Sstevel@tonic-gate 		 */
5967c478bd9Sstevel@tonic-gate 		vap->va_type = IXDR_GET_ENUM(ptr, enum vtype);
5972c2d21e9SRichard Lowe 		if ((ftype3)vap->va_type < NF3REG ||
5982c2d21e9SRichard Lowe 		    (ftype3)vap->va_type > NF3FIFO)
5997c478bd9Sstevel@tonic-gate 			vap->va_type = VBAD;
6007c478bd9Sstevel@tonic-gate 		else
6017c478bd9Sstevel@tonic-gate 			vap->va_type = nf3_to_vt[vap->va_type];
6027c478bd9Sstevel@tonic-gate 		vap->va_mode = IXDR_GET_U_INT32(ptr);
6037c478bd9Sstevel@tonic-gate 		vap->va_nlink = IXDR_GET_U_INT32(ptr);
6047c478bd9Sstevel@tonic-gate 		vap->va_uid = (uid_t)IXDR_GET_U_INT32(ptr);
6057c478bd9Sstevel@tonic-gate 		if (vap->va_uid == NFS_UID_NOBODY)
6067c478bd9Sstevel@tonic-gate 			vap->va_uid = UID_NOBODY;
6077c478bd9Sstevel@tonic-gate 		vap->va_gid = (gid_t)IXDR_GET_U_INT32(ptr);
6087c478bd9Sstevel@tonic-gate 		if (vap->va_gid == NFS_GID_NOBODY)
6097c478bd9Sstevel@tonic-gate 			vap->va_gid = GID_NOBODY;
6107c478bd9Sstevel@tonic-gate 		IXDR_GET_U_HYPER(ptr, vap->va_size);
6117c478bd9Sstevel@tonic-gate 		/*
6127c478bd9Sstevel@tonic-gate 		 * If invalid size, stop decode, set status, and
6137c478bd9Sstevel@tonic-gate 		 * return TRUE, x_handy will be correct, caller must ignore vap.
6147c478bd9Sstevel@tonic-gate 		 */
6157c478bd9Sstevel@tonic-gate 		if (!NFS3_SIZE_OK(vap->va_size)) {
6167c478bd9Sstevel@tonic-gate 			objp->status = EFBIG;
6177c478bd9Sstevel@tonic-gate 			return (TRUE);
6187c478bd9Sstevel@tonic-gate 		}
6197c478bd9Sstevel@tonic-gate 		IXDR_GET_U_HYPER(ptr, used);
6207c478bd9Sstevel@tonic-gate 		rdev.specdata1 = IXDR_GET_U_INT32(ptr);
6217c478bd9Sstevel@tonic-gate 		rdev.specdata2 = IXDR_GET_U_INT32(ptr);
6227c478bd9Sstevel@tonic-gate 		/* fsid is ignored */
6237c478bd9Sstevel@tonic-gate 		ptr += 2;
6247c478bd9Sstevel@tonic-gate 		IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 		/*
6277c478bd9Sstevel@tonic-gate 		 * nfs protocol defines times as unsigned so don't
6287c478bd9Sstevel@tonic-gate 		 * extend sign, unless sysadmin set nfs_allow_preepoch_time.
6297c478bd9Sstevel@tonic-gate 		 * The inline macros do the equivilant of NFS_TIME_T_CONVERT
6307c478bd9Sstevel@tonic-gate 		 */
6317c478bd9Sstevel@tonic-gate 		if (nfs_allow_preepoch_time) {
6327c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_sec = IXDR_GET_INT32(ptr);
6337c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
6347c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_sec = IXDR_GET_INT32(ptr);
6357c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
6367c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_sec = IXDR_GET_INT32(ptr);
6377c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
6387c478bd9Sstevel@tonic-gate 		} else {
6397c478bd9Sstevel@tonic-gate 			/*
6407c478bd9Sstevel@tonic-gate 			 * Check if the time would overflow on 32-bit
6417c478bd9Sstevel@tonic-gate 			 */
6427c478bd9Sstevel@tonic-gate 			ntime = IXDR_GET_U_INT32(ptr);
6437c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
6447c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
6457c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
6467c478bd9Sstevel@tonic-gate 				return (TRUE);
6477c478bd9Sstevel@tonic-gate 			}
6487c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_sec = ntime;
6497c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate 			ntime = IXDR_GET_U_INT32(ptr);
6527c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
6537c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
6547c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
6557c478bd9Sstevel@tonic-gate 				return (TRUE);
6567c478bd9Sstevel@tonic-gate 			}
6577c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_sec = ntime;
6587c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 			ntime = IXDR_GET_U_INT32(ptr);
6617c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
6627c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
6637c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
6647c478bd9Sstevel@tonic-gate 				return (TRUE);
6657c478bd9Sstevel@tonic-gate 			}
6667c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_sec = ntime;
6677c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
6687c478bd9Sstevel@tonic-gate 		}
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 	} else {
6717c478bd9Sstevel@tonic-gate 		uint64 fsid;
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate 		/*
6747c478bd9Sstevel@tonic-gate 		 * Slow path
6757c478bd9Sstevel@tonic-gate 		 */
6767c478bd9Sstevel@tonic-gate 		if (!(xdr_enum(xdrs, (enum_t *)&vap->va_type) &&
6770a701b1eSRobert Gordon 		    xdr_u_int(xdrs, &vap->va_mode) &&
6780a701b1eSRobert Gordon 		    xdr_u_int(xdrs, &vap->va_nlink) &&
6790a701b1eSRobert Gordon 		    xdr_u_int(xdrs, (uint_t *)&vap->va_uid) &&
6800a701b1eSRobert Gordon 		    xdr_u_int(xdrs, (uint_t *)&vap->va_gid) &&
6810a701b1eSRobert Gordon 		    xdr_u_longlong_t(xdrs, &vap->va_size) &&
6820a701b1eSRobert Gordon 		    xdr_u_longlong_t(xdrs, &used) &&
6830a701b1eSRobert Gordon 		    xdr_u_int(xdrs, &rdev.specdata1) &&
6840a701b1eSRobert Gordon 		    xdr_u_int(xdrs, &rdev.specdata2) &&
6850a701b1eSRobert Gordon 		    xdr_u_longlong_t(xdrs, &fsid) &&	/* ignored */
6860a701b1eSRobert Gordon 		    xdr_u_longlong_t(xdrs, &vap->va_nodeid)))
6877c478bd9Sstevel@tonic-gate 				return (FALSE);
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate 		if (nfs_allow_preepoch_time) {
6907c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
6917c478bd9Sstevel@tonic-gate 				return (FALSE);
6927c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_sec = (int32_t)ntime;
6937c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
6947c478bd9Sstevel@tonic-gate 				return (FALSE);
6957c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_nsec = ntime;
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
6987c478bd9Sstevel@tonic-gate 				return (FALSE);
6997c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_sec = (int32_t)ntime;
7007c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7017c478bd9Sstevel@tonic-gate 				return (FALSE);
7027c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_nsec = ntime;
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7057c478bd9Sstevel@tonic-gate 				return (FALSE);
7067c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_sec = (int32_t)ntime;
7077c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7087c478bd9Sstevel@tonic-gate 				return (FALSE);
7097c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_nsec = ntime;
7107c478bd9Sstevel@tonic-gate 		} else {
7117c478bd9Sstevel@tonic-gate 			/*
7127c478bd9Sstevel@tonic-gate 			 * Check if the time would overflow on 32-bit
7137c478bd9Sstevel@tonic-gate 			 * Set status and keep decoding stream.
7147c478bd9Sstevel@tonic-gate 			 */
7157c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7167c478bd9Sstevel@tonic-gate 				return (FALSE);
7177c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
7187c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
7197c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
7207c478bd9Sstevel@tonic-gate 			}
7217c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_sec = ntime;
7227c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7237c478bd9Sstevel@tonic-gate 				return (FALSE);
7247c478bd9Sstevel@tonic-gate 			vap->va_atime.tv_nsec = ntime;
7257c478bd9Sstevel@tonic-gate 
7267c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7277c478bd9Sstevel@tonic-gate 				return (FALSE);
7287c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
7297c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
7307c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
7317c478bd9Sstevel@tonic-gate 			}
7327c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_sec = ntime;
7337c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7347c478bd9Sstevel@tonic-gate 				return (FALSE);
7357c478bd9Sstevel@tonic-gate 			vap->va_mtime.tv_nsec = ntime;
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7387c478bd9Sstevel@tonic-gate 				return (FALSE);
7397c478bd9Sstevel@tonic-gate 			/*CONSTCOND*/
7407c478bd9Sstevel@tonic-gate 			if (NFS3_TIME_OVERFLOW(ntime)) {
7417c478bd9Sstevel@tonic-gate 				objp->status = EOVERFLOW;
7427c478bd9Sstevel@tonic-gate 			}
7437c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_sec = ntime;
7447c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ntime))
7457c478bd9Sstevel@tonic-gate 				return (FALSE);
7467c478bd9Sstevel@tonic-gate 			vap->va_ctime.tv_nsec = ntime;
7477c478bd9Sstevel@tonic-gate 		}
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate 		/*
7507c478bd9Sstevel@tonic-gate 		 * Fixup as needed
7517c478bd9Sstevel@tonic-gate 		 */
7522c2d21e9SRichard Lowe 		if ((ftype3)vap->va_type < NF3REG ||
7532c2d21e9SRichard Lowe 		    (ftype3)vap->va_type > NF3FIFO)
7547c478bd9Sstevel@tonic-gate 			vap->va_type = VBAD;
7557c478bd9Sstevel@tonic-gate 		else
7567c478bd9Sstevel@tonic-gate 			vap->va_type = nf3_to_vt[vap->va_type];
7577c478bd9Sstevel@tonic-gate 		if (vap->va_uid == NFS_UID_NOBODY)
7587c478bd9Sstevel@tonic-gate 			vap->va_uid = UID_NOBODY;
7597c478bd9Sstevel@tonic-gate 		if (vap->va_gid == NFS_GID_NOBODY)
7607c478bd9Sstevel@tonic-gate 			vap->va_gid = GID_NOBODY;
7617c478bd9Sstevel@tonic-gate 		/*
7627c478bd9Sstevel@tonic-gate 		 * If invalid size, set status, and
7637c478bd9Sstevel@tonic-gate 		 * return TRUE, caller must ignore vap.
7647c478bd9Sstevel@tonic-gate 		 */
7657c478bd9Sstevel@tonic-gate 		if (!NFS3_SIZE_OK(vap->va_size)) {
7667c478bd9Sstevel@tonic-gate 			objp->status = EFBIG;
7677c478bd9Sstevel@tonic-gate 			return (TRUE);
7687c478bd9Sstevel@tonic-gate 		}
7697c478bd9Sstevel@tonic-gate 	}
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate 	/*
7727c478bd9Sstevel@tonic-gate 	 * Fill in derived fields
7737c478bd9Sstevel@tonic-gate 	 */
7747c478bd9Sstevel@tonic-gate 	vap->va_fsid = objp->vp->v_vfsp->vfs_dev;
7757c478bd9Sstevel@tonic-gate 	vap->va_seq = 0;
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate 	/*
7787c478bd9Sstevel@tonic-gate 	 * Common case values
7797c478bd9Sstevel@tonic-gate 	 */
7807c478bd9Sstevel@tonic-gate 	vap->va_rdev = 0;
7817c478bd9Sstevel@tonic-gate 	vap->va_blksize = MAXBSIZE;
7827c478bd9Sstevel@tonic-gate 	vap->va_nblocks = 0;
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate 	switch (vap->va_type) {
7857c478bd9Sstevel@tonic-gate 	case VREG:
7867c478bd9Sstevel@tonic-gate 	case VDIR:
7877c478bd9Sstevel@tonic-gate 	case VLNK:
7887c478bd9Sstevel@tonic-gate 		vap->va_nblocks = (u_longlong_t)
7890a701b1eSRobert Gordon 		    ((used + (size3)DEV_BSIZE - (size3)1) /
7900a701b1eSRobert Gordon 		    (size3)DEV_BSIZE);
7917c478bd9Sstevel@tonic-gate 		break;
7927c478bd9Sstevel@tonic-gate 	case VBLK:
7937c478bd9Sstevel@tonic-gate 		vap->va_blksize = DEV_BSIZE;
7947c478bd9Sstevel@tonic-gate 		/* FALLTHRU */
7957c478bd9Sstevel@tonic-gate 	case VCHR:
7967c478bd9Sstevel@tonic-gate 		vap->va_rdev = makedevice(rdev.specdata1, rdev.specdata2);
7977c478bd9Sstevel@tonic-gate 		break;
7987c478bd9Sstevel@tonic-gate 	case VSOCK:
7997c478bd9Sstevel@tonic-gate 	case VFIFO:
8007c478bd9Sstevel@tonic-gate 	default:
8017c478bd9Sstevel@tonic-gate 		break;
8027c478bd9Sstevel@tonic-gate 	}
8037c478bd9Sstevel@tonic-gate 
8047c478bd9Sstevel@tonic-gate 	return (TRUE);
8057c478bd9Sstevel@tonic-gate }
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate static bool_t
xdr_post_op_vattr(XDR * xdrs,post_op_vattr * objp)8087c478bd9Sstevel@tonic-gate xdr_post_op_vattr(XDR *xdrs, post_op_vattr *objp)
8097c478bd9Sstevel@tonic-gate {
8107c478bd9Sstevel@tonic-gate 	/*
8117c478bd9Sstevel@tonic-gate 	 * DECODE only
8127c478bd9Sstevel@tonic-gate 	 */
8137c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->attributes))
8167c478bd9Sstevel@tonic-gate 		return (FALSE);
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 	if (objp->attributes == FALSE)
8197c478bd9Sstevel@tonic-gate 		return (TRUE);
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate 	if (objp->attributes != TRUE)
8227c478bd9Sstevel@tonic-gate 		return (FALSE);
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate 	if (!xdr_fattr3_to_vattr(xdrs, &objp->fres))
8257c478bd9Sstevel@tonic-gate 		return (FALSE);
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 	/*
8287c478bd9Sstevel@tonic-gate 	 * The file size may cause an EFBIG or the time values
8297c478bd9Sstevel@tonic-gate 	 * may cause EOVERFLOW, if so simply drop the attributes.
8307c478bd9Sstevel@tonic-gate 	 */
8317c478bd9Sstevel@tonic-gate 	if (objp->fres.status != NFS3_OK)
8327c478bd9Sstevel@tonic-gate 		objp->attributes = FALSE;
8337c478bd9Sstevel@tonic-gate 
8347c478bd9Sstevel@tonic-gate 	return (TRUE);
8357c478bd9Sstevel@tonic-gate }
8367c478bd9Sstevel@tonic-gate 
8377c478bd9Sstevel@tonic-gate bool_t
xdr_post_op_attr(XDR * xdrs,post_op_attr * objp)8387c478bd9Sstevel@tonic-gate xdr_post_op_attr(XDR *xdrs, post_op_attr *objp)
8397c478bd9Sstevel@tonic-gate {
8407c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->attributes))
8417c478bd9Sstevel@tonic-gate 		return (FALSE);
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate 	if (objp->attributes == FALSE)
8447c478bd9Sstevel@tonic-gate 		return (TRUE);
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate 	if (objp->attributes != TRUE)
8477c478bd9Sstevel@tonic-gate 		return (FALSE);
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 	if (!xdr_fattr3(xdrs, &objp->attr))
8507c478bd9Sstevel@tonic-gate 		return (FALSE);
8517c478bd9Sstevel@tonic-gate 
8527c478bd9Sstevel@tonic-gate 	/*
8537c478bd9Sstevel@tonic-gate 	 * Check that we don't get a file we can't handle through
8547c478bd9Sstevel@tonic-gate 	 *	existing interfaces (especially stat64()).
8557c478bd9Sstevel@tonic-gate 	 * Decode only check since on encode the data has
8567c478bd9Sstevel@tonic-gate 	 * been dealt with in the above call to xdr_fattr3().
8577c478bd9Sstevel@tonic-gate 	 */
8587c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
8597c478bd9Sstevel@tonic-gate 		/* Set attrs to false if invalid size or time */
8607c478bd9Sstevel@tonic-gate 		if (!NFS3_SIZE_OK(objp->attr.size)) {
8617c478bd9Sstevel@tonic-gate 			objp->attributes = FALSE;
8627c478bd9Sstevel@tonic-gate 			return (TRUE);
8637c478bd9Sstevel@tonic-gate 		}
8647c478bd9Sstevel@tonic-gate #ifndef _LP64
8657c478bd9Sstevel@tonic-gate 		if (!NFS3_FATTR_TIME_OK(&objp->attr))
8667c478bd9Sstevel@tonic-gate 			objp->attributes = FALSE;
8677c478bd9Sstevel@tonic-gate #endif
8687c478bd9Sstevel@tonic-gate 	}
8697c478bd9Sstevel@tonic-gate 	return (TRUE);
8707c478bd9Sstevel@tonic-gate }
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate static bool_t
xdr_wcc_data(XDR * xdrs,wcc_data * objp)8737c478bd9Sstevel@tonic-gate xdr_wcc_data(XDR *xdrs, wcc_data *objp)
8747c478bd9Sstevel@tonic-gate {
8757c478bd9Sstevel@tonic-gate 	int32_t *ptr;
8767c478bd9Sstevel@tonic-gate 	wcc_attr *attrp;
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
8797c478bd9Sstevel@tonic-gate 		return (TRUE);
8807c478bd9Sstevel@tonic-gate 
8817c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
8827c478bd9Sstevel@tonic-gate 		/* pre_op_attr */
8837c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->before.attributes))
8847c478bd9Sstevel@tonic-gate 			return (FALSE);
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate 		switch (objp->before.attributes) {
8877c478bd9Sstevel@tonic-gate 		case TRUE:
8887c478bd9Sstevel@tonic-gate 			attrp = &objp->before.attr;
8897c478bd9Sstevel@tonic-gate 			ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
8907c478bd9Sstevel@tonic-gate 			if (ptr != NULL) {
8917c478bd9Sstevel@tonic-gate 				IXDR_GET_U_HYPER(ptr, attrp->size);
8927c478bd9Sstevel@tonic-gate 				attrp->mtime.seconds = IXDR_GET_U_INT32(ptr);
8937c478bd9Sstevel@tonic-gate 				attrp->mtime.nseconds = IXDR_GET_U_INT32(ptr);
8947c478bd9Sstevel@tonic-gate 				attrp->ctime.seconds = IXDR_GET_U_INT32(ptr);
8957c478bd9Sstevel@tonic-gate 				attrp->ctime.nseconds = IXDR_GET_U_INT32(ptr);
8967c478bd9Sstevel@tonic-gate 			} else {
8977c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs, &attrp->size))
8987c478bd9Sstevel@tonic-gate 					return (FALSE);
8997c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
9007c478bd9Sstevel@tonic-gate 					return (FALSE);
9017c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
9027c478bd9Sstevel@tonic-gate 					return (FALSE);
9037c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
9047c478bd9Sstevel@tonic-gate 					return (FALSE);
9057c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
9067c478bd9Sstevel@tonic-gate 					return (FALSE);
9077c478bd9Sstevel@tonic-gate 			}
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate #ifndef _LP64
9107c478bd9Sstevel@tonic-gate 			/*
9117c478bd9Sstevel@tonic-gate 			 * check time overflow.
9127c478bd9Sstevel@tonic-gate 			 */
9137c478bd9Sstevel@tonic-gate 			if (!NFS3_TIME_OK(attrp->mtime.seconds) ||
9147c478bd9Sstevel@tonic-gate 			    !NFS3_TIME_OK(attrp->ctime.seconds))
9157c478bd9Sstevel@tonic-gate 				objp->before.attributes = FALSE;
9167c478bd9Sstevel@tonic-gate #endif
9177c478bd9Sstevel@tonic-gate 			break;
9187c478bd9Sstevel@tonic-gate 		case FALSE:
9197c478bd9Sstevel@tonic-gate 			break;
9207c478bd9Sstevel@tonic-gate 		default:
9217c478bd9Sstevel@tonic-gate 			return (FALSE);
9227c478bd9Sstevel@tonic-gate 		}
9237c478bd9Sstevel@tonic-gate 	}
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
9267c478bd9Sstevel@tonic-gate 		/* pre_op_attr */
9277c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->before.attributes))
9287c478bd9Sstevel@tonic-gate 			return (FALSE);
9297c478bd9Sstevel@tonic-gate 
9307c478bd9Sstevel@tonic-gate 		switch (objp->before.attributes) {
9317c478bd9Sstevel@tonic-gate 		case TRUE:
9327c478bd9Sstevel@tonic-gate 			attrp = &objp->before.attr;
9337c478bd9Sstevel@tonic-gate 
9347c478bd9Sstevel@tonic-gate 			ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
9357c478bd9Sstevel@tonic-gate 			if (ptr != NULL) {
9367c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_HYPER(ptr, attrp->size);
9377c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_INT32(ptr, attrp->mtime.seconds);
9387c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_INT32(ptr, attrp->mtime.nseconds);
9397c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_INT32(ptr, attrp->ctime.seconds);
9407c478bd9Sstevel@tonic-gate 				IXDR_PUT_U_INT32(ptr, attrp->ctime.nseconds);
9417c478bd9Sstevel@tonic-gate 			} else {
9427c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs, &attrp->size))
9437c478bd9Sstevel@tonic-gate 					return (FALSE);
9447c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
9457c478bd9Sstevel@tonic-gate 					return (FALSE);
9467c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
9477c478bd9Sstevel@tonic-gate 					return (FALSE);
9487c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
9497c478bd9Sstevel@tonic-gate 					return (FALSE);
9507c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
9517c478bd9Sstevel@tonic-gate 					return (FALSE);
9527c478bd9Sstevel@tonic-gate 			}
9537c478bd9Sstevel@tonic-gate 			break;
9547c478bd9Sstevel@tonic-gate 		case FALSE:
9557c478bd9Sstevel@tonic-gate 			break;
9567c478bd9Sstevel@tonic-gate 		default:
9577c478bd9Sstevel@tonic-gate 			return (FALSE);
9587c478bd9Sstevel@tonic-gate 		}
9597c478bd9Sstevel@tonic-gate 	}
9607c478bd9Sstevel@tonic-gate 	return (xdr_post_op_attr(xdrs, &objp->after));
9617c478bd9Sstevel@tonic-gate }
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate bool_t
xdr_post_op_fh3(XDR * xdrs,post_op_fh3 * objp)9647c478bd9Sstevel@tonic-gate xdr_post_op_fh3(XDR *xdrs, post_op_fh3 *objp)
9657c478bd9Sstevel@tonic-gate {
9667c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->handle_follows))
9677c478bd9Sstevel@tonic-gate 		return (FALSE);
9687c478bd9Sstevel@tonic-gate 	switch (objp->handle_follows) {
9697c478bd9Sstevel@tonic-gate 	case TRUE:
97027242a7cSthurlow 		switch (xdrs->x_op) {
97127242a7cSthurlow 		case XDR_ENCODE:
97227242a7cSthurlow 			if (!xdr_nfs_fh3_server(xdrs, &objp->handle))
97327242a7cSthurlow 				return (FALSE);
97427242a7cSthurlow 			break;
97527242a7cSthurlow 		case XDR_FREE:
97627242a7cSthurlow 		case XDR_DECODE:
97727242a7cSthurlow 			if (!xdr_nfs_fh3(xdrs, &objp->handle))
97827242a7cSthurlow 				return (FALSE);
97927242a7cSthurlow 			break;
98027242a7cSthurlow 		}
98127242a7cSthurlow 		return (TRUE);
9827c478bd9Sstevel@tonic-gate 	case FALSE:
9837c478bd9Sstevel@tonic-gate 		return (TRUE);
9847c478bd9Sstevel@tonic-gate 	default:
9857c478bd9Sstevel@tonic-gate 		return (FALSE);
9867c478bd9Sstevel@tonic-gate 	}
9877c478bd9Sstevel@tonic-gate }
9887c478bd9Sstevel@tonic-gate 
9897c478bd9Sstevel@tonic-gate static bool_t
xdr_sattr3(XDR * xdrs,sattr3 * objp)9907c478bd9Sstevel@tonic-gate xdr_sattr3(XDR *xdrs, sattr3 *objp)
9917c478bd9Sstevel@tonic-gate {
9927c478bd9Sstevel@tonic-gate 	/* set_mode3 */
9937c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->mode.set_it))
9947c478bd9Sstevel@tonic-gate 		return (FALSE);
9957c478bd9Sstevel@tonic-gate 	if (objp->mode.set_it)
9967c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->mode.mode))
9977c478bd9Sstevel@tonic-gate 			return (FALSE);
9987c478bd9Sstevel@tonic-gate 	/* set_uid3 */
9997c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->uid.set_it))
10007c478bd9Sstevel@tonic-gate 		return (FALSE);
10017c478bd9Sstevel@tonic-gate 	if (objp->uid.set_it)
10027c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->uid.uid))
10037c478bd9Sstevel@tonic-gate 			return (FALSE);
10047c478bd9Sstevel@tonic-gate 	/* set_gid3 */
10057c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->gid.set_it))
10067c478bd9Sstevel@tonic-gate 		return (FALSE);
10077c478bd9Sstevel@tonic-gate 	if (objp->gid.set_it)
10087c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->gid.gid))
10097c478bd9Sstevel@tonic-gate 			return (FALSE);
10107c478bd9Sstevel@tonic-gate 
10117c478bd9Sstevel@tonic-gate 	/* set_size3 */
10127c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->size.set_it))
10137c478bd9Sstevel@tonic-gate 		return (FALSE);
10147c478bd9Sstevel@tonic-gate 	if (objp->size.set_it)
10157c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, &objp->size.size))
10167c478bd9Sstevel@tonic-gate 			return (FALSE);
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate 	/* set_atime */
10197c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->atime.set_it))
10207c478bd9Sstevel@tonic-gate 		return (FALSE);
10217c478bd9Sstevel@tonic-gate 	if (objp->atime.set_it == SET_TO_CLIENT_TIME) {
10227c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->atime.atime.seconds))
10237c478bd9Sstevel@tonic-gate 			return (FALSE);
10247c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->atime.atime.nseconds))
10257c478bd9Sstevel@tonic-gate 			return (FALSE);
10267c478bd9Sstevel@tonic-gate 	}
10277c478bd9Sstevel@tonic-gate 
10287c478bd9Sstevel@tonic-gate 	/* set_mtime */
10297c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->mtime.set_it))
10307c478bd9Sstevel@tonic-gate 		return (FALSE);
10317c478bd9Sstevel@tonic-gate 	if (objp->mtime.set_it == SET_TO_CLIENT_TIME) {
10327c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->mtime.mtime.seconds))
10337c478bd9Sstevel@tonic-gate 			return (FALSE);
10347c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->mtime.mtime.nseconds))
10357c478bd9Sstevel@tonic-gate 			return (FALSE);
10367c478bd9Sstevel@tonic-gate 	}
10377c478bd9Sstevel@tonic-gate 
10387c478bd9Sstevel@tonic-gate 	return (TRUE);
10397c478bd9Sstevel@tonic-gate }
10407c478bd9Sstevel@tonic-gate 
10417c478bd9Sstevel@tonic-gate bool_t
xdr_GETATTR3res(XDR * xdrs,GETATTR3res * objp)10427c478bd9Sstevel@tonic-gate xdr_GETATTR3res(XDR *xdrs, GETATTR3res *objp)
10437c478bd9Sstevel@tonic-gate {
10447c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
10457c478bd9Sstevel@tonic-gate 		return (FALSE);
10467c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
10477c478bd9Sstevel@tonic-gate 		return (TRUE);
10487c478bd9Sstevel@tonic-gate 	/* xdr_GETATTR3resok */
10497c478bd9Sstevel@tonic-gate 	return (xdr_fattr3(xdrs, &objp->resok.obj_attributes));
10507c478bd9Sstevel@tonic-gate }
10517c478bd9Sstevel@tonic-gate 
10527c478bd9Sstevel@tonic-gate bool_t
xdr_GETATTR3vres(XDR * xdrs,GETATTR3vres * objp)10537c478bd9Sstevel@tonic-gate xdr_GETATTR3vres(XDR *xdrs, GETATTR3vres *objp)
10547c478bd9Sstevel@tonic-gate {
10557c478bd9Sstevel@tonic-gate 	/*
10567c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
10577c478bd9Sstevel@tonic-gate 	 */
10587c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
10597c478bd9Sstevel@tonic-gate 		return (TRUE);
10607c478bd9Sstevel@tonic-gate 
10617c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
10627c478bd9Sstevel@tonic-gate 		return (FALSE);
10637c478bd9Sstevel@tonic-gate 
10647c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
10657c478bd9Sstevel@tonic-gate 		return (FALSE);
10667c478bd9Sstevel@tonic-gate 
10677c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
10687c478bd9Sstevel@tonic-gate 		return (TRUE);
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate 	return (xdr_fattr3_to_vattr(xdrs, &objp->fres));
10717c478bd9Sstevel@tonic-gate }
10727c478bd9Sstevel@tonic-gate 
10737c478bd9Sstevel@tonic-gate 
10747c478bd9Sstevel@tonic-gate bool_t
xdr_SETATTR3args(XDR * xdrs,SETATTR3args * objp)10757c478bd9Sstevel@tonic-gate xdr_SETATTR3args(XDR *xdrs, SETATTR3args *objp)
10767c478bd9Sstevel@tonic-gate {
107727242a7cSthurlow 	switch (xdrs->x_op) {
107827242a7cSthurlow 	case XDR_FREE:
107927242a7cSthurlow 	case XDR_ENCODE:
108027242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, &objp->object))
108127242a7cSthurlow 			return (FALSE);
108227242a7cSthurlow 		break;
108327242a7cSthurlow 	case XDR_DECODE:
108427242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->object))
108527242a7cSthurlow 			return (FALSE);
108627242a7cSthurlow 		break;
108727242a7cSthurlow 	}
10887c478bd9Sstevel@tonic-gate 	if (!xdr_sattr3(xdrs, &objp->new_attributes))
10897c478bd9Sstevel@tonic-gate 		return (FALSE);
10907c478bd9Sstevel@tonic-gate 
10917c478bd9Sstevel@tonic-gate 	/* sattrguard3 */
10927c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->guard.check))
10937c478bd9Sstevel@tonic-gate 		return (FALSE);
10947c478bd9Sstevel@tonic-gate 	switch (objp->guard.check) {
10957c478bd9Sstevel@tonic-gate 	case TRUE:
10967c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->guard.obj_ctime.seconds))
10977c478bd9Sstevel@tonic-gate 			return (FALSE);
10987c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->guard.obj_ctime.nseconds));
10997c478bd9Sstevel@tonic-gate 	case FALSE:
11007c478bd9Sstevel@tonic-gate 		return (TRUE);
11017c478bd9Sstevel@tonic-gate 	default:
11027c478bd9Sstevel@tonic-gate 		return (FALSE);
11037c478bd9Sstevel@tonic-gate 	}
11047c478bd9Sstevel@tonic-gate }
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate bool_t
xdr_SETATTR3res(XDR * xdrs,SETATTR3res * objp)11077c478bd9Sstevel@tonic-gate xdr_SETATTR3res(XDR *xdrs, SETATTR3res *objp)
11087c478bd9Sstevel@tonic-gate {
11097c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
11107c478bd9Sstevel@tonic-gate 		return (FALSE);
11117c478bd9Sstevel@tonic-gate 	switch (objp->status) {
11127c478bd9Sstevel@tonic-gate 	case NFS3_OK:
11137c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resok.obj_wcc));
11147c478bd9Sstevel@tonic-gate 	default:
11157c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.obj_wcc));
11167c478bd9Sstevel@tonic-gate 	}
11177c478bd9Sstevel@tonic-gate }
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate bool_t
xdr_LOOKUP3res(XDR * xdrs,LOOKUP3res * objp)11207c478bd9Sstevel@tonic-gate xdr_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp)
11217c478bd9Sstevel@tonic-gate {
11227c478bd9Sstevel@tonic-gate 	LOOKUP3resok *resokp;
11237c478bd9Sstevel@tonic-gate 
11247c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
11257c478bd9Sstevel@tonic-gate 		return (FALSE);
11267c478bd9Sstevel@tonic-gate 
11277c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
11287c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
11297c478bd9Sstevel@tonic-gate 
11307c478bd9Sstevel@tonic-gate 	/* xdr_LOOKUP3resok */
11317c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
113227242a7cSthurlow 	switch (xdrs->x_op) {
113327242a7cSthurlow 	case XDR_ENCODE:
113427242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &resokp->object))
113527242a7cSthurlow 			return (FALSE);
113627242a7cSthurlow 		break;
113727242a7cSthurlow 	case XDR_FREE:
113827242a7cSthurlow 	case XDR_DECODE:
113927242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, &resokp->object))
114027242a7cSthurlow 			return (FALSE);
114127242a7cSthurlow 		break;
114227242a7cSthurlow 	}
11437c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
11447c478bd9Sstevel@tonic-gate 		return (FALSE);
11457c478bd9Sstevel@tonic-gate 	return (xdr_post_op_attr(xdrs, &resokp->dir_attributes));
11467c478bd9Sstevel@tonic-gate }
11477c478bd9Sstevel@tonic-gate 
11487c478bd9Sstevel@tonic-gate bool_t
xdr_LOOKUP3vres(XDR * xdrs,LOOKUP3vres * objp)11497c478bd9Sstevel@tonic-gate xdr_LOOKUP3vres(XDR *xdrs, LOOKUP3vres *objp)
11507c478bd9Sstevel@tonic-gate {
11517c478bd9Sstevel@tonic-gate 	/*
11527c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
11537c478bd9Sstevel@tonic-gate 	 */
11547c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
11557c478bd9Sstevel@tonic-gate 		return (TRUE);
11567c478bd9Sstevel@tonic-gate 
11577c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
11587c478bd9Sstevel@tonic-gate 		return (FALSE);
11597c478bd9Sstevel@tonic-gate 
11607c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
11617c478bd9Sstevel@tonic-gate 		return (FALSE);
11627c478bd9Sstevel@tonic-gate 
11637c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
11647c478bd9Sstevel@tonic-gate 		return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
11657c478bd9Sstevel@tonic-gate 
11667c478bd9Sstevel@tonic-gate 	if (!xdr_nfs_fh3(xdrs, &objp->object))
11677c478bd9Sstevel@tonic-gate 		return (FALSE);
11687c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_vattr(xdrs, &objp->obj_attributes))
11697c478bd9Sstevel@tonic-gate 		return (FALSE);
11707c478bd9Sstevel@tonic-gate 	return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
11717c478bd9Sstevel@tonic-gate }
11727c478bd9Sstevel@tonic-gate 
11737c478bd9Sstevel@tonic-gate bool_t
xdr_ACCESS3args(XDR * xdrs,ACCESS3args * objp)11747c478bd9Sstevel@tonic-gate xdr_ACCESS3args(XDR *xdrs, ACCESS3args *objp)
11757c478bd9Sstevel@tonic-gate {
117627242a7cSthurlow 	switch (xdrs->x_op) {
117727242a7cSthurlow 	case XDR_FREE:
117827242a7cSthurlow 	case XDR_ENCODE:
117927242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, &objp->object))
118027242a7cSthurlow 			return (FALSE);
118127242a7cSthurlow 		break;
118227242a7cSthurlow 	case XDR_DECODE:
118327242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->object))
118427242a7cSthurlow 			return (FALSE);
118527242a7cSthurlow 		break;
11867c478bd9Sstevel@tonic-gate 	}
11877c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->access));
11887c478bd9Sstevel@tonic-gate }
11897c478bd9Sstevel@tonic-gate 
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate bool_t
xdr_ACCESS3res(XDR * xdrs,ACCESS3res * objp)11927c478bd9Sstevel@tonic-gate xdr_ACCESS3res(XDR *xdrs, ACCESS3res *objp)
11937c478bd9Sstevel@tonic-gate {
11947c478bd9Sstevel@tonic-gate 	ACCESS3resok *resokp;
11957c478bd9Sstevel@tonic-gate 
11967c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
11977c478bd9Sstevel@tonic-gate 		return (FALSE);
11987c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
11997c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
12007c478bd9Sstevel@tonic-gate 
12017c478bd9Sstevel@tonic-gate 	/* xdr_ACCESS3resok */
12027c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
12037c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
12047c478bd9Sstevel@tonic-gate 		return (FALSE);
12057c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &resokp->access));
12067c478bd9Sstevel@tonic-gate }
12077c478bd9Sstevel@tonic-gate 
12080a701b1eSRobert Gordon bool_t
xdr_READLINK3args(XDR * xdrs,READLINK3args * objp)12090a701b1eSRobert Gordon xdr_READLINK3args(XDR *xdrs,  READLINK3args *objp)
12100a701b1eSRobert Gordon {
12110a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
12120a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
12130a701b1eSRobert Gordon 
12140a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
12150a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
12160a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
12170a701b1eSRobert Gordon 		rci.rci_len = MAXPATHLEN;
12180a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
12190a701b1eSRobert Gordon 	}
12200a701b1eSRobert Gordon 	if (!xdr_nfs_fh3(xdrs, (nfs_fh3 *)objp))
12210a701b1eSRobert Gordon 		return (FALSE);
12220a701b1eSRobert Gordon 	return (TRUE);
12230a701b1eSRobert Gordon }
12240a701b1eSRobert Gordon 
12257c478bd9Sstevel@tonic-gate bool_t
xdr_READLINK3res(XDR * xdrs,READLINK3res * objp)12267c478bd9Sstevel@tonic-gate xdr_READLINK3res(XDR *xdrs, READLINK3res *objp)
12277c478bd9Sstevel@tonic-gate {
12287c478bd9Sstevel@tonic-gate 
12297c478bd9Sstevel@tonic-gate 	READLINK3resok *resokp;
12307c478bd9Sstevel@tonic-gate 
12317c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
12327c478bd9Sstevel@tonic-gate 		return (FALSE);
12337c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
12347c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs,
12350a701b1eSRobert Gordon 		    &objp->resfail.symlink_attributes));
12367c478bd9Sstevel@tonic-gate 
12377c478bd9Sstevel@tonic-gate 	/* xdr_READLINK3resok */
12387c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
12397c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->symlink_attributes))
12407c478bd9Sstevel@tonic-gate 		return (FALSE);
12417c478bd9Sstevel@tonic-gate 	return (xdr_string3(xdrs, &resokp->data, MAXPATHLEN));
12427c478bd9Sstevel@tonic-gate }
12437c478bd9Sstevel@tonic-gate 
12447c478bd9Sstevel@tonic-gate bool_t
xdr_READ3args(XDR * xdrs,READ3args * objp)12457c478bd9Sstevel@tonic-gate xdr_READ3args(XDR *xdrs, READ3args *objp)
12467c478bd9Sstevel@tonic-gate {
12470a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
12480a701b1eSRobert Gordon 	rdma_wlist_conn_info_t rwci;
12490a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
12500a701b1eSRobert Gordon 
125127242a7cSthurlow 	switch (xdrs->x_op) {
125227242a7cSthurlow 	case XDR_FREE:
125327242a7cSthurlow 	case XDR_ENCODE:
125427242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, &objp->file))
125527242a7cSthurlow 			return (FALSE);
125627242a7cSthurlow 		break;
125727242a7cSthurlow 	case XDR_DECODE:
125827242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
125927242a7cSthurlow 			return (FALSE);
126027242a7cSthurlow 		break;
12617c478bd9Sstevel@tonic-gate 	}
12627c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->offset))
12637c478bd9Sstevel@tonic-gate 		return (FALSE);
12640a701b1eSRobert Gordon 	if (!xdr_u_int(xdrs, &objp->count))
12650a701b1eSRobert Gordon 		return (FALSE);
12660a701b1eSRobert Gordon 
12670a701b1eSRobert Gordon 	DTRACE_PROBE1(xdr__i__read3_buf_len, int, objp->count);
12680a701b1eSRobert Gordon 
12690a701b1eSRobert Gordon 	objp->wlist = NULL;
12700a701b1eSRobert Gordon 
12710a701b1eSRobert Gordon 	/* if xdrrdma_sizeof in progress, then store the size */
12720a701b1eSRobert Gordon 	if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
12730a701b1eSRobert Gordon 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
12740a701b1eSRobert Gordon 		rci.rci_len = objp->count;
12750a701b1eSRobert Gordon 		(void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
12760a701b1eSRobert Gordon 	}
12770a701b1eSRobert Gordon 
12780a701b1eSRobert Gordon 	if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
12790a701b1eSRobert Gordon 		return (TRUE);
12800a701b1eSRobert Gordon 
12810a701b1eSRobert Gordon 	if (xdrs->x_op == XDR_ENCODE) {
12820a701b1eSRobert Gordon 
12830a701b1eSRobert Gordon 		if (objp->res_uiop != NULL) {
12840a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_UIO_CHUNK;
12850a701b1eSRobert Gordon 			rci.rci_a.rci_uiop = objp->res_uiop;
12860a701b1eSRobert Gordon 			rci.rci_len = objp->count;
12870a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
12880a701b1eSRobert Gordon 		} else {
12890a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_ADDR_CHUNK;
12900a701b1eSRobert Gordon 			rci.rci_a.rci_addr = objp->res_data_val_alt;
12910a701b1eSRobert Gordon 			rci.rci_len = objp->count;
12920a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
12930a701b1eSRobert Gordon 		}
12940a701b1eSRobert Gordon 
12950a701b1eSRobert Gordon 		return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
12960a701b1eSRobert Gordon 	}
12970a701b1eSRobert Gordon 
12980a701b1eSRobert Gordon 	/* XDR_DECODE case */
12990a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
13000a701b1eSRobert Gordon 	objp->wlist = rwci.rwci_wlist;
13010a701b1eSRobert Gordon 	objp->conn = rwci.rwci_conn;
13020a701b1eSRobert Gordon 
13030a701b1eSRobert Gordon 	return (TRUE);
13047c478bd9Sstevel@tonic-gate }
13057c478bd9Sstevel@tonic-gate 
13067c478bd9Sstevel@tonic-gate bool_t
xdr_READ3res(XDR * xdrs,READ3res * objp)13077c478bd9Sstevel@tonic-gate xdr_READ3res(XDR *xdrs, READ3res *objp)
13087c478bd9Sstevel@tonic-gate {
13097c478bd9Sstevel@tonic-gate 	READ3resok *resokp;
13107c478bd9Sstevel@tonic-gate 	bool_t ret;
13117c478bd9Sstevel@tonic-gate 	mblk_t *mp;
13127c478bd9Sstevel@tonic-gate 
13137c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
13147c478bd9Sstevel@tonic-gate 		return (FALSE);
13157c478bd9Sstevel@tonic-gate 
13167c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
13177c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.file_attributes));
13187c478bd9Sstevel@tonic-gate 
13197c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
13207c478bd9Sstevel@tonic-gate 
13217c478bd9Sstevel@tonic-gate 	if (xdr_post_op_attr(xdrs, &resokp->file_attributes) == FALSE ||
13227c478bd9Sstevel@tonic-gate 	    xdr_u_int(xdrs, &resokp->count) == FALSE ||
13237c478bd9Sstevel@tonic-gate 	    xdr_bool(xdrs, &resokp->eof) == FALSE) {
13247c478bd9Sstevel@tonic-gate 		return (FALSE);
13257c478bd9Sstevel@tonic-gate 	}
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
13287c478bd9Sstevel@tonic-gate 
13297c478bd9Sstevel@tonic-gate 		mp = resokp->data.mp;
1330e36d7b11SSebastien Roy 		if (mp != NULL) {
1331e36d7b11SSebastien Roy 			if (xdrs->x_ops == &xdrmblk_ops) {
1332e36d7b11SSebastien Roy 				if (xdrmblk_putmblk(xdrs, mp, resokp->count)) {
1333e36d7b11SSebastien Roy 					resokp->data.mp = NULL;
1334e36d7b11SSebastien Roy 					return (TRUE);
1335e36d7b11SSebastien Roy 				} else {
1336e36d7b11SSebastien Roy 					return (FALSE);
1337e36d7b11SSebastien Roy 				}
1338e36d7b11SSebastien Roy 			} else if (mp->b_cont != NULL) {
1339e36d7b11SSebastien Roy 				/*
1340e36d7b11SSebastien Roy 				 * We have read results in an mblk chain, but
1341e36d7b11SSebastien Roy 				 * the encoding operations don't handle mblks
1342e36d7b11SSebastien Roy 				 * (they'll operate on data.data_val rather
1343e36d7b11SSebastien Roy 				 * than data.mp).  Because data_val can only
1344e36d7b11SSebastien Roy 				 * point at a single data buffer, we need to
1345e36d7b11SSebastien Roy 				 * pullup the read results into a single data
1346e36d7b11SSebastien Roy 				 * block and reset data_val to point to it.
1347e36d7b11SSebastien Roy 				 *
1348e36d7b11SSebastien Roy 				 * This happens with RPC GSS where the wrapping
1349e36d7b11SSebastien Roy 				 * function does XDR serialization into a
1350e36d7b11SSebastien Roy 				 * temporary buffer prior to applying GSS.
1351e36d7b11SSebastien Roy 				 * Because we're not in a performance sensitive
1352e36d7b11SSebastien Roy 				 * path, the pullupmsg() here shouldn't hurt us
1353e36d7b11SSebastien Roy 				 * too badly.
1354e36d7b11SSebastien Roy 				 */
1355e36d7b11SSebastien Roy 				if (pullupmsg(mp, -1) == 0)
1356e36d7b11SSebastien Roy 					return (FALSE);
1357e36d7b11SSebastien Roy 				resokp->data.data_val = (caddr_t)mp->b_rptr;
13587c478bd9Sstevel@tonic-gate 			}
1359e36d7b11SSebastien Roy 		} else {
13600a701b1eSRobert Gordon 			if (xdr_u_int(xdrs, &resokp->count) == FALSE) {
13610a701b1eSRobert Gordon 				return (FALSE);
13620a701b1eSRobert Gordon 			}
13630a701b1eSRobert Gordon 			/*
13640a701b1eSRobert Gordon 			 * If read data sent by wlist (RDMA_WRITE), don't do
13650a701b1eSRobert Gordon 			 * xdr_bytes() below.   RDMA_WRITE transfers the data.
13660a701b1eSRobert Gordon 			 * Note: this is encode-only because the client code
13670a701b1eSRobert Gordon 			 * uses xdr_READ3vres/xdr_READ3uiores to decode results.
13680a701b1eSRobert Gordon 			 */
13690a701b1eSRobert Gordon 			if (resokp->wlist) {
13700a701b1eSRobert Gordon 				if (resokp->count != 0) {
13710a701b1eSRobert Gordon 					return (xdrrdma_send_read_data(
1372f837ee4aSSiddheshwar Mahesh 					    xdrs, resokp->count,
1373f837ee4aSSiddheshwar Mahesh 					    resokp->wlist));
13740a701b1eSRobert Gordon 				}
13750a701b1eSRobert Gordon 				return (TRUE);
13760a701b1eSRobert Gordon 			}
13777c478bd9Sstevel@tonic-gate 		}
13787c478bd9Sstevel@tonic-gate 		/*
13797c478bd9Sstevel@tonic-gate 		 * Fall thru for the xdr_bytes()
13807c478bd9Sstevel@tonic-gate 		 *
13817c478bd9Sstevel@tonic-gate 		 * note: the mblk will be freed in
13827c478bd9Sstevel@tonic-gate 		 * rfs3_read_free.
13837c478bd9Sstevel@tonic-gate 		 */
13847c478bd9Sstevel@tonic-gate 	}
13857c478bd9Sstevel@tonic-gate 
13860a701b1eSRobert Gordon 	/* no RDMA_WRITE transfer -- send data inline */
13870a701b1eSRobert Gordon 
13887c478bd9Sstevel@tonic-gate 	ret = xdr_bytes(xdrs, (char **)&resokp->data.data_val,
13897c478bd9Sstevel@tonic-gate 	    &resokp->data.data_len, nfs3tsize());
13907c478bd9Sstevel@tonic-gate 
13917c478bd9Sstevel@tonic-gate 	return (ret);
13927c478bd9Sstevel@tonic-gate }
13937c478bd9Sstevel@tonic-gate 
13947c478bd9Sstevel@tonic-gate bool_t
xdr_READ3vres(XDR * xdrs,READ3vres * objp)13957c478bd9Sstevel@tonic-gate xdr_READ3vres(XDR *xdrs, READ3vres *objp)
13967c478bd9Sstevel@tonic-gate {
13970a701b1eSRobert Gordon 	count3 ocount;
13987c478bd9Sstevel@tonic-gate 	/*
13997c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
14007c478bd9Sstevel@tonic-gate 	 */
14017c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
14027c478bd9Sstevel@tonic-gate 		return (TRUE);
14037c478bd9Sstevel@tonic-gate 
14047c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
14057c478bd9Sstevel@tonic-gate 		return (FALSE);
14067c478bd9Sstevel@tonic-gate 
14077c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
14087c478bd9Sstevel@tonic-gate 		return (FALSE);
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_vattr(xdrs, &objp->pov))
14117c478bd9Sstevel@tonic-gate 		return (FALSE);
14127c478bd9Sstevel@tonic-gate 
14137c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
14147c478bd9Sstevel@tonic-gate 		return (TRUE);
14157c478bd9Sstevel@tonic-gate 
14167c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->count))
14177c478bd9Sstevel@tonic-gate 		return (FALSE);
14187c478bd9Sstevel@tonic-gate 
14197c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->eof))
14207c478bd9Sstevel@tonic-gate 		return (FALSE);
14217c478bd9Sstevel@tonic-gate 
14220a701b1eSRobert Gordon 	/*
14230a701b1eSRobert Gordon 	 * If read data received via RDMA_WRITE, don't do xdr_bytes().
14240a701b1eSRobert Gordon 	 * RDMA_WRITE already moved the data so decode length of RDMA_WRITE.
14250a701b1eSRobert Gordon 	 */
14260a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops) {
14270a701b1eSRobert Gordon 		struct clist *cl;
14280a701b1eSRobert Gordon 
14290a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
14300a701b1eSRobert Gordon 
14310a701b1eSRobert Gordon 		if (cl) {
14320a701b1eSRobert Gordon 			if (!xdr_u_int(xdrs, &ocount)) {
14330a701b1eSRobert Gordon 				return (FALSE);
14340a701b1eSRobert Gordon 			}
14350a701b1eSRobert Gordon 			if (ocount != objp->count) {
14360a701b1eSRobert Gordon 				DTRACE_PROBE2(xdr__e__read3vres_fail,
14370a701b1eSRobert Gordon 				    int, ocount, int, objp->count);
1438f837ee4aSSiddheshwar Mahesh 				objp->wlist = NULL;
14390a701b1eSRobert Gordon 				return (FALSE);
14400a701b1eSRobert Gordon 			}
14410a701b1eSRobert Gordon 
1442f837ee4aSSiddheshwar Mahesh 			objp->wlist_len = clist_len(cl);
1443f837ee4aSSiddheshwar Mahesh 			objp->data.data_len = ocount;
1444f837ee4aSSiddheshwar Mahesh 
1445f837ee4aSSiddheshwar Mahesh 			if (objp->wlist_len !=
1446f837ee4aSSiddheshwar Mahesh 			    roundup(objp->data.data_len, BYTES_PER_XDR_UNIT)) {
1447f837ee4aSSiddheshwar Mahesh 				DTRACE_PROBE2(
1448f837ee4aSSiddheshwar Mahesh 				    xdr__e__read3vres_fail,
1449f837ee4aSSiddheshwar Mahesh 				    int, ocount,
1450f837ee4aSSiddheshwar Mahesh 				    int, objp->data.data_len);
1451f837ee4aSSiddheshwar Mahesh 				objp->wlist = NULL;
1452f837ee4aSSiddheshwar Mahesh 				return (FALSE);
1453f837ee4aSSiddheshwar Mahesh 			}
14540a701b1eSRobert Gordon 			return (TRUE);
14550a701b1eSRobert Gordon 		}
14560a701b1eSRobert Gordon 	}
14570a701b1eSRobert Gordon 
14587c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
14597c478bd9Sstevel@tonic-gate 	    &objp->data.data_len, nfs3tsize()));
14607c478bd9Sstevel@tonic-gate }
14617c478bd9Sstevel@tonic-gate 
14627c478bd9Sstevel@tonic-gate bool_t
xdr_READ3uiores(XDR * xdrs,READ3uiores * objp)14637c478bd9Sstevel@tonic-gate xdr_READ3uiores(XDR *xdrs, READ3uiores *objp)
14647c478bd9Sstevel@tonic-gate {
14650a701b1eSRobert Gordon 	count3 ocount;
14667c478bd9Sstevel@tonic-gate 	bool_t attributes;
14677c478bd9Sstevel@tonic-gate 	mblk_t *mp;
14687c478bd9Sstevel@tonic-gate 	size_t n;
14697c478bd9Sstevel@tonic-gate 	int error;
14707c478bd9Sstevel@tonic-gate 	int size = (int)objp->size;
14717c478bd9Sstevel@tonic-gate 	struct uio *uiop = objp->uiop;
14727c478bd9Sstevel@tonic-gate 	int32_t fattr3_len = NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
14737c478bd9Sstevel@tonic-gate 	int32_t *ptr;
14747c478bd9Sstevel@tonic-gate 
14757c478bd9Sstevel@tonic-gate 	/*
14767c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
14777c478bd9Sstevel@tonic-gate 	 */
14787c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
14797c478bd9Sstevel@tonic-gate 		return (TRUE);
14807c478bd9Sstevel@tonic-gate 
14817c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
14827c478bd9Sstevel@tonic-gate 		return (FALSE);
14837c478bd9Sstevel@tonic-gate 
14847c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
14857c478bd9Sstevel@tonic-gate 		return (FALSE);
14867c478bd9Sstevel@tonic-gate 
14877c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&attributes))
14887c478bd9Sstevel@tonic-gate 		return (FALSE);
14897c478bd9Sstevel@tonic-gate 
14907c478bd9Sstevel@tonic-gate 	/*
14917c478bd9Sstevel@tonic-gate 	 * For directio we just skip over attributes if present
14927c478bd9Sstevel@tonic-gate 	 */
14937c478bd9Sstevel@tonic-gate 	switch (attributes) {
14947c478bd9Sstevel@tonic-gate 	case TRUE:
14957c478bd9Sstevel@tonic-gate 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fattr3_len))
14967c478bd9Sstevel@tonic-gate 			return (FALSE);
14977c478bd9Sstevel@tonic-gate 		break;
14987c478bd9Sstevel@tonic-gate 	case FALSE:
14997c478bd9Sstevel@tonic-gate 		break;
15007c478bd9Sstevel@tonic-gate 	default:
15017c478bd9Sstevel@tonic-gate 		return (FALSE);
15027c478bd9Sstevel@tonic-gate 	}
15037c478bd9Sstevel@tonic-gate 
15047c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
15057c478bd9Sstevel@tonic-gate 		return (TRUE);
15067c478bd9Sstevel@tonic-gate 
15077c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->count))
15087c478bd9Sstevel@tonic-gate 		return (FALSE);
15097c478bd9Sstevel@tonic-gate 
15107c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
15117c478bd9Sstevel@tonic-gate 		return (FALSE);
15127c478bd9Sstevel@tonic-gate 
15137c478bd9Sstevel@tonic-gate 	if (xdrs->x_ops == &xdrmblk_ops) {
15147c478bd9Sstevel@tonic-gate 		if (!xdrmblk_getmblk(xdrs, &mp, &objp->size))
15157c478bd9Sstevel@tonic-gate 			return (FALSE);
15167c478bd9Sstevel@tonic-gate 
15177c478bd9Sstevel@tonic-gate 		if (objp->size == 0)
15187c478bd9Sstevel@tonic-gate 			return (TRUE);
15197c478bd9Sstevel@tonic-gate 
15207c478bd9Sstevel@tonic-gate 		if (objp->size > size)
15217c478bd9Sstevel@tonic-gate 			return (FALSE);
15227c478bd9Sstevel@tonic-gate 
15237c478bd9Sstevel@tonic-gate 		size = (int)objp->size;
15247c478bd9Sstevel@tonic-gate 		do {
15257c478bd9Sstevel@tonic-gate 			n = MIN(size, mp->b_wptr - mp->b_rptr);
15267c478bd9Sstevel@tonic-gate 			if ((n = MIN(uiop->uio_resid, n)) != 0) {
15277c478bd9Sstevel@tonic-gate 
15287c478bd9Sstevel@tonic-gate 				error = uiomove((char *)mp->b_rptr, n, UIO_READ,
15290a701b1eSRobert Gordon 				    uiop);
15307c478bd9Sstevel@tonic-gate 				if (error)
15317c478bd9Sstevel@tonic-gate 					return (FALSE);
15327c478bd9Sstevel@tonic-gate 				mp->b_rptr += n;
15337c478bd9Sstevel@tonic-gate 				size -= n;
15347c478bd9Sstevel@tonic-gate 			}
15357c478bd9Sstevel@tonic-gate 
15367c478bd9Sstevel@tonic-gate 			while (mp && (mp->b_rptr >= mp->b_wptr))
15377c478bd9Sstevel@tonic-gate 				mp = mp->b_cont;
15387c478bd9Sstevel@tonic-gate 		} while (mp && size > 0 && uiop->uio_resid > 0);
15397c478bd9Sstevel@tonic-gate 
15407c478bd9Sstevel@tonic-gate 		return (TRUE);
15417c478bd9Sstevel@tonic-gate 	}
15427c478bd9Sstevel@tonic-gate 
15430a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops) {
15440a701b1eSRobert Gordon 		struct clist *cl;
15450a701b1eSRobert Gordon 
15460a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
15470a701b1eSRobert Gordon 
15480a701b1eSRobert Gordon 		objp->wlist = cl;
15490a701b1eSRobert Gordon 
15500a701b1eSRobert Gordon 		if (objp->wlist) {
15510a701b1eSRobert Gordon 			if (!xdr_u_int(xdrs, &ocount)) {
15520a701b1eSRobert Gordon 				objp->wlist = NULL;
15530a701b1eSRobert Gordon 				return (FALSE);
15540a701b1eSRobert Gordon 			}
15550a701b1eSRobert Gordon 
15560a701b1eSRobert Gordon 			if (ocount != objp->count) {
15570a701b1eSRobert Gordon 				DTRACE_PROBE2(xdr__e__read3uiores_fail,
15580a701b1eSRobert Gordon 				    int, ocount, int, objp->count);
15590a701b1eSRobert Gordon 				objp->wlist = NULL;
15600a701b1eSRobert Gordon 				return (FALSE);
15610a701b1eSRobert Gordon 			}
15620a701b1eSRobert Gordon 
1563f837ee4aSSiddheshwar Mahesh 			objp->wlist_len = clist_len(cl);
15640a701b1eSRobert Gordon 
15650a701b1eSRobert Gordon 			uiop->uio_resid -= objp->count;
15660a701b1eSRobert Gordon 			uiop->uio_iov->iov_len -= objp->count;
15670a701b1eSRobert Gordon 			uiop->uio_iov->iov_base += objp->count;
15680a701b1eSRobert Gordon 			uiop->uio_loffset += objp->count;
15690a701b1eSRobert Gordon 
15700a701b1eSRobert Gordon 			/*
15710a701b1eSRobert Gordon 			 * XXX: Assume 1 iov, needs to be changed.
15720a701b1eSRobert Gordon 			 */
1573f837ee4aSSiddheshwar Mahesh 			objp->size = objp->count;
15740a701b1eSRobert Gordon 
15750a701b1eSRobert Gordon 			return (TRUE);
15760a701b1eSRobert Gordon 		}
15770a701b1eSRobert Gordon 	}
15780a701b1eSRobert Gordon 
15797c478bd9Sstevel@tonic-gate 	/*
15800a701b1eSRobert Gordon 	 * This isn't an xdrmblk stream nor RDMA.
15810a701b1eSRobert Gordon 	 * Handle the likely case that it can be
15820a701b1eSRobert Gordon 	 * inlined (ex. xdrmem).
15837c478bd9Sstevel@tonic-gate 	 */
15847c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->size))
15857c478bd9Sstevel@tonic-gate 		return (FALSE);
15867c478bd9Sstevel@tonic-gate 
15877c478bd9Sstevel@tonic-gate 	if (objp->size == 0)
15887c478bd9Sstevel@tonic-gate 		return (TRUE);
15897c478bd9Sstevel@tonic-gate 
15907c478bd9Sstevel@tonic-gate 	if (objp->size > size)
15917c478bd9Sstevel@tonic-gate 		return (FALSE);
15927c478bd9Sstevel@tonic-gate 
15937c478bd9Sstevel@tonic-gate 	size = (int)objp->size;
15947c478bd9Sstevel@tonic-gate 	if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
15957c478bd9Sstevel@tonic-gate 		return (uiomove(ptr, size, UIO_READ, uiop) ? FALSE : TRUE);
15967c478bd9Sstevel@tonic-gate 
15977c478bd9Sstevel@tonic-gate 	/*
15987c478bd9Sstevel@tonic-gate 	 * Handle some other (unlikely) stream type that will need a copy.
15997c478bd9Sstevel@tonic-gate 	 */
16007c478bd9Sstevel@tonic-gate 	if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
16017c478bd9Sstevel@tonic-gate 		return (FALSE);
16027c478bd9Sstevel@tonic-gate 
16037c478bd9Sstevel@tonic-gate 	if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
16047c478bd9Sstevel@tonic-gate 		kmem_free(ptr, size);
16057c478bd9Sstevel@tonic-gate 		return (FALSE);
16067c478bd9Sstevel@tonic-gate 	}
16077c478bd9Sstevel@tonic-gate 	error = uiomove(ptr, size, UIO_READ, uiop);
16087c478bd9Sstevel@tonic-gate 	kmem_free(ptr, size);
16097c478bd9Sstevel@tonic-gate 
16107c478bd9Sstevel@tonic-gate 	return (error ? FALSE : TRUE);
16117c478bd9Sstevel@tonic-gate }
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate bool_t
xdr_WRITE3args(XDR * xdrs,WRITE3args * objp)16147c478bd9Sstevel@tonic-gate xdr_WRITE3args(XDR *xdrs, WRITE3args *objp)
16157c478bd9Sstevel@tonic-gate {
161627242a7cSthurlow 	switch (xdrs->x_op) {
161727242a7cSthurlow 	case XDR_FREE:
161827242a7cSthurlow 	case XDR_ENCODE:
161927242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, &objp->file))
162027242a7cSthurlow 			return (FALSE);
162127242a7cSthurlow 		break;
162227242a7cSthurlow 	case XDR_DECODE:
162327242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
162427242a7cSthurlow 			return (FALSE);
162527242a7cSthurlow 		break;
16267c478bd9Sstevel@tonic-gate 	}
16277c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->offset))
16287c478bd9Sstevel@tonic-gate 		return (FALSE);
16297c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->count))
16307c478bd9Sstevel@tonic-gate 		return (FALSE);
16317c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->stable))
16327c478bd9Sstevel@tonic-gate 		return (FALSE);
16337c478bd9Sstevel@tonic-gate 
16347c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
16357c478bd9Sstevel@tonic-gate 		if (xdrs->x_ops == &xdrmblk_ops) {
16367c478bd9Sstevel@tonic-gate 			if (xdrmblk_getmblk(xdrs, &objp->mblk,
16377c478bd9Sstevel@tonic-gate 			    &objp->data.data_len) == TRUE) {
16387c478bd9Sstevel@tonic-gate 				objp->data.data_val = NULL;
16397c478bd9Sstevel@tonic-gate 				return (TRUE);
16407c478bd9Sstevel@tonic-gate 			}
16417c478bd9Sstevel@tonic-gate 		}
16427c478bd9Sstevel@tonic-gate 		objp->mblk = NULL;
16430a701b1eSRobert Gordon 
16440a701b1eSRobert Gordon 		if (xdrs->x_ops == &xdrrdmablk_ops) {
16450a701b1eSRobert Gordon 			if (xdrrdma_getrdmablk(xdrs, &objp->rlist,
16460a701b1eSRobert Gordon 			    &objp->data.data_len,
16470a701b1eSRobert Gordon 			    &objp->conn, nfs3tsize()) == TRUE) {
16480a701b1eSRobert Gordon 				objp->data.data_val = NULL;
16490a701b1eSRobert Gordon 				if (xdrrdma_read_from_client(
1650f837ee4aSSiddheshwar Mahesh 				    objp->rlist,
16510a701b1eSRobert Gordon 				    &objp->conn,
16520a701b1eSRobert Gordon 				    objp->count) == FALSE) {
16530a701b1eSRobert Gordon 					return (FALSE);
16540a701b1eSRobert Gordon 				}
16550a701b1eSRobert Gordon 				return (TRUE);
16560a701b1eSRobert Gordon 			}
16570a701b1eSRobert Gordon 		}
16580a701b1eSRobert Gordon 		objp->rlist = NULL;
16590a701b1eSRobert Gordon 
16607c478bd9Sstevel@tonic-gate 		/* Else fall thru for the xdr_bytes(). */
16617c478bd9Sstevel@tonic-gate 	}
16627c478bd9Sstevel@tonic-gate 
16630a701b1eSRobert Gordon 	if (xdrs->x_op == XDR_FREE) {
16640a701b1eSRobert Gordon 		if (objp->rlist != NULL) {
16650a701b1eSRobert Gordon 			(void) xdrrdma_free_clist(objp->conn, objp->rlist);
16660a701b1eSRobert Gordon 			objp->rlist = NULL;
16670a701b1eSRobert Gordon 			objp->data.data_val = NULL;
16680a701b1eSRobert Gordon 			return (TRUE);
16690a701b1eSRobert Gordon 		}
16700a701b1eSRobert Gordon 	}
16710a701b1eSRobert Gordon 
16720a701b1eSRobert Gordon 	DTRACE_PROBE1(xdr__i__write3_buf_len,
16730a701b1eSRobert Gordon 	    int, objp->data.data_len);
16740a701b1eSRobert Gordon 
16757c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
16767c478bd9Sstevel@tonic-gate 	    &objp->data.data_len, nfs3tsize()));
16777c478bd9Sstevel@tonic-gate }
16787c478bd9Sstevel@tonic-gate 
16797c478bd9Sstevel@tonic-gate bool_t
xdr_WRITE3res(XDR * xdrs,WRITE3res * objp)16807c478bd9Sstevel@tonic-gate xdr_WRITE3res(XDR *xdrs, WRITE3res *objp)
16817c478bd9Sstevel@tonic-gate {
16827c478bd9Sstevel@tonic-gate 	WRITE3resok *resokp;
16837c478bd9Sstevel@tonic-gate 
16847c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
16857c478bd9Sstevel@tonic-gate 		return (FALSE);
16867c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK) /* xdr_WRITE3resfail */
16877c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
16887c478bd9Sstevel@tonic-gate 
16897c478bd9Sstevel@tonic-gate 	/* xdr_WRITE3resok */
16907c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
16917c478bd9Sstevel@tonic-gate 	if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
16927c478bd9Sstevel@tonic-gate 		return (FALSE);
16937c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->count))
16947c478bd9Sstevel@tonic-gate 		return (FALSE);
16957c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&resokp->committed))
16967c478bd9Sstevel@tonic-gate 		return (FALSE);
16977c478bd9Sstevel@tonic-gate 	/*
16987c478bd9Sstevel@tonic-gate 	 * writeverf3 is really an opaque 8 byte
16997c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
17007c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
17017c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
17027c478bd9Sstevel@tonic-gate 	 */
17037c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, &resokp->verf));
17047c478bd9Sstevel@tonic-gate }
17057c478bd9Sstevel@tonic-gate 
17067c478bd9Sstevel@tonic-gate bool_t
xdr_CREATE3args(XDR * xdrs,CREATE3args * objp)17077c478bd9Sstevel@tonic-gate xdr_CREATE3args(XDR *xdrs, CREATE3args *objp)
17087c478bd9Sstevel@tonic-gate {
17097c478bd9Sstevel@tonic-gate 	createhow3 *howp;
17107c478bd9Sstevel@tonic-gate 
17117c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->where))
17127c478bd9Sstevel@tonic-gate 		return (FALSE);
17137c478bd9Sstevel@tonic-gate 
17147c478bd9Sstevel@tonic-gate 	/* xdr_createhow3 */
17157c478bd9Sstevel@tonic-gate 	howp = &objp->how;
17167c478bd9Sstevel@tonic-gate 
17177c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&howp->mode))
17187c478bd9Sstevel@tonic-gate 		return (FALSE);
17197c478bd9Sstevel@tonic-gate 	switch (howp->mode) {
17207c478bd9Sstevel@tonic-gate 	case UNCHECKED:
17217c478bd9Sstevel@tonic-gate 	case GUARDED:
17227c478bd9Sstevel@tonic-gate 		return (xdr_sattr3(xdrs, &howp->createhow3_u.obj_attributes));
17237c478bd9Sstevel@tonic-gate 	case EXCLUSIVE:
17247c478bd9Sstevel@tonic-gate 		/*
17257c478bd9Sstevel@tonic-gate 		 * createverf3 is really an opaque 8 byte
17267c478bd9Sstevel@tonic-gate 		 * quantity, but we will treat it as a
17277c478bd9Sstevel@tonic-gate 		 * hyper for efficiency, the cost of
17287c478bd9Sstevel@tonic-gate 		 * a byteswap here saves bcopys elsewhere
17297c478bd9Sstevel@tonic-gate 		 */
17307c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs, &howp->createhow3_u.verf));
17317c478bd9Sstevel@tonic-gate 	default:
17327c478bd9Sstevel@tonic-gate 		return (FALSE);
17337c478bd9Sstevel@tonic-gate 	}
17347c478bd9Sstevel@tonic-gate }
17357c478bd9Sstevel@tonic-gate 
17367c478bd9Sstevel@tonic-gate bool_t
xdr_CREATE3res(XDR * xdrs,CREATE3res * objp)17377c478bd9Sstevel@tonic-gate xdr_CREATE3res(XDR *xdrs, CREATE3res *objp)
17387c478bd9Sstevel@tonic-gate {
17397c478bd9Sstevel@tonic-gate 	CREATE3resok *resokp;
17407c478bd9Sstevel@tonic-gate 
17417c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
17427c478bd9Sstevel@tonic-gate 		return (FALSE);
17437c478bd9Sstevel@tonic-gate 	switch (objp->status) {
17447c478bd9Sstevel@tonic-gate 	case NFS3_OK:
17457c478bd9Sstevel@tonic-gate 		/* xdr_CREATE3resok */
17467c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
17477c478bd9Sstevel@tonic-gate 
17487c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
17497c478bd9Sstevel@tonic-gate 			return (FALSE);
17507c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
17517c478bd9Sstevel@tonic-gate 			return (FALSE);
17527c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
17537c478bd9Sstevel@tonic-gate 	default:
17547c478bd9Sstevel@tonic-gate 		/* xdr_CREATE3resfail */
17557c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
17567c478bd9Sstevel@tonic-gate 	}
17577c478bd9Sstevel@tonic-gate }
17587c478bd9Sstevel@tonic-gate 
17597c478bd9Sstevel@tonic-gate bool_t
xdr_MKDIR3args(XDR * xdrs,MKDIR3args * objp)17607c478bd9Sstevel@tonic-gate xdr_MKDIR3args(XDR *xdrs, MKDIR3args *objp)
17617c478bd9Sstevel@tonic-gate {
17627c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->where))
17637c478bd9Sstevel@tonic-gate 		return (FALSE);
17647c478bd9Sstevel@tonic-gate 	return (xdr_sattr3(xdrs, &objp->attributes));
17657c478bd9Sstevel@tonic-gate }
17667c478bd9Sstevel@tonic-gate 
17677c478bd9Sstevel@tonic-gate bool_t
xdr_MKDIR3res(XDR * xdrs,MKDIR3res * objp)17687c478bd9Sstevel@tonic-gate xdr_MKDIR3res(XDR *xdrs, MKDIR3res *objp)
17697c478bd9Sstevel@tonic-gate {
17707c478bd9Sstevel@tonic-gate 	MKDIR3resok *resokp;
17717c478bd9Sstevel@tonic-gate 
17727c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
17737c478bd9Sstevel@tonic-gate 		return (FALSE);
17747c478bd9Sstevel@tonic-gate 	switch (objp->status) {
17757c478bd9Sstevel@tonic-gate 	case NFS3_OK:
17767c478bd9Sstevel@tonic-gate 		/* xdr_MKDIR3resok */
17777c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
17787c478bd9Sstevel@tonic-gate 
17797c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
17807c478bd9Sstevel@tonic-gate 			return (FALSE);
17817c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
17827c478bd9Sstevel@tonic-gate 			return (FALSE);
17837c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
17847c478bd9Sstevel@tonic-gate 	default:
17857c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
17867c478bd9Sstevel@tonic-gate 	}
17877c478bd9Sstevel@tonic-gate }
17887c478bd9Sstevel@tonic-gate 
17897c478bd9Sstevel@tonic-gate bool_t
xdr_SYMLINK3args(XDR * xdrs,SYMLINK3args * objp)17907c478bd9Sstevel@tonic-gate xdr_SYMLINK3args(XDR *xdrs, SYMLINK3args *objp)
17917c478bd9Sstevel@tonic-gate {
17927c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->where))
17937c478bd9Sstevel@tonic-gate 		return (FALSE);
17947c478bd9Sstevel@tonic-gate 	if (!xdr_sattr3(xdrs, &objp->symlink.symlink_attributes))
17957c478bd9Sstevel@tonic-gate 		return (FALSE);
17967c478bd9Sstevel@tonic-gate 	return (xdr_string3(xdrs, &objp->symlink.symlink_data, MAXPATHLEN));
17977c478bd9Sstevel@tonic-gate }
17987c478bd9Sstevel@tonic-gate 
17997c478bd9Sstevel@tonic-gate bool_t
xdr_SYMLINK3res(XDR * xdrs,SYMLINK3res * objp)18007c478bd9Sstevel@tonic-gate xdr_SYMLINK3res(XDR *xdrs, SYMLINK3res *objp)
18017c478bd9Sstevel@tonic-gate {
18027c478bd9Sstevel@tonic-gate 	SYMLINK3resok *resokp;
18037c478bd9Sstevel@tonic-gate 
18047c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
18057c478bd9Sstevel@tonic-gate 		return (FALSE);
18067c478bd9Sstevel@tonic-gate 	switch (objp->status) {
18077c478bd9Sstevel@tonic-gate 	case NFS3_OK:
18087c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
18097c478bd9Sstevel@tonic-gate 		/* xdr_SYMLINK3resok */
18107c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
18117c478bd9Sstevel@tonic-gate 			return (FALSE);
18127c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
18137c478bd9Sstevel@tonic-gate 			return (FALSE);
18147c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
18157c478bd9Sstevel@tonic-gate 	default:
18167c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
18177c478bd9Sstevel@tonic-gate 	}
18187c478bd9Sstevel@tonic-gate }
18197c478bd9Sstevel@tonic-gate 
18207c478bd9Sstevel@tonic-gate bool_t
xdr_MKNOD3args(XDR * xdrs,MKNOD3args * objp)18217c478bd9Sstevel@tonic-gate xdr_MKNOD3args(XDR *xdrs, MKNOD3args *objp)
18227c478bd9Sstevel@tonic-gate {
18237c478bd9Sstevel@tonic-gate 	mknoddata3 *whatp;
18247c478bd9Sstevel@tonic-gate 	devicedata3 *nod_objp;
18257c478bd9Sstevel@tonic-gate 
18267c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->where))
18277c478bd9Sstevel@tonic-gate 		return (FALSE);
18287c478bd9Sstevel@tonic-gate 
18297c478bd9Sstevel@tonic-gate 	whatp = &objp->what;
18307c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&whatp->type))
18317c478bd9Sstevel@tonic-gate 		return (FALSE);
18327c478bd9Sstevel@tonic-gate 	switch (whatp->type) {
18337c478bd9Sstevel@tonic-gate 	case NF3CHR:
18347c478bd9Sstevel@tonic-gate 	case NF3BLK:
18357c478bd9Sstevel@tonic-gate 		/* xdr_devicedata3 */
18367c478bd9Sstevel@tonic-gate 		nod_objp = &whatp->mknoddata3_u.device;
18377c478bd9Sstevel@tonic-gate 		if (!xdr_sattr3(xdrs, &nod_objp->dev_attributes))
18387c478bd9Sstevel@tonic-gate 			return (FALSE);
18397c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &nod_objp->spec.specdata1))
18407c478bd9Sstevel@tonic-gate 			return (FALSE);
18417c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &nod_objp->spec.specdata2));
18427c478bd9Sstevel@tonic-gate 	case NF3SOCK:
18437c478bd9Sstevel@tonic-gate 	case NF3FIFO:
18447c478bd9Sstevel@tonic-gate 		return (xdr_sattr3(xdrs, &whatp->mknoddata3_u.pipe_attributes));
18457c478bd9Sstevel@tonic-gate 	default:
18467c478bd9Sstevel@tonic-gate 		break;
18477c478bd9Sstevel@tonic-gate 	}
18487c478bd9Sstevel@tonic-gate 	return (TRUE);
18497c478bd9Sstevel@tonic-gate }
18507c478bd9Sstevel@tonic-gate 
18517c478bd9Sstevel@tonic-gate bool_t
xdr_MKNOD3res(XDR * xdrs,MKNOD3res * objp)18527c478bd9Sstevel@tonic-gate xdr_MKNOD3res(XDR *xdrs, MKNOD3res *objp)
18537c478bd9Sstevel@tonic-gate {
18547c478bd9Sstevel@tonic-gate 	MKNOD3resok *resokp;
18557c478bd9Sstevel@tonic-gate 
18567c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
18577c478bd9Sstevel@tonic-gate 		return (FALSE);
18587c478bd9Sstevel@tonic-gate 	switch (objp->status) {
18597c478bd9Sstevel@tonic-gate 	case NFS3_OK:
18607c478bd9Sstevel@tonic-gate 		/* xdr_MKNOD3resok */
18617c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
18627c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
18637c478bd9Sstevel@tonic-gate 			return (FALSE);
18647c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
18657c478bd9Sstevel@tonic-gate 			return (FALSE);
18667c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
18677c478bd9Sstevel@tonic-gate 	default:
18687c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
18697c478bd9Sstevel@tonic-gate 	}
18707c478bd9Sstevel@tonic-gate }
18717c478bd9Sstevel@tonic-gate 
18727c478bd9Sstevel@tonic-gate bool_t
xdr_REMOVE3res(XDR * xdrs,REMOVE3res * objp)18737c478bd9Sstevel@tonic-gate xdr_REMOVE3res(XDR *xdrs, REMOVE3res *objp)
18747c478bd9Sstevel@tonic-gate {
18757c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
18767c478bd9Sstevel@tonic-gate 		return (FALSE);
18777c478bd9Sstevel@tonic-gate 	switch (objp->status) {
18787c478bd9Sstevel@tonic-gate 	case NFS3_OK:
18797c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
18807c478bd9Sstevel@tonic-gate 	default:
18817c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
18827c478bd9Sstevel@tonic-gate 	}
18837c478bd9Sstevel@tonic-gate }
18847c478bd9Sstevel@tonic-gate 
18857c478bd9Sstevel@tonic-gate bool_t
xdr_RMDIR3res(XDR * xdrs,RMDIR3res * objp)18867c478bd9Sstevel@tonic-gate xdr_RMDIR3res(XDR *xdrs, RMDIR3res *objp)
18877c478bd9Sstevel@tonic-gate {
18887c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
18897c478bd9Sstevel@tonic-gate 		return (FALSE);
18907c478bd9Sstevel@tonic-gate 	switch (objp->status) {
18917c478bd9Sstevel@tonic-gate 	case NFS3_OK:
18927c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
18937c478bd9Sstevel@tonic-gate 	default:
18947c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
18957c478bd9Sstevel@tonic-gate 	}
18967c478bd9Sstevel@tonic-gate }
18977c478bd9Sstevel@tonic-gate 
18987c478bd9Sstevel@tonic-gate bool_t
xdr_RENAME3args(XDR * xdrs,RENAME3args * objp)18997c478bd9Sstevel@tonic-gate xdr_RENAME3args(XDR *xdrs, RENAME3args *objp)
19007c478bd9Sstevel@tonic-gate {
19017c478bd9Sstevel@tonic-gate 	if (!xdr_diropargs3(xdrs, &objp->from))
19027c478bd9Sstevel@tonic-gate 		return (FALSE);
19037c478bd9Sstevel@tonic-gate 	return (xdr_diropargs3(xdrs, &objp->to));
19047c478bd9Sstevel@tonic-gate }
19057c478bd9Sstevel@tonic-gate 
19067c478bd9Sstevel@tonic-gate bool_t
xdr_RENAME3res(XDR * xdrs,RENAME3res * objp)19077c478bd9Sstevel@tonic-gate xdr_RENAME3res(XDR *xdrs, RENAME3res *objp)
19087c478bd9Sstevel@tonic-gate {
19097c478bd9Sstevel@tonic-gate 	RENAME3resok *resokp;
19107c478bd9Sstevel@tonic-gate 	RENAME3resfail *resfailp;
19117c478bd9Sstevel@tonic-gate 
19127c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
19137c478bd9Sstevel@tonic-gate 		return (FALSE);
19147c478bd9Sstevel@tonic-gate 	switch (objp->status) {
19157c478bd9Sstevel@tonic-gate 	case NFS3_OK:
19167c478bd9Sstevel@tonic-gate 		/* xdr_RENAME3resok */
19177c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
19187c478bd9Sstevel@tonic-gate 
19197c478bd9Sstevel@tonic-gate 		if (!xdr_wcc_data(xdrs, &resokp->fromdir_wcc))
19207c478bd9Sstevel@tonic-gate 			return (FALSE);
19217c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->todir_wcc));
19227c478bd9Sstevel@tonic-gate 	default:
19237c478bd9Sstevel@tonic-gate 		/* xdr_RENAME3resfail */
19247c478bd9Sstevel@tonic-gate 		resfailp = &objp->resfail;
19257c478bd9Sstevel@tonic-gate 		if (!xdr_wcc_data(xdrs, &resfailp->fromdir_wcc))
19267c478bd9Sstevel@tonic-gate 			return (FALSE);
19277c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resfailp->todir_wcc));
19287c478bd9Sstevel@tonic-gate 	}
19297c478bd9Sstevel@tonic-gate }
19307c478bd9Sstevel@tonic-gate 
19317c478bd9Sstevel@tonic-gate bool_t
xdr_LINK3args(XDR * xdrs,LINK3args * objp)19327c478bd9Sstevel@tonic-gate xdr_LINK3args(XDR *xdrs, LINK3args *objp)
19337c478bd9Sstevel@tonic-gate {
193427242a7cSthurlow 	switch (xdrs->x_op) {
193527242a7cSthurlow 	case XDR_FREE:
193627242a7cSthurlow 	case XDR_ENCODE:
193727242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, &objp->file))
193827242a7cSthurlow 			return (FALSE);
193927242a7cSthurlow 		break;
194027242a7cSthurlow 	case XDR_DECODE:
194127242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
194227242a7cSthurlow 			return (FALSE);
194327242a7cSthurlow 		break;
194427242a7cSthurlow 	}
19457c478bd9Sstevel@tonic-gate 	return (xdr_diropargs3(xdrs, &objp->link));
19467c478bd9Sstevel@tonic-gate }
19477c478bd9Sstevel@tonic-gate 
19487c478bd9Sstevel@tonic-gate bool_t
xdr_LINK3res(XDR * xdrs,LINK3res * objp)19497c478bd9Sstevel@tonic-gate xdr_LINK3res(XDR *xdrs, LINK3res *objp)
19507c478bd9Sstevel@tonic-gate {
19517c478bd9Sstevel@tonic-gate 	LINK3resok *resokp;
19527c478bd9Sstevel@tonic-gate 	LINK3resfail *resfailp;
19537c478bd9Sstevel@tonic-gate 
19547c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
19557c478bd9Sstevel@tonic-gate 		return (FALSE);
19567c478bd9Sstevel@tonic-gate 	switch (objp->status) {
19577c478bd9Sstevel@tonic-gate 	case NFS3_OK:
19587c478bd9Sstevel@tonic-gate 		/* xdr_LINK3resok */
19597c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
19607c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->file_attributes))
19617c478bd9Sstevel@tonic-gate 			return (FALSE);
19627c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resokp->linkdir_wcc));
19637c478bd9Sstevel@tonic-gate 	default:
19647c478bd9Sstevel@tonic-gate 		/* xdr_LINK3resfail */
19657c478bd9Sstevel@tonic-gate 		resfailp = &objp->resfail;
19667c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resfailp->file_attributes))
19677c478bd9Sstevel@tonic-gate 			return (FALSE);
19687c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &resfailp->linkdir_wcc));
19697c478bd9Sstevel@tonic-gate 	}
19707c478bd9Sstevel@tonic-gate }
19717c478bd9Sstevel@tonic-gate 
19727c478bd9Sstevel@tonic-gate bool_t
xdr_READDIR3args(XDR * xdrs,READDIR3args * objp)19737c478bd9Sstevel@tonic-gate xdr_READDIR3args(XDR *xdrs, READDIR3args *objp)
19747c478bd9Sstevel@tonic-gate {
19750a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
19760a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
19770a701b1eSRobert Gordon 
19787c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
19797c478bd9Sstevel@tonic-gate 		return (TRUE);
19807c478bd9Sstevel@tonic-gate 
198127242a7cSthurlow 	switch (xdrs->x_op) {
198227242a7cSthurlow 	case XDR_FREE:
198327242a7cSthurlow 	case XDR_ENCODE:
198427242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, &objp->dir))
198527242a7cSthurlow 			return (FALSE);
198627242a7cSthurlow 		break;
198727242a7cSthurlow 	case XDR_DECODE:
198827242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
198927242a7cSthurlow 			return (FALSE);
199027242a7cSthurlow 		break;
19917c478bd9Sstevel@tonic-gate 	}
19920a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
19930a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
19940a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
19950a701b1eSRobert Gordon 		rci.rci_len = objp->count;
19960a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
19970a701b1eSRobert Gordon 	}
19980a701b1eSRobert Gordon 
19997c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookie))
20007c478bd9Sstevel@tonic-gate 		return (FALSE);
20017c478bd9Sstevel@tonic-gate 	/*
20027c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
20037c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
20047c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
20057c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
20067c478bd9Sstevel@tonic-gate 	 */
20077c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
20087c478bd9Sstevel@tonic-gate 		return (FALSE);
20097c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->count));
20107c478bd9Sstevel@tonic-gate }
20117c478bd9Sstevel@tonic-gate 
20127c478bd9Sstevel@tonic-gate #ifdef	nextdp
20137c478bd9Sstevel@tonic-gate #undef	nextdp
20147c478bd9Sstevel@tonic-gate #endif
20157c478bd9Sstevel@tonic-gate #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
20167c478bd9Sstevel@tonic-gate #ifdef	roundup
20177c478bd9Sstevel@tonic-gate #undef	roundup
20187c478bd9Sstevel@tonic-gate #endif
20197c478bd9Sstevel@tonic-gate #define	roundup(x, y)	((((x) + ((y) - 1)) / (y)) * (y))
20207c478bd9Sstevel@tonic-gate 
20217c478bd9Sstevel@tonic-gate /*
20227c478bd9Sstevel@tonic-gate  * ENCODE ONLY
20237c478bd9Sstevel@tonic-gate  */
20247c478bd9Sstevel@tonic-gate static bool_t
xdr_putdirlist(XDR * xdrs,READDIR3resok * objp)20257c478bd9Sstevel@tonic-gate xdr_putdirlist(XDR *xdrs, READDIR3resok *objp)
20267c478bd9Sstevel@tonic-gate {
20277c478bd9Sstevel@tonic-gate 	struct dirent64 *dp;
20287c478bd9Sstevel@tonic-gate 	char *name;
20297c478bd9Sstevel@tonic-gate 	int size;
20307c478bd9Sstevel@tonic-gate 	int bufsize;
20317c478bd9Sstevel@tonic-gate 	uint_t namlen;
20327c478bd9Sstevel@tonic-gate 	bool_t true = TRUE;
20337c478bd9Sstevel@tonic-gate 	bool_t false = FALSE;
20347c478bd9Sstevel@tonic-gate 	int entrysz;
20357c478bd9Sstevel@tonic-gate 	int tofit;
20367c478bd9Sstevel@tonic-gate 	fileid3 fileid;
20377c478bd9Sstevel@tonic-gate 	cookie3 cookie;
20387c478bd9Sstevel@tonic-gate 
20397c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_ENCODE)
20407c478bd9Sstevel@tonic-gate 		return (FALSE);
20417c478bd9Sstevel@tonic-gate 
20427c478bd9Sstevel@tonic-gate 	/*
20437c478bd9Sstevel@tonic-gate 	 * bufsize is used to keep track of the size of the response.
20447c478bd9Sstevel@tonic-gate 	 * It is primed with:
20457c478bd9Sstevel@tonic-gate 	 *	1 for the status +
20467c478bd9Sstevel@tonic-gate 	 *	1 for the dir_attributes.attributes boolean +
20477c478bd9Sstevel@tonic-gate 	 *	2 for the cookie verifier
20487c478bd9Sstevel@tonic-gate 	 * all times BYTES_PER_XDR_UNIT to convert from XDR units
20497c478bd9Sstevel@tonic-gate 	 * to bytes.  If there are directory attributes to be
20507c478bd9Sstevel@tonic-gate 	 * returned, then:
20517c478bd9Sstevel@tonic-gate 	 *	NFS3_SIZEOF_FATTR3 for the dir_attributes.attr fattr3
20527c478bd9Sstevel@tonic-gate 	 * time BYTES_PER_XDR_UNIT is added to account for them.
20537c478bd9Sstevel@tonic-gate 	 */
20547c478bd9Sstevel@tonic-gate 	bufsize = (1 + 1 + 2) * BYTES_PER_XDR_UNIT;
20557c478bd9Sstevel@tonic-gate 	if (objp->dir_attributes.attributes)
20567c478bd9Sstevel@tonic-gate 		bufsize += NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
20577c478bd9Sstevel@tonic-gate 	for (size = objp->size, dp = (struct dirent64 *)objp->reply.entries;
20587c478bd9Sstevel@tonic-gate 	    size > 0;
20597c478bd9Sstevel@tonic-gate 	    size -= dp->d_reclen, dp = nextdp(dp)) {
20607c478bd9Sstevel@tonic-gate 		if (dp->d_reclen == 0)
20617c478bd9Sstevel@tonic-gate 			return (FALSE);
20627c478bd9Sstevel@tonic-gate 		if (dp->d_ino == 0)
20637c478bd9Sstevel@tonic-gate 			continue;
20647c478bd9Sstevel@tonic-gate 		name = dp->d_name;
20657c478bd9Sstevel@tonic-gate 		namlen = (uint_t)strlen(dp->d_name);
20667c478bd9Sstevel@tonic-gate 		/*
20677c478bd9Sstevel@tonic-gate 		 * An entry is composed of:
20687c478bd9Sstevel@tonic-gate 		 *	1 for the true/false list indicator +
20697c478bd9Sstevel@tonic-gate 		 *	2 for the fileid +
20707c478bd9Sstevel@tonic-gate 		 *	1 for the length of the name +
20717c478bd9Sstevel@tonic-gate 		 *	2 for the cookie +
20727c478bd9Sstevel@tonic-gate 		 * all times BYTES_PER_XDR_UNIT to convert from
20737c478bd9Sstevel@tonic-gate 		 * XDR units to bytes, plus the length of the name
20747c478bd9Sstevel@tonic-gate 		 * rounded up to the nearest BYTES_PER_XDR_UNIT.
20757c478bd9Sstevel@tonic-gate 		 */
20767c478bd9Sstevel@tonic-gate 		entrysz = (1 + 2 + 1 + 2) * BYTES_PER_XDR_UNIT +
20777c478bd9Sstevel@tonic-gate 		    roundup(namlen, BYTES_PER_XDR_UNIT);
20787c478bd9Sstevel@tonic-gate 		/*
20797c478bd9Sstevel@tonic-gate 		 * We need to check to see if the number of bytes left
20807c478bd9Sstevel@tonic-gate 		 * to go into the buffer will actually fit into the
20817c478bd9Sstevel@tonic-gate 		 * buffer.  This is calculated as the size of this
20827c478bd9Sstevel@tonic-gate 		 * entry plus:
20837c478bd9Sstevel@tonic-gate 		 *	1 for the true/false list indicator +
20847c478bd9Sstevel@tonic-gate 		 *	1 for the eof indicator
20857c478bd9Sstevel@tonic-gate 		 * times BYTES_PER_XDR_UNIT to convert from from
20867c478bd9Sstevel@tonic-gate 		 * XDR units to bytes.
20877c478bd9Sstevel@tonic-gate 		 */
20887c478bd9Sstevel@tonic-gate 		tofit = entrysz + (1 + 1) * BYTES_PER_XDR_UNIT;
20897c478bd9Sstevel@tonic-gate 		if (bufsize + tofit > objp->count) {
20907c478bd9Sstevel@tonic-gate 			objp->reply.eof = FALSE;
20917c478bd9Sstevel@tonic-gate 			break;
20927c478bd9Sstevel@tonic-gate 		}
20937c478bd9Sstevel@tonic-gate 		fileid = (fileid3)(dp->d_ino);
20947c478bd9Sstevel@tonic-gate 		cookie = (cookie3)(dp->d_off);
20957c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &true) ||
20967c478bd9Sstevel@tonic-gate 		    !xdr_u_longlong_t(xdrs, &fileid) ||
20977c478bd9Sstevel@tonic-gate 		    !xdr_bytes(xdrs, &name, &namlen, ~0) ||
20987c478bd9Sstevel@tonic-gate 		    !xdr_u_longlong_t(xdrs, &cookie)) {
20997c478bd9Sstevel@tonic-gate 			return (FALSE);
21007c478bd9Sstevel@tonic-gate 		}
21017c478bd9Sstevel@tonic-gate 		bufsize += entrysz;
21027c478bd9Sstevel@tonic-gate 	}
21037c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &false))
21047c478bd9Sstevel@tonic-gate 		return (FALSE);
21057c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->reply.eof))
21067c478bd9Sstevel@tonic-gate 		return (FALSE);
21077c478bd9Sstevel@tonic-gate 	return (TRUE);
21087c478bd9Sstevel@tonic-gate }
21097c478bd9Sstevel@tonic-gate 
21107c478bd9Sstevel@tonic-gate bool_t
xdr_READDIR3res(XDR * xdrs,READDIR3res * objp)21117c478bd9Sstevel@tonic-gate xdr_READDIR3res(XDR *xdrs, READDIR3res *objp)
21127c478bd9Sstevel@tonic-gate {
21137c478bd9Sstevel@tonic-gate 	READDIR3resok *resokp;
21147c478bd9Sstevel@tonic-gate 
21157c478bd9Sstevel@tonic-gate 	/*
21167c478bd9Sstevel@tonic-gate 	 * ENCODE or FREE only
21177c478bd9Sstevel@tonic-gate 	 */
21187c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
21197c478bd9Sstevel@tonic-gate 		return (FALSE);
21207c478bd9Sstevel@tonic-gate 
21217c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
21227c478bd9Sstevel@tonic-gate 		return (FALSE);
21237c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
21247c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
21257c478bd9Sstevel@tonic-gate 
21267c478bd9Sstevel@tonic-gate 	/* xdr_READDIR3resok */
21277c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
21287c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
21297c478bd9Sstevel@tonic-gate 		return (FALSE);
21307c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_ENCODE)
21317c478bd9Sstevel@tonic-gate 		return (TRUE);
21327c478bd9Sstevel@tonic-gate 	/*
21337c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
21347c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
21357c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
21367c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
21377c478bd9Sstevel@tonic-gate 	 */
21387c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
21397c478bd9Sstevel@tonic-gate 		return (FALSE);
21407c478bd9Sstevel@tonic-gate 	return (xdr_putdirlist(xdrs, resokp));
21417c478bd9Sstevel@tonic-gate }
21427c478bd9Sstevel@tonic-gate 
21437c478bd9Sstevel@tonic-gate bool_t
xdr_READDIR3vres(XDR * xdrs,READDIR3vres * objp)21447c478bd9Sstevel@tonic-gate xdr_READDIR3vres(XDR *xdrs, READDIR3vres *objp)
21457c478bd9Sstevel@tonic-gate {
21467c478bd9Sstevel@tonic-gate 	dirent64_t *dp;
21477c478bd9Sstevel@tonic-gate 	uint_t entries_size;
21487c478bd9Sstevel@tonic-gate 	int outcount = 0;
21497c478bd9Sstevel@tonic-gate 
21507c478bd9Sstevel@tonic-gate 	/*
21517c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
21527c478bd9Sstevel@tonic-gate 	 */
21537c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
21547c478bd9Sstevel@tonic-gate 		return (TRUE);
21557c478bd9Sstevel@tonic-gate 
21567c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
21577c478bd9Sstevel@tonic-gate 		return (FALSE);
21587c478bd9Sstevel@tonic-gate 
21597c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
21607c478bd9Sstevel@tonic-gate 		return (FALSE);
21617c478bd9Sstevel@tonic-gate 
21627c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
21637c478bd9Sstevel@tonic-gate 		return (FALSE);
21647c478bd9Sstevel@tonic-gate 
21657c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
21667c478bd9Sstevel@tonic-gate 		return (TRUE);
21677c478bd9Sstevel@tonic-gate 
21687c478bd9Sstevel@tonic-gate 	/*
21697c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
21707c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
21717c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
21727c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
21737c478bd9Sstevel@tonic-gate 	 */
21747c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
21757c478bd9Sstevel@tonic-gate 		return (FALSE);
21767c478bd9Sstevel@tonic-gate 
21777c478bd9Sstevel@tonic-gate 	entries_size = objp->entries_size;
21787c478bd9Sstevel@tonic-gate 	dp = objp->entries;
21797c478bd9Sstevel@tonic-gate 
21807c478bd9Sstevel@tonic-gate 	for (;;) {
21817c478bd9Sstevel@tonic-gate 		uint_t this_reclen;
21827c478bd9Sstevel@tonic-gate 		bool_t valid;
21837c478bd9Sstevel@tonic-gate 		uint_t namlen;
21847c478bd9Sstevel@tonic-gate 		ino64_t fileid;
21857c478bd9Sstevel@tonic-gate 
21867c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
21877c478bd9Sstevel@tonic-gate 			return (FALSE);
21887c478bd9Sstevel@tonic-gate 		if (!valid) {
21897c478bd9Sstevel@tonic-gate 			/*
21907c478bd9Sstevel@tonic-gate 			 * We have run out of entries, decode eof.
21917c478bd9Sstevel@tonic-gate 			 */
21927c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
21937c478bd9Sstevel@tonic-gate 				return (FALSE);
21947c478bd9Sstevel@tonic-gate 
21957c478bd9Sstevel@tonic-gate 			break;
21967c478bd9Sstevel@tonic-gate 		}
21977c478bd9Sstevel@tonic-gate 
21987c478bd9Sstevel@tonic-gate 		/*
21997c478bd9Sstevel@tonic-gate 		 * fileid3 fileid
22007c478bd9Sstevel@tonic-gate 		 */
22017c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
22027c478bd9Sstevel@tonic-gate 			return (FALSE);
22037c478bd9Sstevel@tonic-gate 
22047c478bd9Sstevel@tonic-gate 		/*
22057c478bd9Sstevel@tonic-gate 		 * filename3 name
22067c478bd9Sstevel@tonic-gate 		 */
22077c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
22087c478bd9Sstevel@tonic-gate 			return (FALSE);
22097c478bd9Sstevel@tonic-gate 		this_reclen = DIRENT64_RECLEN(namlen);
22107c478bd9Sstevel@tonic-gate 
22117c478bd9Sstevel@tonic-gate 		/*
22127c478bd9Sstevel@tonic-gate 		 * If this will overflow buffer, stop decoding
22137c478bd9Sstevel@tonic-gate 		 */
22147c478bd9Sstevel@tonic-gate 		if ((outcount + this_reclen) > entries_size) {
22157c478bd9Sstevel@tonic-gate 			objp->eof = FALSE;
22167c478bd9Sstevel@tonic-gate 			break;
22177c478bd9Sstevel@tonic-gate 		}
22187c478bd9Sstevel@tonic-gate 		dp->d_reclen = this_reclen;
22197c478bd9Sstevel@tonic-gate 		dp->d_ino = fileid;
22207c478bd9Sstevel@tonic-gate 
22217c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, dp->d_name, namlen))
22227c478bd9Sstevel@tonic-gate 			return (FALSE);
22237c478bd9Sstevel@tonic-gate 		bzero(&dp->d_name[namlen],
22247c478bd9Sstevel@tonic-gate 		    DIRENT64_NAMELEN(this_reclen) - namlen);
22257c478bd9Sstevel@tonic-gate 
22267c478bd9Sstevel@tonic-gate 		/*
22277c478bd9Sstevel@tonic-gate 		 * cookie3 cookie
22287c478bd9Sstevel@tonic-gate 		 */
22297c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
22307c478bd9Sstevel@tonic-gate 			return (FALSE);
22317c478bd9Sstevel@tonic-gate 		objp->loff = dp->d_off;
22327c478bd9Sstevel@tonic-gate 
22337c478bd9Sstevel@tonic-gate 		outcount += this_reclen;
22347c478bd9Sstevel@tonic-gate 		dp = (dirent64_t *)((intptr_t)dp + this_reclen);
22357c478bd9Sstevel@tonic-gate 	}
22367c478bd9Sstevel@tonic-gate 
22377c478bd9Sstevel@tonic-gate 	objp->size = outcount;
22387c478bd9Sstevel@tonic-gate 	return (TRUE);
22397c478bd9Sstevel@tonic-gate }
22407c478bd9Sstevel@tonic-gate 
22417c478bd9Sstevel@tonic-gate bool_t
xdr_READDIRPLUS3args(XDR * xdrs,READDIRPLUS3args * objp)22427c478bd9Sstevel@tonic-gate xdr_READDIRPLUS3args(XDR *xdrs, READDIRPLUS3args *objp)
22437c478bd9Sstevel@tonic-gate {
22440a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
22450a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
22460a701b1eSRobert Gordon 
22477c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
22487c478bd9Sstevel@tonic-gate 		return (TRUE);
22497c478bd9Sstevel@tonic-gate 
225027242a7cSthurlow 	switch (xdrs->x_op) {
225127242a7cSthurlow 	case XDR_FREE:
225227242a7cSthurlow 	case XDR_ENCODE:
225327242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, &objp->dir))
225427242a7cSthurlow 			return (FALSE);
225527242a7cSthurlow 		break;
225627242a7cSthurlow 	case XDR_DECODE:
225727242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
225827242a7cSthurlow 			return (FALSE);
225927242a7cSthurlow 		break;
22607c478bd9Sstevel@tonic-gate 	}
22610a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
22620a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
22630a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
22640a701b1eSRobert Gordon 		rci.rci_len = objp->maxcount;
22650a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
22660a701b1eSRobert Gordon 	}
22670a701b1eSRobert Gordon 
22687c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookie))
22697c478bd9Sstevel@tonic-gate 		return (FALSE);
22707c478bd9Sstevel@tonic-gate 	/*
22717c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
22727c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
22737c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
22747c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
22757c478bd9Sstevel@tonic-gate 	 */
22767c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
22777c478bd9Sstevel@tonic-gate 		return (FALSE);
22787c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->dircount))
22797c478bd9Sstevel@tonic-gate 		return (FALSE);
22807c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->maxcount));
22817c478bd9Sstevel@tonic-gate }
22827c478bd9Sstevel@tonic-gate 
22837c478bd9Sstevel@tonic-gate /*
22847c478bd9Sstevel@tonic-gate  * ENCODE ONLY
22857c478bd9Sstevel@tonic-gate  */
22867c478bd9Sstevel@tonic-gate static bool_t
xdr_putdirpluslist(XDR * xdrs,READDIRPLUS3resok * objp)22877c478bd9Sstevel@tonic-gate xdr_putdirpluslist(XDR *xdrs, READDIRPLUS3resok *objp)
22887c478bd9Sstevel@tonic-gate {
22897c478bd9Sstevel@tonic-gate 	struct dirent64 *dp;
22907c478bd9Sstevel@tonic-gate 	char *name;
22917c478bd9Sstevel@tonic-gate 	int nents;
22927c478bd9Sstevel@tonic-gate 	bool_t true = TRUE;
22937c478bd9Sstevel@tonic-gate 	bool_t false = FALSE;
22947c478bd9Sstevel@tonic-gate 	fileid3 fileid;
22957c478bd9Sstevel@tonic-gate 	cookie3 cookie;
22967c478bd9Sstevel@tonic-gate 	entryplus3_info *infop;
22977c478bd9Sstevel@tonic-gate 
22987c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_ENCODE)
22997c478bd9Sstevel@tonic-gate 		return (FALSE);
23007c478bd9Sstevel@tonic-gate 
23017c478bd9Sstevel@tonic-gate 	dp = (struct dirent64 *)objp->reply.entries;
23027c478bd9Sstevel@tonic-gate 	nents = objp->size;
23037c478bd9Sstevel@tonic-gate 	infop = objp->infop;
23047c478bd9Sstevel@tonic-gate 
23057c478bd9Sstevel@tonic-gate 	while (nents > 0) {
23067c478bd9Sstevel@tonic-gate 		if (dp->d_reclen == 0)
23077c478bd9Sstevel@tonic-gate 			return (FALSE);
23087c478bd9Sstevel@tonic-gate 		if (dp->d_ino != 0) {
23097c478bd9Sstevel@tonic-gate 			name = dp->d_name;
23107c478bd9Sstevel@tonic-gate 			fileid = (fileid3)(dp->d_ino);
23117c478bd9Sstevel@tonic-gate 			cookie = (cookie3)(dp->d_off);
23127c478bd9Sstevel@tonic-gate 			if (!xdr_bool(xdrs, &true) ||
23137c478bd9Sstevel@tonic-gate 			    !xdr_u_longlong_t(xdrs, &fileid) ||
23147c478bd9Sstevel@tonic-gate 			    !xdr_bytes(xdrs, &name, &infop->namelen, ~0) ||
23157c478bd9Sstevel@tonic-gate 			    !xdr_u_longlong_t(xdrs, &cookie) ||
23167c478bd9Sstevel@tonic-gate 			    !xdr_post_op_attr(xdrs, &infop->attr) ||
23177c478bd9Sstevel@tonic-gate 			    !xdr_post_op_fh3(xdrs, &infop->fh)) {
23187c478bd9Sstevel@tonic-gate 				return (FALSE);
23197c478bd9Sstevel@tonic-gate 			}
23207c478bd9Sstevel@tonic-gate 		}
23217c478bd9Sstevel@tonic-gate 		dp = nextdp(dp);
23227c478bd9Sstevel@tonic-gate 		infop++;
23237c478bd9Sstevel@tonic-gate 		nents--;
23247c478bd9Sstevel@tonic-gate 	}
23257c478bd9Sstevel@tonic-gate 
23267c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &false))
23277c478bd9Sstevel@tonic-gate 		return (FALSE);
23287c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->reply.eof))
23297c478bd9Sstevel@tonic-gate 		return (FALSE);
23307c478bd9Sstevel@tonic-gate 	return (TRUE);
23317c478bd9Sstevel@tonic-gate }
23327c478bd9Sstevel@tonic-gate 
23337c478bd9Sstevel@tonic-gate bool_t
xdr_READDIRPLUS3res(XDR * xdrs,READDIRPLUS3res * objp)23347c478bd9Sstevel@tonic-gate xdr_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
23357c478bd9Sstevel@tonic-gate {
23367c478bd9Sstevel@tonic-gate 	READDIRPLUS3resok *resokp;
23377c478bd9Sstevel@tonic-gate 
23387c478bd9Sstevel@tonic-gate 	/*
23397c478bd9Sstevel@tonic-gate 	 * ENCODE or FREE only
23407c478bd9Sstevel@tonic-gate 	 */
23417c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
23427c478bd9Sstevel@tonic-gate 		return (FALSE);
23437c478bd9Sstevel@tonic-gate 
23447c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
23457c478bd9Sstevel@tonic-gate 		return (FALSE);
23467c478bd9Sstevel@tonic-gate 	switch (objp->status) {
23477c478bd9Sstevel@tonic-gate 	case NFS3_OK:
23487c478bd9Sstevel@tonic-gate 		/* xdr_READDIRPLUS3resok */
23497c478bd9Sstevel@tonic-gate 		resokp = &objp->resok;
23507c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
23517c478bd9Sstevel@tonic-gate 			return (FALSE);
23527c478bd9Sstevel@tonic-gate 		/*
23537c478bd9Sstevel@tonic-gate 		 * cookieverf is really an opaque 8 byte
23547c478bd9Sstevel@tonic-gate 		 * quantity, but we will treat it as a
23557c478bd9Sstevel@tonic-gate 		 * hyper for efficiency, the cost of
23567c478bd9Sstevel@tonic-gate 		 * a byteswap here saves bcopys elsewhere
23577c478bd9Sstevel@tonic-gate 		 */
23587c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
23597c478bd9Sstevel@tonic-gate 			return (FALSE);
23607c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_ENCODE) {
23617c478bd9Sstevel@tonic-gate 			if (!xdr_putdirpluslist(xdrs, resokp))
23627c478bd9Sstevel@tonic-gate 				return (FALSE);
23637c478bd9Sstevel@tonic-gate 		}
23647c478bd9Sstevel@tonic-gate 		break;
23657c478bd9Sstevel@tonic-gate 	default:
23667c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
23677c478bd9Sstevel@tonic-gate 	}
23687c478bd9Sstevel@tonic-gate 	return (TRUE);
23697c478bd9Sstevel@tonic-gate }
23707c478bd9Sstevel@tonic-gate 
23717c478bd9Sstevel@tonic-gate /*
23727c478bd9Sstevel@tonic-gate  * Decode readdirplus directly into a dirent64_t and do the DNLC caching.
23737c478bd9Sstevel@tonic-gate  */
23747c478bd9Sstevel@tonic-gate bool_t
xdr_READDIRPLUS3vres(XDR * xdrs,READDIRPLUS3vres * objp)23757c478bd9Sstevel@tonic-gate xdr_READDIRPLUS3vres(XDR *xdrs, READDIRPLUS3vres *objp)
23767c478bd9Sstevel@tonic-gate {
23777c478bd9Sstevel@tonic-gate 	dirent64_t *dp;
23787c478bd9Sstevel@tonic-gate 	vnode_t *dvp;
23797c478bd9Sstevel@tonic-gate 	uint_t entries_size;
23807c478bd9Sstevel@tonic-gate 	int outcount = 0;
23817c478bd9Sstevel@tonic-gate 	vnode_t *nvp;
23827c478bd9Sstevel@tonic-gate 	rnode_t *rp;
23837c478bd9Sstevel@tonic-gate 	post_op_vattr pov;
23847c478bd9Sstevel@tonic-gate 	vattr_t va;
23857c478bd9Sstevel@tonic-gate 
23867c478bd9Sstevel@tonic-gate 	/*
23877c478bd9Sstevel@tonic-gate 	 * DECODE or FREE only
23887c478bd9Sstevel@tonic-gate 	 */
23897c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
23907c478bd9Sstevel@tonic-gate 		return (TRUE);
23917c478bd9Sstevel@tonic-gate 
23927c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_DECODE)
23937c478bd9Sstevel@tonic-gate 		return (FALSE);
23947c478bd9Sstevel@tonic-gate 
23957c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
23967c478bd9Sstevel@tonic-gate 		return (FALSE);
23977c478bd9Sstevel@tonic-gate 
23987c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
23997c478bd9Sstevel@tonic-gate 		return (FALSE);
24007c478bd9Sstevel@tonic-gate 
24017c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
24027c478bd9Sstevel@tonic-gate 		return (TRUE);
24037c478bd9Sstevel@tonic-gate 
24047c478bd9Sstevel@tonic-gate 	/*
24057c478bd9Sstevel@tonic-gate 	 * cookieverf is really an opaque 8 byte
24067c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
24077c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
24087c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
24097c478bd9Sstevel@tonic-gate 	 */
24107c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
24117c478bd9Sstevel@tonic-gate 		return (FALSE);
24127c478bd9Sstevel@tonic-gate 
24137c478bd9Sstevel@tonic-gate 	dvp = objp->dir_attributes.fres.vp;
24147c478bd9Sstevel@tonic-gate 	rp = VTOR(dvp);
24157c478bd9Sstevel@tonic-gate 
24167c478bd9Sstevel@tonic-gate 	pov.fres.vap = &va;
24177c478bd9Sstevel@tonic-gate 	pov.fres.vp = dvp;
24187c478bd9Sstevel@tonic-gate 
24197c478bd9Sstevel@tonic-gate 	entries_size = objp->entries_size;
24207c478bd9Sstevel@tonic-gate 	dp = objp->entries;
24217c478bd9Sstevel@tonic-gate 
24227c478bd9Sstevel@tonic-gate 	for (;;) {
24237c478bd9Sstevel@tonic-gate 		uint_t this_reclen;
24247c478bd9Sstevel@tonic-gate 		bool_t valid;
24257c478bd9Sstevel@tonic-gate 		uint_t namlen;
24267c478bd9Sstevel@tonic-gate 		nfs_fh3 fh;
24277c478bd9Sstevel@tonic-gate 		int va_valid;
24287c478bd9Sstevel@tonic-gate 		int fh_valid;
24297c478bd9Sstevel@tonic-gate 		ino64_t fileid;
24307c478bd9Sstevel@tonic-gate 
24317c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
24327c478bd9Sstevel@tonic-gate 			return (FALSE);
24337c478bd9Sstevel@tonic-gate 		if (!valid) {
24347c478bd9Sstevel@tonic-gate 			/*
24357c478bd9Sstevel@tonic-gate 			 * We have run out of entries, decode eof.
24367c478bd9Sstevel@tonic-gate 			 */
24377c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
24387c478bd9Sstevel@tonic-gate 				return (FALSE);
24397c478bd9Sstevel@tonic-gate 
24407c478bd9Sstevel@tonic-gate 			break;
24417c478bd9Sstevel@tonic-gate 		}
24427c478bd9Sstevel@tonic-gate 
24437c478bd9Sstevel@tonic-gate 		/*
24447c478bd9Sstevel@tonic-gate 		 * fileid3 fileid
24457c478bd9Sstevel@tonic-gate 		 */
24467c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
24477c478bd9Sstevel@tonic-gate 			return (FALSE);
24487c478bd9Sstevel@tonic-gate 
24497c478bd9Sstevel@tonic-gate 		/*
24507c478bd9Sstevel@tonic-gate 		 * filename3 name
24517c478bd9Sstevel@tonic-gate 		 */
24527c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
24537c478bd9Sstevel@tonic-gate 			return (FALSE);
24547c478bd9Sstevel@tonic-gate 		this_reclen = DIRENT64_RECLEN(namlen);
24557c478bd9Sstevel@tonic-gate 
24567c478bd9Sstevel@tonic-gate 		/*
24577c478bd9Sstevel@tonic-gate 		 * If this will overflow buffer, stop decoding
24587c478bd9Sstevel@tonic-gate 		 */
24597c478bd9Sstevel@tonic-gate 		if ((outcount + this_reclen) > entries_size) {
24607c478bd9Sstevel@tonic-gate 			objp->eof = FALSE;
24617c478bd9Sstevel@tonic-gate 			break;
24627c478bd9Sstevel@tonic-gate 		}
24637c478bd9Sstevel@tonic-gate 		dp->d_reclen = this_reclen;
24647c478bd9Sstevel@tonic-gate 		dp->d_ino = fileid;
24657c478bd9Sstevel@tonic-gate 
24667c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, dp->d_name, namlen))
24677c478bd9Sstevel@tonic-gate 			return (FALSE);
24687c478bd9Sstevel@tonic-gate 		bzero(&dp->d_name[namlen],
24697c478bd9Sstevel@tonic-gate 		    DIRENT64_NAMELEN(this_reclen) - namlen);
24707c478bd9Sstevel@tonic-gate 
24717c478bd9Sstevel@tonic-gate 		/*
24727c478bd9Sstevel@tonic-gate 		 * cookie3 cookie
24737c478bd9Sstevel@tonic-gate 		 */
24747c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
24757c478bd9Sstevel@tonic-gate 			return (FALSE);
24767c478bd9Sstevel@tonic-gate 		objp->loff = dp->d_off;
24777c478bd9Sstevel@tonic-gate 
24787c478bd9Sstevel@tonic-gate 		/*
24797c478bd9Sstevel@tonic-gate 		 * post_op_attr name_attributes
24807c478bd9Sstevel@tonic-gate 		 */
24817c478bd9Sstevel@tonic-gate 		if (!xdr_post_op_vattr(xdrs, &pov))
24827c478bd9Sstevel@tonic-gate 			return (FALSE);
24837c478bd9Sstevel@tonic-gate 
24847c478bd9Sstevel@tonic-gate 		if (pov.attributes == TRUE &&
24850a701b1eSRobert Gordon 		    pov.fres.status == NFS3_OK)
24867c478bd9Sstevel@tonic-gate 			va_valid = TRUE;
24877c478bd9Sstevel@tonic-gate 		else
24887c478bd9Sstevel@tonic-gate 			va_valid = FALSE;
24897c478bd9Sstevel@tonic-gate 
24907c478bd9Sstevel@tonic-gate 		/*
24917c478bd9Sstevel@tonic-gate 		 * post_op_fh3 name_handle
24927c478bd9Sstevel@tonic-gate 		 */
24937c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&fh_valid))
24947c478bd9Sstevel@tonic-gate 			return (FALSE);
24957c478bd9Sstevel@tonic-gate 
24967c478bd9Sstevel@tonic-gate 		/*
24977c478bd9Sstevel@tonic-gate 		 * By definition of the standard fh_valid can be 0 (FALSE) or
24987c478bd9Sstevel@tonic-gate 		 * 1 (TRUE), but we have to account for it being anything else
24997c478bd9Sstevel@tonic-gate 		 * in case some other system didn't follow the standard.  Note
25007c478bd9Sstevel@tonic-gate 		 * that this is why the else checks if the fh_valid variable
25017c478bd9Sstevel@tonic-gate 		 * is != FALSE.
25027c478bd9Sstevel@tonic-gate 		 */
25037c478bd9Sstevel@tonic-gate 		if (fh_valid == TRUE) {
25047c478bd9Sstevel@tonic-gate 			if (!xdr_nfs_fh3(xdrs, &fh))
25057c478bd9Sstevel@tonic-gate 				return (FALSE);
25067c478bd9Sstevel@tonic-gate 		} else {
25077c478bd9Sstevel@tonic-gate 			if (fh_valid != FALSE)
25087c478bd9Sstevel@tonic-gate 				return (FALSE);
25097c478bd9Sstevel@tonic-gate 		}
25107c478bd9Sstevel@tonic-gate 
25117c478bd9Sstevel@tonic-gate 		/*
25127c478bd9Sstevel@tonic-gate 		 * If the name is "." or there are no attributes,
25137c478bd9Sstevel@tonic-gate 		 * don't polute the DNLC with "." entries or files
25147c478bd9Sstevel@tonic-gate 		 * we cannot determine the type for.
25157c478bd9Sstevel@tonic-gate 		 */
25167c478bd9Sstevel@tonic-gate 		if (!(namlen == 1 && dp->d_name[0] == '.') &&
25170a701b1eSRobert Gordon 		    va_valid && fh_valid) {
25187c478bd9Sstevel@tonic-gate 
25197c478bd9Sstevel@tonic-gate 			/*
25207c478bd9Sstevel@tonic-gate 			 * Do the DNLC caching
25217c478bd9Sstevel@tonic-gate 			 */
25227c478bd9Sstevel@tonic-gate 			nvp = makenfs3node_va(&fh, &va, dvp->v_vfsp,
25230a701b1eSRobert Gordon 			    objp->time, objp->credentials,
25240a701b1eSRobert Gordon 			    rp->r_path, dp->d_name);
25257c478bd9Sstevel@tonic-gate 			dnlc_update(dvp, dp->d_name, nvp);
25267c478bd9Sstevel@tonic-gate 			VN_RELE(nvp);
25277c478bd9Sstevel@tonic-gate 		}
25287c478bd9Sstevel@tonic-gate 
25297c478bd9Sstevel@tonic-gate 		outcount += this_reclen;
25307c478bd9Sstevel@tonic-gate 		dp = (dirent64_t *)((intptr_t)dp + this_reclen);
25317c478bd9Sstevel@tonic-gate 	}
25327c478bd9Sstevel@tonic-gate 
25337c478bd9Sstevel@tonic-gate 	objp->size = outcount;
25347c478bd9Sstevel@tonic-gate 	return (TRUE);
25357c478bd9Sstevel@tonic-gate }
25367c478bd9Sstevel@tonic-gate 
25377c478bd9Sstevel@tonic-gate bool_t
xdr_FSSTAT3res(XDR * xdrs,FSSTAT3res * objp)25387c478bd9Sstevel@tonic-gate xdr_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp)
25397c478bd9Sstevel@tonic-gate {
25407c478bd9Sstevel@tonic-gate 	FSSTAT3resok *resokp;
25417c478bd9Sstevel@tonic-gate 
25427c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
25437c478bd9Sstevel@tonic-gate 		return (FALSE);
25447c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
25457c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
25467c478bd9Sstevel@tonic-gate 
25477c478bd9Sstevel@tonic-gate 	/* xdr_FSSTAT3resok */
25487c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
25497c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
25507c478bd9Sstevel@tonic-gate 		return (FALSE);
25517c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->tbytes))
25527c478bd9Sstevel@tonic-gate 		return (FALSE);
25537c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->fbytes))
25547c478bd9Sstevel@tonic-gate 		return (FALSE);
25557c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->abytes))
25567c478bd9Sstevel@tonic-gate 		return (FALSE);
25577c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->tfiles))
25587c478bd9Sstevel@tonic-gate 		return (FALSE);
25597c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->ffiles))
25607c478bd9Sstevel@tonic-gate 		return (FALSE);
25617c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->afiles))
25627c478bd9Sstevel@tonic-gate 		return (FALSE);
25637c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &resokp->invarsec));
25647c478bd9Sstevel@tonic-gate }
25657c478bd9Sstevel@tonic-gate 
25667c478bd9Sstevel@tonic-gate bool_t
xdr_FSINFO3res(XDR * xdrs,FSINFO3res * objp)25677c478bd9Sstevel@tonic-gate xdr_FSINFO3res(XDR *xdrs, FSINFO3res *objp)
25687c478bd9Sstevel@tonic-gate {
25697c478bd9Sstevel@tonic-gate 	FSINFO3resok *resokp;
25707c478bd9Sstevel@tonic-gate 
25717c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
25727c478bd9Sstevel@tonic-gate 		return (FALSE);
25737c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK) /* xdr_FSSTAT3resfail */
25747c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
25757c478bd9Sstevel@tonic-gate 
25767c478bd9Sstevel@tonic-gate 	/* xdr_FSINFO3resok */
25777c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
25787c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
25797c478bd9Sstevel@tonic-gate 		return (FALSE);
25807c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->rtmax))
25817c478bd9Sstevel@tonic-gate 		return (FALSE);
25827c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->rtpref))
25837c478bd9Sstevel@tonic-gate 		return (FALSE);
25847c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->rtmult))
25857c478bd9Sstevel@tonic-gate 		return (FALSE);
25867c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->wtmax))
25877c478bd9Sstevel@tonic-gate 		return (FALSE);
25887c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->wtpref))
25897c478bd9Sstevel@tonic-gate 		return (FALSE);
25907c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->wtmult))
25917c478bd9Sstevel@tonic-gate 		return (FALSE);
25927c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->dtpref))
25937c478bd9Sstevel@tonic-gate 		return (FALSE);
25947c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &resokp->maxfilesize))
25957c478bd9Sstevel@tonic-gate 		return (FALSE);
25967c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->time_delta.seconds))
25977c478bd9Sstevel@tonic-gate 		return (FALSE);
25987c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->time_delta.nseconds))
25997c478bd9Sstevel@tonic-gate 		return (FALSE);
26007c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &resokp->properties));
26017c478bd9Sstevel@tonic-gate }
26027c478bd9Sstevel@tonic-gate 
26037c478bd9Sstevel@tonic-gate bool_t
xdr_PATHCONF3res(XDR * xdrs,PATHCONF3res * objp)26047c478bd9Sstevel@tonic-gate xdr_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp)
26057c478bd9Sstevel@tonic-gate {
26067c478bd9Sstevel@tonic-gate 	PATHCONF3resok *resokp;
26077c478bd9Sstevel@tonic-gate 
26087c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
26097c478bd9Sstevel@tonic-gate 		return (FALSE);
26107c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
26117c478bd9Sstevel@tonic-gate 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
26127c478bd9Sstevel@tonic-gate 
26137c478bd9Sstevel@tonic-gate 	/* xdr_PATHCONF3resok */
26147c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
26157c478bd9Sstevel@tonic-gate 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
26167c478bd9Sstevel@tonic-gate 		return (FALSE);
26177c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->info.link_max))
26187c478bd9Sstevel@tonic-gate 		return (FALSE);
26197c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &resokp->info.name_max))
26207c478bd9Sstevel@tonic-gate 		return (FALSE);
26217c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &resokp->info.no_trunc))
26227c478bd9Sstevel@tonic-gate 		return (FALSE);
26237c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &resokp->info.chown_restricted))
26247c478bd9Sstevel@tonic-gate 		return (FALSE);
26257c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &resokp->info.case_insensitive))
26267c478bd9Sstevel@tonic-gate 		return (FALSE);
26277c478bd9Sstevel@tonic-gate 	return (xdr_bool(xdrs, &resokp->info.case_preserving));
26287c478bd9Sstevel@tonic-gate }
26297c478bd9Sstevel@tonic-gate 
26307c478bd9Sstevel@tonic-gate bool_t
xdr_COMMIT3args(XDR * xdrs,COMMIT3args * objp)26317c478bd9Sstevel@tonic-gate xdr_COMMIT3args(XDR *xdrs, COMMIT3args *objp)
26327c478bd9Sstevel@tonic-gate {
26337c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
26347c478bd9Sstevel@tonic-gate 		return (TRUE);
26357c478bd9Sstevel@tonic-gate 
263627242a7cSthurlow 	switch (xdrs->x_op) {
263727242a7cSthurlow 	case XDR_FREE:
263827242a7cSthurlow 	case XDR_ENCODE:
263927242a7cSthurlow 		if (!xdr_nfs_fh3(xdrs, &objp->file))
264027242a7cSthurlow 			return (FALSE);
264127242a7cSthurlow 		break;
264227242a7cSthurlow 	case XDR_DECODE:
264327242a7cSthurlow 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
264427242a7cSthurlow 			return (FALSE);
264527242a7cSthurlow 		break;
26467c478bd9Sstevel@tonic-gate 	}
26477c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, &objp->offset))
26487c478bd9Sstevel@tonic-gate 		return (FALSE);
26497c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->count));
26507c478bd9Sstevel@tonic-gate }
26517c478bd9Sstevel@tonic-gate 
26527c478bd9Sstevel@tonic-gate bool_t
xdr_COMMIT3res(XDR * xdrs,COMMIT3res * objp)26537c478bd9Sstevel@tonic-gate xdr_COMMIT3res(XDR *xdrs, COMMIT3res *objp)
26547c478bd9Sstevel@tonic-gate {
26557c478bd9Sstevel@tonic-gate 	COMMIT3resok *resokp;
26567c478bd9Sstevel@tonic-gate 
26577c478bd9Sstevel@tonic-gate 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
26587c478bd9Sstevel@tonic-gate 		return (FALSE);
26597c478bd9Sstevel@tonic-gate 	if (objp->status != NFS3_OK)
26607c478bd9Sstevel@tonic-gate 		return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
26617c478bd9Sstevel@tonic-gate 
26627c478bd9Sstevel@tonic-gate 	/* xdr_COMMIT3resok */
26637c478bd9Sstevel@tonic-gate 	resokp = &objp->resok;
26647c478bd9Sstevel@tonic-gate 	if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
26657c478bd9Sstevel@tonic-gate 		return (FALSE);
26667c478bd9Sstevel@tonic-gate 	/*
26677c478bd9Sstevel@tonic-gate 	 * writeverf3 is really an opaque 8 byte
26687c478bd9Sstevel@tonic-gate 	 * quantity, but we will treat it as a
26697c478bd9Sstevel@tonic-gate 	 * hyper for efficiency, the cost of
26707c478bd9Sstevel@tonic-gate 	 * a byteswap here saves bcopys elsewhere
26717c478bd9Sstevel@tonic-gate 	 */
26727c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, &resokp->verf));
26737c478bd9Sstevel@tonic-gate }
2674