xref: /illumos-gate/usr/src/uts/common/fs/nfs/nfs4_xdr.c (revision 0a701b1e)
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 /*
22*0a701b1eSRobert Gordon  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*0a701b1eSRobert Gordon  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
26*0a701b1eSRobert Gordon #pragma ident	"@(#)nfs4_xdr.c	1.27	08/08/11 SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * A handcoded version based on the original rpcgen code.
307c478bd9Sstevel@tonic-gate  *
317c478bd9Sstevel@tonic-gate  * Note: All future NFS4 protocol changes should be added by hand
327c478bd9Sstevel@tonic-gate  * to this file.
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  * CAUTION: All protocol changes must also be propagated to:
357c478bd9Sstevel@tonic-gate  *     usr/src/cmd/cmd-inet/usr.sbin/snoop/nfs4_xdr.c
367c478bd9Sstevel@tonic-gate  */
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #include <sys/types.h>
397c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
407c478bd9Sstevel@tonic-gate #include <sys/dnlc.h>
417c478bd9Sstevel@tonic-gate #include <nfs/nfs.h>
427c478bd9Sstevel@tonic-gate #include <nfs/nfs4_kprot.h>
437c478bd9Sstevel@tonic-gate #include <nfs/rnode4.h>
447c478bd9Sstevel@tonic-gate #include <nfs/nfs4.h>
457c478bd9Sstevel@tonic-gate #include <nfs/nfs4_clnt.h>
467c478bd9Sstevel@tonic-gate #include <sys/sdt.h>
477c478bd9Sstevel@tonic-gate #include <rpc/rpc_rdma.h>
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate bool_t
507c478bd9Sstevel@tonic-gate xdr_bitmap4(XDR *xdrs, bitmap4 *objp)
517c478bd9Sstevel@tonic-gate {
527c478bd9Sstevel@tonic-gate 	int32_t len, size;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
557c478bd9Sstevel@tonic-gate 		return (TRUE);
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate 	/*
587c478bd9Sstevel@tonic-gate 	 * Simplified bitmap4 processing, always encode from uint64_t
597c478bd9Sstevel@tonic-gate 	 * to 2 uint32_t's, always decode first 2 uint32_t's into a
607c478bd9Sstevel@tonic-gate 	 * uint64_t and ignore all of the rest.
617c478bd9Sstevel@tonic-gate 	 */
627c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
637c478bd9Sstevel@tonic-gate 		len = 2;
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len))
667c478bd9Sstevel@tonic-gate 			return (FALSE);
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
697c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
70*0a701b1eSRobert Gordon 		    BYTES_PER_XDR_UNIT)) == TRUE) {
717c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)objp));
727c478bd9Sstevel@tonic-gate 		}
737c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
747c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)objp) == TRUE) {
757c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
76*0a701b1eSRobert Gordon 			    BYTES_PER_XDR_UNIT)));
777c478bd9Sstevel@tonic-gate 		}
787c478bd9Sstevel@tonic-gate #endif
797c478bd9Sstevel@tonic-gate 		return (FALSE);
807c478bd9Sstevel@tonic-gate 	}
817c478bd9Sstevel@tonic-gate 
827c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, &len))
837c478bd9Sstevel@tonic-gate 		return (FALSE);
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	/*
867c478bd9Sstevel@tonic-gate 	 * Common fast DECODE cases
877c478bd9Sstevel@tonic-gate 	 */
887c478bd9Sstevel@tonic-gate 	if (len == 2) {
897c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
907c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
91*0a701b1eSRobert Gordon 		    BYTES_PER_XDR_UNIT)) == TRUE) {
927c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)objp));
937c478bd9Sstevel@tonic-gate 		}
947c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
957c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)objp) == TRUE) {
967c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
97*0a701b1eSRobert Gordon 			    BYTES_PER_XDR_UNIT)));
987c478bd9Sstevel@tonic-gate 		}
997c478bd9Sstevel@tonic-gate #endif
1007c478bd9Sstevel@tonic-gate 		return (FALSE);
1017c478bd9Sstevel@tonic-gate 	}
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	*objp = 0;
1047c478bd9Sstevel@tonic-gate 	if (len == 0)
1057c478bd9Sstevel@tonic-gate 		return (TRUE);
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 	/*
1087c478bd9Sstevel@tonic-gate 	 * The not so common DECODE cases, len == 1 || len > 2
1097c478bd9Sstevel@tonic-gate 	 */
1107c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
1117c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
1127c478bd9Sstevel@tonic-gate 		return (FALSE);
1137c478bd9Sstevel@tonic-gate 	if (--len == 0)
1147c478bd9Sstevel@tonic-gate 		return (TRUE);
1157c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
1167c478bd9Sstevel@tonic-gate 		return (FALSE);
1177c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
1187c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
1197c478bd9Sstevel@tonic-gate 		return (FALSE);
1207c478bd9Sstevel@tonic-gate 	if (--len == 0)
1217c478bd9Sstevel@tonic-gate 		return (TRUE);
1227c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
1237c478bd9Sstevel@tonic-gate 		return (FALSE);
1247c478bd9Sstevel@tonic-gate #else
1257c478bd9Sstevel@tonic-gate 	return (FALSE);
1267c478bd9Sstevel@tonic-gate #endif
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	if (--len == 0)
1297c478bd9Sstevel@tonic-gate 		return (TRUE);
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	size = len * BYTES_PER_XDR_UNIT;
1327c478bd9Sstevel@tonic-gate 	return (XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size));
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate /* Called by xdr_array, nfsid_map_xdr */
1367c478bd9Sstevel@tonic-gate bool_t
1377c478bd9Sstevel@tonic-gate xdr_utf8string(XDR *xdrs, utf8string *objp)
1387c478bd9Sstevel@tonic-gate {
1397c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE)
1407c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->utf8string_val,
141*0a701b1eSRobert Gordon 		    (uint_t *)&objp->utf8string_len, NFS4_MAX_UTF8STRING));
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	if (objp->utf8string_val != NULL) {
1447c478bd9Sstevel@tonic-gate 		kmem_free(objp->utf8string_val, objp->utf8string_len);
1457c478bd9Sstevel@tonic-gate 		objp->utf8string_val = NULL;
1467c478bd9Sstevel@tonic-gate 	}
1477c478bd9Sstevel@tonic-gate 	return (TRUE);
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate /*
151eac3aab7Srobinson  * XDR_INLINE decode a filehandle.
1527c46fb7fSek  */
1537c46fb7fSek bool_t
154eac3aab7Srobinson xdr_inline_decode_nfs_fh4(uint32_t *ptr, nfs_fh4_fmt_t *fhp, uint32_t fhsize)
1557c46fb7fSek {
156eac3aab7Srobinson 	uchar_t *bp = (uchar_t *)ptr;
1574f85d229Srobinson 	uchar_t *cp;
158eac3aab7Srobinson 	uint32_t dsize;
159eac3aab7Srobinson 	uintptr_t resid;
1604f85d229Srobinson 
1617c46fb7fSek 	/*
162eac3aab7Srobinson 	 * Check to see if what the client sent us is bigger or smaller
163eac3aab7Srobinson 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
164eac3aab7Srobinson 	 * unfortunately badly named as it is no longer the max and is
165eac3aab7Srobinson 	 * really the min of what is sent over the wire.
1667c46fb7fSek 	 */
167eac3aab7Srobinson 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
168eac3aab7Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA +
169eac3aab7Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
170eac3aab7Srobinson 		return (FALSE);
171eac3aab7Srobinson 	}
1724f85d229Srobinson 
1737c46fb7fSek 	/*
174eac3aab7Srobinson 	 * All internal parts of a filehandle are in native byte order.
175eac3aab7Srobinson 	 *
176eac3aab7Srobinson 	 * Decode what should be fh4_fsid, it is aligned.
1777c46fb7fSek 	 */
178eac3aab7Srobinson 	fhp->fh4_fsid.val[0] = *(uint32_t *)bp;
179eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
180eac3aab7Srobinson 	fhp->fh4_fsid.val[1] = *(uint32_t *)bp;
181eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
1827c46fb7fSek 
1837c46fb7fSek 	/*
184eac3aab7Srobinson 	 * Decode what should be fh4_len.  fh4_len is two bytes, so we're
185eac3aab7Srobinson 	 * unaligned now.
1867c46fb7fSek 	 */
187eac3aab7Srobinson 	cp = (uchar_t *)&fhp->fh4_len;
188eac3aab7Srobinson 	*cp++ = *bp++;
189eac3aab7Srobinson 	*cp++ = *bp++;
190eac3aab7Srobinson 	fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
1917c46fb7fSek 
1927c46fb7fSek 	/*
193da6c28aaSamw 	 * For backwards compatibility, the fid length may be less than
194eac3aab7Srobinson 	 * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
1957c46fb7fSek 	 */
196eac3aab7Srobinson 	dsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
1977c46fb7fSek 
1987c46fb7fSek 	/*
199eac3aab7Srobinson 	 * Make sure the client isn't sending us a bogus length for fh4_data.
2007c46fb7fSek 	 */
201eac3aab7Srobinson 	if (fhsize < dsize)
202eac3aab7Srobinson 		return (FALSE);
203eac3aab7Srobinson 	bcopy(bp, fhp->fh4_data, dsize);
204eac3aab7Srobinson 	bp += dsize;
205eac3aab7Srobinson 	fhsize -= dsize;
2067c46fb7fSek 
207eac3aab7Srobinson 	if (fhsize < sizeof (ushort_t))
208eac3aab7Srobinson 		return (FALSE);
209eac3aab7Srobinson 	cp = (uchar_t *)&fhp->fh4_xlen;
210eac3aab7Srobinson 	*cp++ = *bp++;
211eac3aab7Srobinson 	*cp++ = *bp++;
212eac3aab7Srobinson 	fhsize -= sizeof (ushort_t);
213eac3aab7Srobinson 
214eac3aab7Srobinson 	dsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
2157c46fb7fSek 
2167c46fb7fSek 	/*
217eac3aab7Srobinson 	 * Make sure the client isn't sending us a bogus length for fh4_xdata.
2187c46fb7fSek 	 */
219eac3aab7Srobinson 	if (fhsize < dsize)
220eac3aab7Srobinson 		return (FALSE);
221eac3aab7Srobinson 	bcopy(bp, fhp->fh4_xdata, dsize);
222eac3aab7Srobinson 	fhsize -= dsize;
223eac3aab7Srobinson 	bp += dsize;
2247c46fb7fSek 
2257c46fb7fSek 	/*
226eac3aab7Srobinson 	 * We realign things on purpose, so skip any padding
2277c46fb7fSek 	 */
228eac3aab7Srobinson 	resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
229eac3aab7Srobinson 	if (resid != 0) {
230eac3aab7Srobinson 		if (fhsize < (BYTES_PER_XDR_UNIT - resid))
231eac3aab7Srobinson 			return (FALSE);
232eac3aab7Srobinson 		bp += BYTES_PER_XDR_UNIT - resid;
233eac3aab7Srobinson 		fhsize -= BYTES_PER_XDR_UNIT - resid;
234eac3aab7Srobinson 	}
2357c46fb7fSek 
236eac3aab7Srobinson 	if (fhsize < BYTES_PER_XDR_UNIT)
237eac3aab7Srobinson 		return (FALSE);
238eac3aab7Srobinson 	fhp->fh4_flag = *(uint32_t *)bp;
239eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
240eac3aab7Srobinson 	fhsize -= BYTES_PER_XDR_UNIT;
2417c46fb7fSek 
2427c46fb7fSek #ifdef VOLATILE_FH_TEST
243eac3aab7Srobinson 	if (fhsize < BYTES_PER_XDR_UNIT)
244eac3aab7Srobinson 		return (FALSE);
245eac3aab7Srobinson 	fhp->fh4_volatile_id = *(uint32_t *)bp;
246eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
247eac3aab7Srobinson 	fhsize -= BYTES_PER_XDR_UNIT;
2487c46fb7fSek #endif
249eac3aab7Srobinson 	/*
250eac3aab7Srobinson 	 * Make sure client didn't send extra bytes
251eac3aab7Srobinson 	 */
252eac3aab7Srobinson 	if (fhsize != 0)
253eac3aab7Srobinson 		return (FALSE);
2547c46fb7fSek 	return (TRUE);
2557c46fb7fSek }
2567c46fb7fSek 
2577c46fb7fSek static bool_t
2587c46fb7fSek xdr_decode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
2597c46fb7fSek {
2607c46fb7fSek 	uint32_t fhsize;		/* filehandle size */
2614f85d229Srobinson 	uint32_t bufsize;
2624f85d229Srobinson 	rpc_inline_t *ptr;
26327242a7cSthurlow 	uchar_t *bp;
2647c46fb7fSek 
2657c46fb7fSek 	ASSERT(xdrs->x_op == XDR_DECODE);
2667c46fb7fSek 
2677c46fb7fSek 	/*
2687c46fb7fSek 	 * Retrieve the filehandle length.
2697c46fb7fSek 	 */
2707c46fb7fSek 	if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
2717c46fb7fSek 		return (FALSE);
2727c46fb7fSek 
2734f85d229Srobinson 	objp->nfs_fh4_val = NULL;
2744f85d229Srobinson 	objp->nfs_fh4_len = 0;
2754f85d229Srobinson 
2767c46fb7fSek 	/*
2774f85d229Srobinson 	 * Check to see if what the client sent us is bigger or smaller
2784f85d229Srobinson 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
2794f85d229Srobinson 	 * unfortunately badly named as it is no longer the max and is
2804f85d229Srobinson 	 * really the min of what is sent over the wire.
2817c46fb7fSek 	 */
2824f85d229Srobinson 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
2834f85d229Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA +
2844f85d229Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
2854f85d229Srobinson 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
2864f85d229Srobinson 			return (FALSE);
2874f85d229Srobinson 		return (TRUE);
2884f85d229Srobinson 	}
2897c46fb7fSek 
2904f85d229Srobinson 	/*
2914f85d229Srobinson 	 * bring in fhsize plus any padding
2924f85d229Srobinson 	 */
2934f85d229Srobinson 	bufsize = RNDUP(fhsize);
2944f85d229Srobinson 	ptr = XDR_INLINE(xdrs, bufsize);
295eac3aab7Srobinson 	bp = (uchar_t *)ptr;
2964f85d229Srobinson 	if (ptr == NULL) {
29727242a7cSthurlow 		bp = kmem_alloc(bufsize, KM_SLEEP);
29827242a7cSthurlow 		if (!xdr_opaque(xdrs, (char *)bp, bufsize)) {
29927242a7cSthurlow 			kmem_free(bp, bufsize);
3004f85d229Srobinson 			return (FALSE);
30127242a7cSthurlow 		}
3024f85d229Srobinson 	}
3037c46fb7fSek 
3047c46fb7fSek 	objp->nfs_fh4_val = kmem_zalloc(sizeof (nfs_fh4_fmt_t), KM_SLEEP);
3057c46fb7fSek 	objp->nfs_fh4_len = sizeof (nfs_fh4_fmt_t);
306eac3aab7Srobinson 
307eac3aab7Srobinson 	if (xdr_inline_decode_nfs_fh4((uint32_t *)bp,
308eac3aab7Srobinson 	    (nfs_fh4_fmt_t *)objp->nfs_fh4_val, fhsize) == FALSE) {
309eac3aab7Srobinson 		/*
310eac3aab7Srobinson 		 * If in the process of decoding we find the file handle
311eac3aab7Srobinson 		 * is not correctly formed, we need to continue decoding
312eac3aab7Srobinson 		 * and trigger an NFS layer error. Set the nfs_fh4_len to
313eac3aab7Srobinson 		 * zero so it gets caught as a bad length.
314eac3aab7Srobinson 		 */
315eac3aab7Srobinson 		kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
316eac3aab7Srobinson 		objp->nfs_fh4_val = NULL;
317eac3aab7Srobinson 		objp->nfs_fh4_len = 0;
318eac3aab7Srobinson 	}
319eac3aab7Srobinson 
320eac3aab7Srobinson 	if (ptr == NULL)
32127242a7cSthurlow 		kmem_free(bp, bufsize);
322eac3aab7Srobinson 	return (TRUE);
323eac3aab7Srobinson }
324eac3aab7Srobinson 
325eac3aab7Srobinson /*
326eac3aab7Srobinson  * XDR_INLINE encode a filehandle.
327eac3aab7Srobinson  */
328eac3aab7Srobinson bool_t
329eac3aab7Srobinson xdr_inline_encode_nfs_fh4(uint32_t **ptrp, uint32_t *ptr_redzone,
330eac3aab7Srobinson 	nfs_fh4_fmt_t *fhp)
331eac3aab7Srobinson {
332eac3aab7Srobinson 	uint32_t *ptr = *ptrp;
333eac3aab7Srobinson 	uchar_t *cp;
334eac3aab7Srobinson 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
335eac3aab7Srobinson 	uint32_t padword;
336eac3aab7Srobinson 
337eac3aab7Srobinson 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
338eac3aab7Srobinson 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
3397c46fb7fSek 
3407c46fb7fSek 	/*
341eac3aab7Srobinson 	 * First get the initial and variable sized part of the filehandle.
3427c46fb7fSek 	 */
343eac3aab7Srobinson 	otw_len = sizeof (fhp->fh4_fsid) +
344eac3aab7Srobinson 	    sizeof (fhp->fh4_len) + fsize +
345eac3aab7Srobinson 	    sizeof (fhp->fh4_xlen) + xsize;
3467c46fb7fSek 
3477c46fb7fSek 	/*
348eac3aab7Srobinson 	 * Round out to a full word.
3497c46fb7fSek 	 */
350eac3aab7Srobinson 	otw_len = RNDUP(otw_len);
351eac3aab7Srobinson 	padword = (otw_len / BYTES_PER_XDR_UNIT);	/* includes fhlen */
3527c46fb7fSek 
3537c46fb7fSek 	/*
354eac3aab7Srobinson 	 * Add in the fixed sized pieces.
3557c46fb7fSek 	 */
356eac3aab7Srobinson 	otw_len += sizeof (fhp->fh4_flag);
357eac3aab7Srobinson #ifdef VOLATILE_FH_TEST
358eac3aab7Srobinson 	otw_len += sizeof (fhp->fh4_volatile_id);
359eac3aab7Srobinson #endif
3607c46fb7fSek 
3614f85d229Srobinson 	/*
362eac3aab7Srobinson 	 * Make sure we don't exceed our buffer.
3634f85d229Srobinson 	 */
364eac3aab7Srobinson 	if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone)
365eac3aab7Srobinson 		return (FALSE);
3667c46fb7fSek 
3677c46fb7fSek 	/*
36827242a7cSthurlow 	 * Zero out the padding.
3697c46fb7fSek 	 */
370eac3aab7Srobinson 	ptr[padword] = 0;
3717c46fb7fSek 
37227242a7cSthurlow 	IXDR_PUT_U_INT32(ptr, otw_len);
37327242a7cSthurlow 
3744f85d229Srobinson 	/*
375eac3aab7Srobinson 	 * The rest of the filehandle is in native byteorder
3764f85d229Srobinson 	 */
377eac3aab7Srobinson 	/* fh4_fsid */
378eac3aab7Srobinson 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[0];
379eac3aab7Srobinson 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[1];
3807c46fb7fSek 
3817c46fb7fSek 	/*
382eac3aab7Srobinson 	 * Since the next pieces are unaligned, we need to
383eac3aab7Srobinson 	 * do bytewise copies.
3847c46fb7fSek 	 */
385eac3aab7Srobinson 	cp = (uchar_t *)ptr;
3867c46fb7fSek 
387eac3aab7Srobinson 	/* fh4_len + fh4_data */
388eac3aab7Srobinson 	bcopy(&fhp->fh4_len, cp, sizeof (fhp->fh4_len) + fsize);
389eac3aab7Srobinson 	cp += sizeof (fhp->fh4_len) + fsize;
390eac3aab7Srobinson 
391eac3aab7Srobinson 	/* fh4_xlen + fh4_xdata */
392eac3aab7Srobinson 	bcopy(&fhp->fh4_xlen, cp, sizeof (fhp->fh4_xlen) + xsize);
393eac3aab7Srobinson 	cp += sizeof (fhp->fh4_xlen) + xsize;
394eac3aab7Srobinson 
395eac3aab7Srobinson 	/* do necessary rounding/padding */
396eac3aab7Srobinson 	cp = (uchar_t *)RNDUP((uintptr_t)cp);
397eac3aab7Srobinson 	ptr = (uint32_t *)cp;
3987c46fb7fSek 
3994f85d229Srobinson 	/*
400eac3aab7Srobinson 	 * With the above padding, we're word aligned again.
4014f85d229Srobinson 	 */
402eac3aab7Srobinson 	ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0);
403eac3aab7Srobinson 
404eac3aab7Srobinson 	/* fh4_flag */
405eac3aab7Srobinson 	*ptr++ = (uint32_t)fhp->fh4_flag;
406eac3aab7Srobinson 
407eac3aab7Srobinson #ifdef VOLATILE_FH_TEST
408eac3aab7Srobinson 	/* fh4_volatile_id */
409eac3aab7Srobinson 	*ptr++ = (uint32_t)fhp->fh4_volatile_id;
410eac3aab7Srobinson #endif
411eac3aab7Srobinson 	*ptrp = ptr;
412eac3aab7Srobinson 
4137c46fb7fSek 	return (TRUE);
4147c46fb7fSek }
4157c46fb7fSek 
4167c46fb7fSek static bool_t
4177c46fb7fSek xdr_encode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
4187c46fb7fSek {
4194f85d229Srobinson 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
4204f85d229Srobinson 	bool_t ret;
4214f85d229Srobinson 	rpc_inline_t *ptr;
4224f85d229Srobinson 	rpc_inline_t *buf = NULL;
4234f85d229Srobinson 	uint32_t *ptr_redzone;
4244f85d229Srobinson 	nfs_fh4_fmt_t *fhp;
4257c46fb7fSek 
4267c46fb7fSek 	ASSERT(xdrs->x_op == XDR_ENCODE);
4277c46fb7fSek 
4284f85d229Srobinson 	fhp = (nfs_fh4_fmt_t *)objp->nfs_fh4_val;
4294f85d229Srobinson 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
4304f85d229Srobinson 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
4317c46fb7fSek 
4324f85d229Srobinson 	/*
4334f85d229Srobinson 	 * First get the over the wire size, it is the 4 bytes
4344f85d229Srobinson 	 * for the length, plus the combined size of the
4354f85d229Srobinson 	 * file handle components.
4364f85d229Srobinson 	 */
4374f85d229Srobinson 	otw_len = BYTES_PER_XDR_UNIT + sizeof (fhp->fh4_fsid) +
4384f85d229Srobinson 	    sizeof (fhp->fh4_len) + fsize +
4394f85d229Srobinson 	    sizeof (fhp->fh4_xlen) + xsize +
4404f85d229Srobinson 	    sizeof (fhp->fh4_flag);
4417c46fb7fSek #ifdef VOLATILE_FH_TEST
4424f85d229Srobinson 	otw_len += sizeof (fhp->fh4_volatile_id);
4437c46fb7fSek #endif
4447c46fb7fSek 	/*
4454f85d229Srobinson 	 * Round out to a full word.
4467c46fb7fSek 	 */
4474f85d229Srobinson 	otw_len = RNDUP(otw_len);
4487c46fb7fSek 
4497c46fb7fSek 	/*
4504f85d229Srobinson 	 * Next try to inline the XDR stream, if that fails (rare)
4514f85d229Srobinson 	 * allocate a buffer to encode the file handle and then
4524f85d229Srobinson 	 * copy it using xdr_opaque and free the buffer.
4537c46fb7fSek 	 */
4544f85d229Srobinson 	ptr = XDR_INLINE(xdrs, otw_len);
4554f85d229Srobinson 	if (ptr == NULL)
4564f85d229Srobinson 		ptr = buf = kmem_alloc(otw_len, KM_SLEEP);
4577c46fb7fSek 
4584f85d229Srobinson 	ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT));
4594f85d229Srobinson 	ret = xdr_inline_encode_nfs_fh4((uint32_t **)&ptr, ptr_redzone, fhp);
4607c46fb7fSek 
4614f85d229Srobinson 	if (buf != NULL) {
4624f85d229Srobinson 		if (ret == TRUE)
4634f85d229Srobinson 			ret = xdr_opaque(xdrs, (char *)buf, otw_len);
4644f85d229Srobinson 		kmem_free(buf, otw_len);
4654f85d229Srobinson 	}
4664f85d229Srobinson 	return (ret);
4677c46fb7fSek }
4687c46fb7fSek 
4697c46fb7fSek /*
4707c46fb7fSek  * XDR a NFSv4 filehandle.
471eac3aab7Srobinson  * Encoding interprets the contents (server).
472eac3aab7Srobinson  * Decoding the contents are opaque (client).
4737c478bd9Sstevel@tonic-gate  */
4747c478bd9Sstevel@tonic-gate bool_t
4757c478bd9Sstevel@tonic-gate xdr_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
4767c478bd9Sstevel@tonic-gate {
477eac3aab7Srobinson 	switch (xdrs->x_op) {
478eac3aab7Srobinson 	case XDR_ENCODE:
4797c46fb7fSek 		return (xdr_encode_nfs_fh4(xdrs, objp));
480eac3aab7Srobinson 	case XDR_DECODE:
481eac3aab7Srobinson 		return (xdr_bytes(xdrs, (char **)&objp->nfs_fh4_val,
482eac3aab7Srobinson 		    (uint_t *)&objp->nfs_fh4_len, NFS4_FHSIZE));
483eac3aab7Srobinson 	case XDR_FREE:
484eac3aab7Srobinson 		if (objp->nfs_fh4_val != NULL) {
485eac3aab7Srobinson 			kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
486eac3aab7Srobinson 			objp->nfs_fh4_val = NULL;
487eac3aab7Srobinson 		}
488eac3aab7Srobinson 		return (TRUE);
4897c478bd9Sstevel@tonic-gate 	}
490eac3aab7Srobinson 	return (FALSE);
4917c478bd9Sstevel@tonic-gate }
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate /* Called by xdr_array */
4947c478bd9Sstevel@tonic-gate static bool_t
4957c478bd9Sstevel@tonic-gate xdr_fs_location4(XDR *xdrs, fs_location4 *objp)
4967c478bd9Sstevel@tonic-gate {
4977c478bd9Sstevel@tonic-gate 	if (!xdr_array(xdrs, (char **)&objp->server_val,
498*0a701b1eSRobert Gordon 	    (uint_t *)&objp->server_len, NFS4_FS_LOCATIONS_LIMIT,
499*0a701b1eSRobert Gordon 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
5007c478bd9Sstevel@tonic-gate 		return (FALSE);
5017c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->rootpath.pathname4_val,
502*0a701b1eSRobert Gordon 	    (uint_t *)&objp->rootpath.pathname4_len,
503*0a701b1eSRobert Gordon 	    NFS4_MAX_PATHNAME4,
504*0a701b1eSRobert Gordon 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string));
5057c478bd9Sstevel@tonic-gate }
5067c478bd9Sstevel@tonic-gate 
5077c478bd9Sstevel@tonic-gate /* Called by xdr_array */
5087c478bd9Sstevel@tonic-gate static bool_t
5097c478bd9Sstevel@tonic-gate xdr_nfsace4(XDR *xdrs, nfsace4 *objp)
5107c478bd9Sstevel@tonic-gate {
5117c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
5127c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->type))
5137c478bd9Sstevel@tonic-gate 			return (FALSE);
5147c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->flag))
5157c478bd9Sstevel@tonic-gate 			return (FALSE);
5167c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->access_mask))
5177c478bd9Sstevel@tonic-gate 			return (FALSE);
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
5207c478bd9Sstevel@tonic-gate 			objp->who.utf8string_val = NULL;
5217c478bd9Sstevel@tonic-gate 			objp->who.utf8string_len = 0;
5227c478bd9Sstevel@tonic-gate 		}
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->who.utf8string_val,
525*0a701b1eSRobert Gordon 		    (uint_t *)&objp->who.utf8string_len,
526*0a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
5277c478bd9Sstevel@tonic-gate 	}
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate 	/*
5307c478bd9Sstevel@tonic-gate 	 * Optimized free case
5317c478bd9Sstevel@tonic-gate 	 */
5327c478bd9Sstevel@tonic-gate 	if (objp->who.utf8string_val != NULL) {
5337c478bd9Sstevel@tonic-gate 		kmem_free(objp->who.utf8string_val, objp->who.utf8string_len);
5347c478bd9Sstevel@tonic-gate 		objp->who.utf8string_val = NULL;
5357c478bd9Sstevel@tonic-gate 	}
5367c478bd9Sstevel@tonic-gate 	return (TRUE);
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate /*
5407c478bd9Sstevel@tonic-gate  * These functions are called out of nfs4_attr.c
5417c478bd9Sstevel@tonic-gate  */
5427c478bd9Sstevel@tonic-gate bool_t
5437c478bd9Sstevel@tonic-gate xdr_fattr4_fsid(XDR *xdrs, fattr4_fsid *objp)
5447c478bd9Sstevel@tonic-gate {
5457c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
5467c478bd9Sstevel@tonic-gate 		return (TRUE);
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->major))
5497c478bd9Sstevel@tonic-gate 		return (FALSE);
5507c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->minor));
5517c478bd9Sstevel@tonic-gate }
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate bool_t
5557c478bd9Sstevel@tonic-gate xdr_fattr4_acl(XDR *xdrs, fattr4_acl *objp)
5567c478bd9Sstevel@tonic-gate {
5577c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->fattr4_acl_val,
558*0a701b1eSRobert Gordon 	    (uint_t *)&objp->fattr4_acl_len, NFS4_ACL_LIMIT,
559*0a701b1eSRobert Gordon 	    sizeof (nfsace4), (xdrproc_t)xdr_nfsace4));
5607c478bd9Sstevel@tonic-gate }
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate bool_t
5637c478bd9Sstevel@tonic-gate xdr_fattr4_fs_locations(XDR *xdrs, fattr4_fs_locations *objp)
5647c478bd9Sstevel@tonic-gate {
5657c478bd9Sstevel@tonic-gate 	if (!xdr_array(xdrs, (char **)&objp->fs_root.pathname4_val,
566*0a701b1eSRobert Gordon 	    (uint_t *)&objp->fs_root.pathname4_len,
567*0a701b1eSRobert Gordon 	    NFS4_MAX_PATHNAME4,
568*0a701b1eSRobert Gordon 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
5697c478bd9Sstevel@tonic-gate 		return (FALSE);
5707c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->locations_val,
571*0a701b1eSRobert Gordon 	    (uint_t *)&objp->locations_len, NFS4_FS_LOCATIONS_LIMIT,
572*0a701b1eSRobert Gordon 	    sizeof (fs_location4), (xdrproc_t)xdr_fs_location4));
5737c478bd9Sstevel@tonic-gate }
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate bool_t
5767c478bd9Sstevel@tonic-gate xdr_fattr4_rawdev(XDR *xdrs, fattr4_rawdev *objp)
5777c478bd9Sstevel@tonic-gate {
5787c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
5797c478bd9Sstevel@tonic-gate 		return (TRUE);
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->specdata1))
5827c478bd9Sstevel@tonic-gate 		return (FALSE);
5837c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->specdata2));
5847c478bd9Sstevel@tonic-gate }
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate bool_t
5877c478bd9Sstevel@tonic-gate xdr_nfstime4(XDR *xdrs, nfstime4 *objp)
5887c478bd9Sstevel@tonic-gate {
5897c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
5907c478bd9Sstevel@tonic-gate 		return (TRUE);
5917c478bd9Sstevel@tonic-gate 
5927c478bd9Sstevel@tonic-gate 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->seconds))
5937c478bd9Sstevel@tonic-gate 		return (FALSE);
5947c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->nseconds));
5957c478bd9Sstevel@tonic-gate }
5967c478bd9Sstevel@tonic-gate 
5977c478bd9Sstevel@tonic-gate 
5987c478bd9Sstevel@tonic-gate /*
5997c478bd9Sstevel@tonic-gate  * structured used for calls into xdr_ga_fattr_res() as a means
6007c478bd9Sstevel@tonic-gate  * to do an immediate/short-term cache of owner/group strings
6017c478bd9Sstevel@tonic-gate  * for callers like the readdir processing.  In the case of readdir,
6027c478bd9Sstevel@tonic-gate  * it is likely that the directory objects will be owned by the same
6037c478bd9Sstevel@tonic-gate  * owner/group and if so there is no need to call into the uid/gid
6047c478bd9Sstevel@tonic-gate  * mapping code.  While the uid/gid interfaces have their own cache
6057c478bd9Sstevel@tonic-gate  * having one here will reduct pathlength further.
6067c478bd9Sstevel@tonic-gate  */
6077c478bd9Sstevel@tonic-gate #define	MAX_OG_NAME 100
6087c478bd9Sstevel@tonic-gate typedef struct ug_cache
6097c478bd9Sstevel@tonic-gate {
6107c478bd9Sstevel@tonic-gate 	uid_t	uid;
6117c478bd9Sstevel@tonic-gate 	gid_t	gid;
6127c478bd9Sstevel@tonic-gate 	utf8string u_curr, u_last;
6137c478bd9Sstevel@tonic-gate 	utf8string g_curr, g_last;
6147c478bd9Sstevel@tonic-gate 	char	u_buf1[MAX_OG_NAME];
6157c478bd9Sstevel@tonic-gate 	char	u_buf2[MAX_OG_NAME];
6167c478bd9Sstevel@tonic-gate 	char	g_buf1[MAX_OG_NAME];
6177c478bd9Sstevel@tonic-gate 	char	g_buf2[MAX_OG_NAME];
6187c478bd9Sstevel@tonic-gate } ug_cache_t;
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate #define	U_SWAP_CURR_LAST(ug) \
6217c478bd9Sstevel@tonic-gate 	(ug)->u_last.utf8string_len = (ug)->u_curr.utf8string_len;	\
6227c478bd9Sstevel@tonic-gate 	if ((ug)->u_last.utf8string_val == (ug)->u_buf1) {		\
6237c478bd9Sstevel@tonic-gate 		(ug)->u_last.utf8string_val = (ug)->u_buf2;		\
6247c478bd9Sstevel@tonic-gate 		(ug)->u_curr.utf8string_val = (ug)->u_buf1;		\
6257c478bd9Sstevel@tonic-gate 	} else {							\
6267c478bd9Sstevel@tonic-gate 		(ug)->u_last.utf8string_val = (ug)->u_buf1;		\
6277c478bd9Sstevel@tonic-gate 		(ug)->u_curr.utf8string_val = (ug)->u_buf2;		\
6287c478bd9Sstevel@tonic-gate 	}
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate #define	G_SWAP_CURR_LAST(ug) \
6317c478bd9Sstevel@tonic-gate 	(ug)->g_last.utf8string_len = (ug)->g_curr.utf8string_len;	\
6327c478bd9Sstevel@tonic-gate 	if ((ug)->g_last.utf8string_val == (ug)->g_buf1) {		\
6337c478bd9Sstevel@tonic-gate 		(ug)->g_last.utf8string_val = (ug)->g_buf2;		\
6347c478bd9Sstevel@tonic-gate 		(ug)->g_curr.utf8string_val = (ug)->g_buf1;		\
6357c478bd9Sstevel@tonic-gate 	} else {							\
6367c478bd9Sstevel@tonic-gate 		(ug)->g_last.utf8string_val = (ug)->g_buf1;		\
6377c478bd9Sstevel@tonic-gate 		(ug)->g_curr.utf8string_val = (ug)->g_buf2;		\
6387c478bd9Sstevel@tonic-gate 	}
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate static ug_cache_t *
6417c478bd9Sstevel@tonic-gate alloc_ugcache()
6427c478bd9Sstevel@tonic-gate {
6437c478bd9Sstevel@tonic-gate 	ug_cache_t *pug = kmem_alloc(sizeof (ug_cache_t), KM_SLEEP);
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate 	pug->uid = pug->gid = 0;
6467c478bd9Sstevel@tonic-gate 	pug->u_curr.utf8string_len = 0;
6477c478bd9Sstevel@tonic-gate 	pug->u_last.utf8string_len = 0;
6487c478bd9Sstevel@tonic-gate 	pug->g_curr.utf8string_len = 0;
6497c478bd9Sstevel@tonic-gate 	pug->g_last.utf8string_len = 0;
6507c478bd9Sstevel@tonic-gate 	pug->u_curr.utf8string_val = pug->u_buf1;
6517c478bd9Sstevel@tonic-gate 	pug->u_last.utf8string_val = pug->u_buf2;
6527c478bd9Sstevel@tonic-gate 	pug->g_curr.utf8string_val = pug->g_buf1;
6537c478bd9Sstevel@tonic-gate 	pug->g_last.utf8string_val = pug->g_buf2;
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate 	return (pug);
6567c478bd9Sstevel@tonic-gate }
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate static void
6597c478bd9Sstevel@tonic-gate xdr_ga_prefill_vattr(struct nfs4_ga_res *garp, struct mntinfo4 *mi)
6607c478bd9Sstevel@tonic-gate {
6617c478bd9Sstevel@tonic-gate 	static vattr_t s_vattr = {
6627c478bd9Sstevel@tonic-gate 		AT_ALL,		/* va_mask */
6637c478bd9Sstevel@tonic-gate 		VNON,		/* va_type */
6647c478bd9Sstevel@tonic-gate 		0777,		/* va_mode */
6657c478bd9Sstevel@tonic-gate 		UID_NOBODY,	/* va_uid */
6667c478bd9Sstevel@tonic-gate 		GID_NOBODY,	/* va_gid */
6677c478bd9Sstevel@tonic-gate 		0,		/* va_fsid */
6687c478bd9Sstevel@tonic-gate 		0,		/* va_nodeid */
6697c478bd9Sstevel@tonic-gate 		1,		/* va_nlink */
6707c478bd9Sstevel@tonic-gate 		0,		/* va_size */
6717c478bd9Sstevel@tonic-gate 		{0, 0},		/* va_atime */
6727c478bd9Sstevel@tonic-gate 		{0, 0},		/* va_mtime */
6737c478bd9Sstevel@tonic-gate 		{0, 0},		/* va_ctime */
6747c478bd9Sstevel@tonic-gate 		0,		/* va_rdev */
6757c478bd9Sstevel@tonic-gate 		MAXBSIZE,	/* va_blksize */
6767c478bd9Sstevel@tonic-gate 		0,		/* va_nblocks */
6777c478bd9Sstevel@tonic-gate 		0		/* va_seq */
6787c478bd9Sstevel@tonic-gate 	};
6797c478bd9Sstevel@tonic-gate 
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	garp->n4g_va = s_vattr;
6827c478bd9Sstevel@tonic-gate 	garp->n4g_va.va_fsid = mi->mi_vfsp->vfs_dev;
6837c478bd9Sstevel@tonic-gate 	hrt2ts(gethrtime(), &garp->n4g_va.va_atime);
6847c478bd9Sstevel@tonic-gate 	garp->n4g_va.va_mtime = garp->n4g_va.va_ctime = garp->n4g_va.va_atime;
6857c478bd9Sstevel@tonic-gate }
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate static void
6887c478bd9Sstevel@tonic-gate xdr_ga_prefill_statvfs(struct nfs4_ga_ext_res *gesp, struct mntinfo4 *mi)
6897c478bd9Sstevel@tonic-gate {
6907c478bd9Sstevel@tonic-gate 	static statvfs64_t s_sb = {
6917c478bd9Sstevel@tonic-gate 		MAXBSIZE,	/* f_bsize */
6927c478bd9Sstevel@tonic-gate 		DEV_BSIZE,	/* f_frsize */
6937c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_blocks */
6947c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_bfree */
6957c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_bavail */
6967c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_files */
6977c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_ffree */
6987c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_favail */
6997c478bd9Sstevel@tonic-gate 		0,		/* f_fsid */
7007c478bd9Sstevel@tonic-gate 		"\0",		/* f_basetype */
7017c478bd9Sstevel@tonic-gate 		0,		/* f_flag */
7027c478bd9Sstevel@tonic-gate 		MAXNAMELEN,	/* f_namemax */
7037c478bd9Sstevel@tonic-gate 		"\0",		/* f_fstr */
7047c478bd9Sstevel@tonic-gate 	};
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 	gesp->n4g_sb = s_sb;
7077c478bd9Sstevel@tonic-gate 	gesp->n4g_sb.f_fsid = mi->mi_vfsp->vfs_fsid.val[0];
7087c478bd9Sstevel@tonic-gate }
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate static bool_t
7117c478bd9Sstevel@tonic-gate xdr_ga_fattr_res(XDR *xdrs, struct nfs4_ga_res *garp, bitmap4 resbmap,
7127c478bd9Sstevel@tonic-gate 		bitmap4 argbmap, struct mntinfo4 *mi, ug_cache_t *pug)
7137c478bd9Sstevel@tonic-gate {
7147c478bd9Sstevel@tonic-gate 	int truefalse;
7157c478bd9Sstevel@tonic-gate 	struct nfs4_ga_ext_res ges, *gesp;
7167c478bd9Sstevel@tonic-gate 	vattr_t *vap = &garp->n4g_va;
7177c478bd9Sstevel@tonic-gate 	vsecattr_t *vsap = &garp->n4g_vsa;
7187c478bd9Sstevel@tonic-gate 
7197c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 	if (garp->n4g_ext_res)
7227c478bd9Sstevel@tonic-gate 		gesp = garp->n4g_ext_res;
7237c478bd9Sstevel@tonic-gate 	else
7247c478bd9Sstevel@tonic-gate 		gesp = &ges;
7257c478bd9Sstevel@tonic-gate 
7267c478bd9Sstevel@tonic-gate 	vap->va_mask = 0;
7277c478bd9Sstevel@tonic-gate 
7287c478bd9Sstevel@tonic-gate 	/* Check to see if the vattr should be pre-filled */
7297c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_VATTR_MASK)
7307c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_vattr(garp, mi);
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_STATFS_ATTR_MASK)
7337c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_statvfs(gesp, mi);
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate 	if (resbmap &
7367c478bd9Sstevel@tonic-gate 	    (FATTR4_SUPPORTED_ATTRS_MASK |
7377c478bd9Sstevel@tonic-gate 	    FATTR4_TYPE_MASK |
7387c478bd9Sstevel@tonic-gate 	    FATTR4_FH_EXPIRE_TYPE_MASK |
7397c478bd9Sstevel@tonic-gate 	    FATTR4_CHANGE_MASK |
7407c478bd9Sstevel@tonic-gate 	    FATTR4_SIZE_MASK |
7417c478bd9Sstevel@tonic-gate 	    FATTR4_LINK_SUPPORT_MASK |
7427c478bd9Sstevel@tonic-gate 	    FATTR4_SYMLINK_SUPPORT_MASK |
7437c478bd9Sstevel@tonic-gate 	    FATTR4_NAMED_ATTR_MASK)) {
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
7467c478bd9Sstevel@tonic-gate 			if (!xdr_bitmap4(xdrs, &gesp->n4g_suppattrs))
7477c478bd9Sstevel@tonic-gate 				return (FALSE);
7487c478bd9Sstevel@tonic-gate 		}
7497c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TYPE_MASK) {
7507c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_type))
7517c478bd9Sstevel@tonic-gate 				return (FALSE);
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate 			if (vap->va_type < NF4REG ||
7547c478bd9Sstevel@tonic-gate 			    vap->va_type > NF4NAMEDATTR)
7557c478bd9Sstevel@tonic-gate 				vap->va_type = VBAD;
7567c478bd9Sstevel@tonic-gate 			else
7577c478bd9Sstevel@tonic-gate 				vap->va_type = nf4_to_vt[vap->va_type];
7587c478bd9Sstevel@tonic-gate 			if (vap->va_type == VBLK)
7597c478bd9Sstevel@tonic-gate 				vap->va_blksize = DEV_BSIZE;
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_TYPE;
7627c478bd9Sstevel@tonic-gate 		}
7637c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
7647c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_fet))
7657c478bd9Sstevel@tonic-gate 				return (FALSE);
7667c478bd9Sstevel@tonic-gate 		}
7677c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHANGE_MASK) {
7687c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
769*0a701b1eSRobert Gordon 			    (u_longlong_t *)&garp->n4g_change))
7707c478bd9Sstevel@tonic-gate 				return (FALSE);
7717c478bd9Sstevel@tonic-gate 			garp->n4g_change_valid = 1;
7727c478bd9Sstevel@tonic-gate 		}
7737c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SIZE_MASK) {
7747c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
775*0a701b1eSRobert Gordon 			    (u_longlong_t *)&vap->va_size))
7767c478bd9Sstevel@tonic-gate 				return (FALSE);
7777c478bd9Sstevel@tonic-gate 			if (!NFS4_SIZE_OK(vap->va_size)) {
7787c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = EFBIG;
7797c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
7807c478bd9Sstevel@tonic-gate 			} else {
7817c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_SIZE;
7827c478bd9Sstevel@tonic-gate 			}
7837c478bd9Sstevel@tonic-gate 		}
7847c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
7857c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
7867c478bd9Sstevel@tonic-gate 				return (FALSE);
7877c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_link_support =
788*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
7897c478bd9Sstevel@tonic-gate 		}
7907c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
7917c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
7927c478bd9Sstevel@tonic-gate 				return (FALSE);
7937c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_symlink_support =
794*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
7957c478bd9Sstevel@tonic-gate 		}
7967c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
7977c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
7987c478bd9Sstevel@tonic-gate 				return (FALSE);
7997c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
8007c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists =
801*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
8027c478bd9Sstevel@tonic-gate 		}
8037c478bd9Sstevel@tonic-gate 	}
8047c478bd9Sstevel@tonic-gate 	if (resbmap &
8057c478bd9Sstevel@tonic-gate 	    (FATTR4_FSID_MASK |
8067c478bd9Sstevel@tonic-gate 	    FATTR4_UNIQUE_HANDLES_MASK |
8077c478bd9Sstevel@tonic-gate 	    FATTR4_LEASE_TIME_MASK |
8087c478bd9Sstevel@tonic-gate 	    FATTR4_RDATTR_ERROR_MASK)) {
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FSID_MASK) {
811*0a701b1eSRobert Gordon 			if ((!xdr_u_longlong_t(xdrs,
812*0a701b1eSRobert Gordon 			    (u_longlong_t *)&garp->n4g_fsid.major)) ||
813*0a701b1eSRobert Gordon 			    (!xdr_u_longlong_t(xdrs,
814*0a701b1eSRobert Gordon 			    (u_longlong_t *)&garp->n4g_fsid.minor)))
8157c478bd9Sstevel@tonic-gate 				return (FALSE);
816*0a701b1eSRobert Gordon 			garp->n4g_fsid_valid = 1;
8177c478bd9Sstevel@tonic-gate 		}
8187c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
8197c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
8207c478bd9Sstevel@tonic-gate 				return (FALSE);
8217c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_unique_handles =
822*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
8237c478bd9Sstevel@tonic-gate 		}
8247c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
8257c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_leasetime))
8267c478bd9Sstevel@tonic-gate 				return (FALSE);
8277c478bd9Sstevel@tonic-gate 		}
8287c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
8297c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs,
830*0a701b1eSRobert Gordon 			    (int *)&gesp->n4g_rdattr_error))
8317c478bd9Sstevel@tonic-gate 				return (FALSE);
8327c478bd9Sstevel@tonic-gate 		}
8337c478bd9Sstevel@tonic-gate 	}
8347c478bd9Sstevel@tonic-gate 	if (resbmap &
8357c478bd9Sstevel@tonic-gate 	    (FATTR4_ACL_MASK |
8367c478bd9Sstevel@tonic-gate 	    FATTR4_ACLSUPPORT_MASK |
8377c478bd9Sstevel@tonic-gate 	    FATTR4_ARCHIVE_MASK |
8387c478bd9Sstevel@tonic-gate 	    FATTR4_CANSETTIME_MASK)) {
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACL_MASK) {
8417c478bd9Sstevel@tonic-gate 			fattr4_acl	acl;
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate 			acl.fattr4_acl_val = NULL;
8447c478bd9Sstevel@tonic-gate 			acl.fattr4_acl_len = 0;
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate 			if (!xdr_fattr4_acl(xdrs, &acl))
8477c478bd9Sstevel@tonic-gate 				return (FALSE);
8487c478bd9Sstevel@tonic-gate 
8497c478bd9Sstevel@tonic-gate 			vsap->vsa_aclcnt = acl.fattr4_acl_len;
8507c478bd9Sstevel@tonic-gate 			vsap->vsa_aclentp = acl.fattr4_acl_val;
8517c478bd9Sstevel@tonic-gate 			vsap->vsa_mask = VSA_ACE | VSA_ACECNT;
852da6c28aaSamw 			vsap->vsa_aclentsz = vsap->vsa_aclcnt * sizeof (ace_t);
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 		}
8557c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
8567c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_aclsupport))
8577c478bd9Sstevel@tonic-gate 				return (FALSE);
8587c478bd9Sstevel@tonic-gate 		}
8597c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ARCHIVE_MASK) {
8607c478bd9Sstevel@tonic-gate 			ASSERT(0);
8617c478bd9Sstevel@tonic-gate 		}
8627c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CANSETTIME_MASK) {
8637c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
8647c478bd9Sstevel@tonic-gate 				return (FALSE);
8657c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_cansettime =
866*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
8677c478bd9Sstevel@tonic-gate 		}
8687c478bd9Sstevel@tonic-gate 	}
8697c478bd9Sstevel@tonic-gate 	if (resbmap &
8707c478bd9Sstevel@tonic-gate 	    (FATTR4_CASE_INSENSITIVE_MASK |
8717c478bd9Sstevel@tonic-gate 	    FATTR4_CASE_PRESERVING_MASK |
8727c478bd9Sstevel@tonic-gate 	    FATTR4_CHOWN_RESTRICTED_MASK |
8737c478bd9Sstevel@tonic-gate 	    FATTR4_FILEHANDLE_MASK |
8747c478bd9Sstevel@tonic-gate 	    FATTR4_FILEID_MASK |
8757c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_AVAIL_MASK |
8767c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_FREE_MASK |
8777c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_TOTAL_MASK)) {
8787c478bd9Sstevel@tonic-gate 
8797c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
8807c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
8817c478bd9Sstevel@tonic-gate 				return (FALSE);
8827c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_insensitive =
883*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
8847c478bd9Sstevel@tonic-gate 		}
8857c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
8867c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
8877c478bd9Sstevel@tonic-gate 				return (FALSE);
8887c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_preserving =
889*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
8907c478bd9Sstevel@tonic-gate 		}
8917c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
8927c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
8937c478bd9Sstevel@tonic-gate 				return (FALSE);
8947c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_chown_restricted =
895*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
8967c478bd9Sstevel@tonic-gate 		}
8977c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
8987c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
8997c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.val =
900*0a701b1eSRobert Gordon 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
9017c478bd9Sstevel@tonic-gate 			if (!xdr_bytes(xdrs,
9027c478bd9Sstevel@tonic-gate 			    (char **)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_val,
9037c478bd9Sstevel@tonic-gate 			    (uint_t *)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_len,
9047c478bd9Sstevel@tonic-gate 			    NFS4_FHSIZE))
9057c478bd9Sstevel@tonic-gate 				return (FALSE);
9067c478bd9Sstevel@tonic-gate 		}
9077c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEID_MASK) {
9087c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
909*0a701b1eSRobert Gordon 			    (u_longlong_t *)&vap->va_nodeid))
9107c478bd9Sstevel@tonic-gate 				return (FALSE);
9117c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NODEID;
9127c478bd9Sstevel@tonic-gate 		}
9137c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
9147c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
915*0a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_favail))
9167c478bd9Sstevel@tonic-gate 				return (FALSE);
9177c478bd9Sstevel@tonic-gate 		}
9187c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_FREE_MASK) {
9197c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
920*0a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_ffree))
9217c478bd9Sstevel@tonic-gate 				return (FALSE);
9227c478bd9Sstevel@tonic-gate 		}
9237c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
9247c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
925*0a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_files))
9267c478bd9Sstevel@tonic-gate 				return (FALSE);
9277c478bd9Sstevel@tonic-gate 		}
9287c478bd9Sstevel@tonic-gate 	}
9297c478bd9Sstevel@tonic-gate 	if (resbmap &
9307c478bd9Sstevel@tonic-gate 	    (FATTR4_FS_LOCATIONS_MASK |
9317c478bd9Sstevel@tonic-gate 	    FATTR4_HIDDEN_MASK |
9327c478bd9Sstevel@tonic-gate 	    FATTR4_HOMOGENEOUS_MASK)) {
9337c478bd9Sstevel@tonic-gate 
9347c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
9357c478bd9Sstevel@tonic-gate 			ASSERT(0);
9367c478bd9Sstevel@tonic-gate 		}
9377c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HIDDEN_MASK) {
9387c478bd9Sstevel@tonic-gate 			ASSERT(0);
9397c478bd9Sstevel@tonic-gate 		}
9407c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
9417c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9427c478bd9Sstevel@tonic-gate 				return (FALSE);
9437c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_homogeneous =
944*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
9457c478bd9Sstevel@tonic-gate 		}
9467c478bd9Sstevel@tonic-gate 	}
9477c478bd9Sstevel@tonic-gate 	if (resbmap &
9487c478bd9Sstevel@tonic-gate 	    (FATTR4_MAXFILESIZE_MASK |
9497c478bd9Sstevel@tonic-gate 	    FATTR4_MAXLINK_MASK |
9507c478bd9Sstevel@tonic-gate 	    FATTR4_MAXNAME_MASK |
9517c478bd9Sstevel@tonic-gate 	    FATTR4_MAXREAD_MASK |
9527c478bd9Sstevel@tonic-gate 	    FATTR4_MAXWRITE_MASK)) {
9537c478bd9Sstevel@tonic-gate 
9547c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
9557c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
956*0a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_maxfilesize))
9577c478bd9Sstevel@tonic-gate 				return (FALSE);
9587c478bd9Sstevel@tonic-gate 		}
9597c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXLINK_MASK) {
9607c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs,
961*0a701b1eSRobert Gordon 			    (int *)&gesp->n4g_pc4.pc4_link_max))
9627c478bd9Sstevel@tonic-gate 				return (FALSE);
9637c478bd9Sstevel@tonic-gate 		}
9647c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXNAME_MASK) {
9657c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs,
966*0a701b1eSRobert Gordon 			    (int *)&gesp->n4g_pc4.pc4_name_max))
9677c478bd9Sstevel@tonic-gate 				return (FALSE);
9687c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
9697c478bd9Sstevel@tonic-gate 		}
9707c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXREAD_MASK) {
9717c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
972*0a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_maxread))
9737c478bd9Sstevel@tonic-gate 				return (FALSE);
9747c478bd9Sstevel@tonic-gate 		}
9757c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXWRITE_MASK) {
9767c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
977*0a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_maxwrite))
9787c478bd9Sstevel@tonic-gate 				return (FALSE);
9797c478bd9Sstevel@tonic-gate 		}
9807c478bd9Sstevel@tonic-gate 	}
9817c478bd9Sstevel@tonic-gate 	if (resbmap &
9827c478bd9Sstevel@tonic-gate 	    (FATTR4_MIMETYPE_MASK |
9837c478bd9Sstevel@tonic-gate 	    FATTR4_MODE_MASK |
9847c478bd9Sstevel@tonic-gate 	    FATTR4_NO_TRUNC_MASK |
9857c478bd9Sstevel@tonic-gate 	    FATTR4_NUMLINKS_MASK)) {
9867c478bd9Sstevel@tonic-gate 
9877c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MIMETYPE_MASK) {
9887c478bd9Sstevel@tonic-gate 			ASSERT(0);
9897c478bd9Sstevel@tonic-gate 		}
9907c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MODE_MASK) {
9917c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_mode))
9927c478bd9Sstevel@tonic-gate 				return (FALSE);
9937c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MODE;
9947c478bd9Sstevel@tonic-gate 		}
9957c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
9967c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9977c478bd9Sstevel@tonic-gate 				return (FALSE);
9987c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_no_trunc =
999*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
10007c478bd9Sstevel@tonic-gate 		}
10017c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NUMLINKS_MASK) {
10027c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_nlink))
10037c478bd9Sstevel@tonic-gate 				return (FALSE);
10047c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NLINK;
10057c478bd9Sstevel@tonic-gate 		}
10067c478bd9Sstevel@tonic-gate 	}
10077c478bd9Sstevel@tonic-gate 	if (resbmap &
10087c478bd9Sstevel@tonic-gate 	    (FATTR4_OWNER_MASK |
10097c478bd9Sstevel@tonic-gate 	    FATTR4_OWNER_GROUP_MASK |
10107c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
10117c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
10127c478bd9Sstevel@tonic-gate 
10137c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_MASK) {
10147c478bd9Sstevel@tonic-gate 			uint_t *owner_length, ol;
10157c478bd9Sstevel@tonic-gate 			char *owner_val = NULL;
10167c478bd9Sstevel@tonic-gate 			char *owner_alloc = NULL;
10177c478bd9Sstevel@tonic-gate 			utf8string ov;
10187c478bd9Sstevel@tonic-gate 			int error;
10197c478bd9Sstevel@tonic-gate 
10207c478bd9Sstevel@tonic-gate 			/* get the OWNER_LENGTH */
10217c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ol))
10227c478bd9Sstevel@tonic-gate 				return (FALSE);
10237c478bd9Sstevel@tonic-gate 
10247c478bd9Sstevel@tonic-gate 			/* Manage the owner length location */
10257c478bd9Sstevel@tonic-gate 			if (pug && ol <= MAX_OG_NAME) {
10267c478bd9Sstevel@tonic-gate 				owner_length = &pug->u_curr.utf8string_len;
10277c478bd9Sstevel@tonic-gate 				*owner_length = ol;
10287c478bd9Sstevel@tonic-gate 			} else {
10297c478bd9Sstevel@tonic-gate 				owner_length = &ol;
10307c478bd9Sstevel@tonic-gate 			}
10317c478bd9Sstevel@tonic-gate 
10327c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
10337c478bd9Sstevel@tonic-gate 			if (*owner_length > MAX_OG_NAME || pug == NULL)
10347c478bd9Sstevel@tonic-gate 				owner_val = owner_alloc =
1035*0a701b1eSRobert Gordon 				    kmem_alloc(*owner_length, KM_SLEEP);
10367c478bd9Sstevel@tonic-gate 			else
10377c478bd9Sstevel@tonic-gate 				owner_val = pug->u_curr.utf8string_val;
10387c478bd9Sstevel@tonic-gate 
10397c478bd9Sstevel@tonic-gate 			/* get the OWNER string */
10407c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, owner_val, *owner_length)) {
10417c478bd9Sstevel@tonic-gate 				if (owner_alloc)
10427c478bd9Sstevel@tonic-gate 					kmem_free(owner_alloc, *owner_length);
10437c478bd9Sstevel@tonic-gate 				return (FALSE);
10447c478bd9Sstevel@tonic-gate 			}
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
10477c478bd9Sstevel@tonic-gate 			if (pug &&
10487c478bd9Sstevel@tonic-gate 			    *owner_length == pug->u_last.utf8string_len &&
10497c478bd9Sstevel@tonic-gate 			    bcmp(owner_val, pug->u_last.utf8string_val,
1050*0a701b1eSRobert Gordon 			    *owner_length) == 0) {
10517c478bd9Sstevel@tonic-gate 				vap->va_uid = pug->uid;
10527c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_UID;
10537c478bd9Sstevel@tonic-gate 			} else {
10547c478bd9Sstevel@tonic-gate 				uid_t uid;
10557c478bd9Sstevel@tonic-gate 
10567c478bd9Sstevel@tonic-gate 				ov.utf8string_len = *owner_length;
10577c478bd9Sstevel@tonic-gate 				ov.utf8string_val = owner_val;
10587c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
10597c478bd9Sstevel@tonic-gate 				/*
10607c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
10617c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
10627c478bd9Sstevel@tonic-gate 				 * be cached.
10637c478bd9Sstevel@tonic-gate 				 */
10647c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
10657c478bd9Sstevel@tonic-gate 					error = 0;
10667c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
1067*0a701b1eSRobert Gordon 					    NFS4_GETATTR_NOCACHE_OK;
10687c478bd9Sstevel@tonic-gate 				}
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate 				if (error) {
10717c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
10727c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
1073*0a701b1eSRobert Gordon 					    NFS4_GETATTR_ATUID_ERR;
10747c478bd9Sstevel@tonic-gate 				} else {
10757c478bd9Sstevel@tonic-gate 					vap->va_uid = uid;
10767c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_UID;
10777c478bd9Sstevel@tonic-gate 					if (pug && ol <= MAX_OG_NAME) {
10787c478bd9Sstevel@tonic-gate 						pug->uid = uid;
10797c478bd9Sstevel@tonic-gate 						U_SWAP_CURR_LAST(pug);
10807c478bd9Sstevel@tonic-gate 					}
10817c478bd9Sstevel@tonic-gate 				}
10827c478bd9Sstevel@tonic-gate 				if (owner_alloc)
10837c478bd9Sstevel@tonic-gate 					kmem_free(owner_alloc, *owner_length);
10847c478bd9Sstevel@tonic-gate 			}
10857c478bd9Sstevel@tonic-gate 		}
10867c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
10877c478bd9Sstevel@tonic-gate 			uint_t *group_length, gl;
10887c478bd9Sstevel@tonic-gate 			char *group_val = NULL;
10897c478bd9Sstevel@tonic-gate 			char *group_alloc = NULL;
10907c478bd9Sstevel@tonic-gate 			utf8string gv;
10917c478bd9Sstevel@tonic-gate 			int error;
10927c478bd9Sstevel@tonic-gate 
10937c478bd9Sstevel@tonic-gate 			/* get the OWNER_GROUP_LENGTH */
10947c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &gl))
10957c478bd9Sstevel@tonic-gate 				return (FALSE);
10967c478bd9Sstevel@tonic-gate 
10977c478bd9Sstevel@tonic-gate 			/* Manage the group length location */
10987c478bd9Sstevel@tonic-gate 			if (pug && gl <= MAX_OG_NAME) {
10997c478bd9Sstevel@tonic-gate 				group_length = &pug->g_curr.utf8string_len;
11007c478bd9Sstevel@tonic-gate 				*group_length = gl;
11017c478bd9Sstevel@tonic-gate 			} else {
11027c478bd9Sstevel@tonic-gate 				group_length = &gl;
11037c478bd9Sstevel@tonic-gate 			}
11047c478bd9Sstevel@tonic-gate 
11057c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
11067c478bd9Sstevel@tonic-gate 			if (*group_length > MAX_OG_NAME || pug == NULL)
11077c478bd9Sstevel@tonic-gate 				group_val = group_alloc =
1108*0a701b1eSRobert Gordon 				    kmem_alloc(*group_length, KM_SLEEP);
11097c478bd9Sstevel@tonic-gate 			else
11107c478bd9Sstevel@tonic-gate 				group_val = pug->g_curr.utf8string_val;
11117c478bd9Sstevel@tonic-gate 
11127c478bd9Sstevel@tonic-gate 			/* get the OWNER_GROUP string */
11137c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, group_val, *group_length)) {
11147c478bd9Sstevel@tonic-gate 				if (group_alloc)
11157c478bd9Sstevel@tonic-gate 					kmem_free(group_alloc, *group_length);
11167c478bd9Sstevel@tonic-gate 				return (FALSE);
11177c478bd9Sstevel@tonic-gate 			}
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
11207c478bd9Sstevel@tonic-gate 			if (pug &&
11217c478bd9Sstevel@tonic-gate 			    *group_length == pug->g_last.utf8string_len &&
11227c478bd9Sstevel@tonic-gate 			    bcmp(group_val, pug->g_last.utf8string_val,
1123*0a701b1eSRobert Gordon 			    *group_length) == 0) {
11247c478bd9Sstevel@tonic-gate 				vap->va_gid = pug->gid;
11257c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_GID;
11267c478bd9Sstevel@tonic-gate 			} else {
11277c478bd9Sstevel@tonic-gate 				uid_t gid;
11287c478bd9Sstevel@tonic-gate 
11297c478bd9Sstevel@tonic-gate 				gv.utf8string_len = *group_length;
11307c478bd9Sstevel@tonic-gate 				gv.utf8string_val = group_val;
11317c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
11327c478bd9Sstevel@tonic-gate 				/*
11337c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
11347c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
11357c478bd9Sstevel@tonic-gate 				 * be cached.
11367c478bd9Sstevel@tonic-gate 				 */
11377c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
11387c478bd9Sstevel@tonic-gate 					error = 0;
11397c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
1140*0a701b1eSRobert Gordon 					    NFS4_GETATTR_NOCACHE_OK;
11417c478bd9Sstevel@tonic-gate 				}
11427c478bd9Sstevel@tonic-gate 
11437c478bd9Sstevel@tonic-gate 				if (error) {
11447c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
11457c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
1146*0a701b1eSRobert Gordon 					    NFS4_GETATTR_ATGID_ERR;
11477c478bd9Sstevel@tonic-gate 				} else {
11487c478bd9Sstevel@tonic-gate 					vap->va_gid = gid;
11497c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_GID;
11507c478bd9Sstevel@tonic-gate 					if (pug && gl <= MAX_OG_NAME) {
11517c478bd9Sstevel@tonic-gate 						pug->gid = gid;
11527c478bd9Sstevel@tonic-gate 						G_SWAP_CURR_LAST(pug);
11537c478bd9Sstevel@tonic-gate 					}
11547c478bd9Sstevel@tonic-gate 				}
11557c478bd9Sstevel@tonic-gate 				if (group_alloc) {
11567c478bd9Sstevel@tonic-gate 					kmem_free(group_alloc, *group_length);
11577c478bd9Sstevel@tonic-gate 				}
11587c478bd9Sstevel@tonic-gate 			}
11597c478bd9Sstevel@tonic-gate 		}
11607c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
11617c478bd9Sstevel@tonic-gate 			ASSERT(0);
11627c478bd9Sstevel@tonic-gate 		}
11637c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
11647c478bd9Sstevel@tonic-gate 			ASSERT(0);
11657c478bd9Sstevel@tonic-gate 		}
11667c478bd9Sstevel@tonic-gate 	}
11677c478bd9Sstevel@tonic-gate 	if (resbmap &
11687c478bd9Sstevel@tonic-gate 	    (FATTR4_QUOTA_USED_MASK |
11697c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_AVAIL_MASK |
11707c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_FREE_MASK |
11717c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_TOTAL_MASK |
11727c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_USED_MASK |
11737c478bd9Sstevel@tonic-gate 	    FATTR4_SYSTEM_MASK)) {
11747c478bd9Sstevel@tonic-gate 
11757c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
11767c478bd9Sstevel@tonic-gate 			ASSERT(0);
11777c478bd9Sstevel@tonic-gate 		}
11787c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RAWDEV_MASK) {
11797c478bd9Sstevel@tonic-gate 			fattr4_rawdev rawdev;
11807c478bd9Sstevel@tonic-gate 			if (!xdr_fattr4_rawdev(xdrs, &rawdev))
11817c478bd9Sstevel@tonic-gate 				return (FALSE);
11827c478bd9Sstevel@tonic-gate 
11837c478bd9Sstevel@tonic-gate 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
11847c478bd9Sstevel@tonic-gate 				vap->va_rdev = makedevice(rawdev.specdata1,
1185*0a701b1eSRobert Gordon 				    rawdev.specdata2);
11867c478bd9Sstevel@tonic-gate 			} else {
11877c478bd9Sstevel@tonic-gate 				vap->va_rdev = 0;
11887c478bd9Sstevel@tonic-gate 			}
11897c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_RDEV;
11907c478bd9Sstevel@tonic-gate 		}
11917c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
11927c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
1193*0a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_bavail))
11947c478bd9Sstevel@tonic-gate 				return (FALSE);
11957c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
11967c478bd9Sstevel@tonic-gate 		}
11977c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
11987c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
1199*0a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_bfree))
12007c478bd9Sstevel@tonic-gate 				return (FALSE);
12017c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
12027c478bd9Sstevel@tonic-gate 		}
12037c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
12047c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
1205*0a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_blocks))
12067c478bd9Sstevel@tonic-gate 				return (FALSE);
12077c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
12087c478bd9Sstevel@tonic-gate 		}
12097c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_USED_MASK) {
12107c478bd9Sstevel@tonic-gate 			uint64_t space_used;
12117c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
1212*0a701b1eSRobert Gordon 			    (u_longlong_t *)&space_used))
12137c478bd9Sstevel@tonic-gate 				return (FALSE);
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 			/* Compute space depending on device type */
12167c478bd9Sstevel@tonic-gate 			ASSERT((vap->va_mask & AT_TYPE));
12177c478bd9Sstevel@tonic-gate 			if (vap->va_type == VREG || vap->va_type == VDIR ||
12187c478bd9Sstevel@tonic-gate 			    vap->va_type == VLNK) {
12197c478bd9Sstevel@tonic-gate 				vap->va_nblocks = (u_longlong_t)
1220*0a701b1eSRobert Gordon 				    ((space_used + (offset4)DEV_BSIZE -
1221*0a701b1eSRobert Gordon 				    (offset4)1) / (offset4)DEV_BSIZE);
12227c478bd9Sstevel@tonic-gate 			} else {
12237c478bd9Sstevel@tonic-gate 				vap->va_nblocks = 0;
12247c478bd9Sstevel@tonic-gate 			}
12257c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NBLOCKS;
12267c478bd9Sstevel@tonic-gate 		}
12277c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYSTEM_MASK) {
12287c478bd9Sstevel@tonic-gate 			ASSERT(0);
12297c478bd9Sstevel@tonic-gate 		}
12307c478bd9Sstevel@tonic-gate 	}
12317c478bd9Sstevel@tonic-gate 	if (resbmap &
12327c478bd9Sstevel@tonic-gate 	    (FATTR4_TIME_ACCESS_MASK |
12337c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_ACCESS_SET_MASK |
12347c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_BACKUP_MASK |
12357c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_CREATE_MASK |
12367c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_DELTA_MASK |
12377c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_METADATA_MASK |
12387c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_MASK |
12397c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_SET_MASK |
12407c478bd9Sstevel@tonic-gate 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
12417c478bd9Sstevel@tonic-gate 
12427c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
12437c478bd9Sstevel@tonic-gate 			nfstime4 atime;
12447c478bd9Sstevel@tonic-gate 			int error;
12457c478bd9Sstevel@tonic-gate 
12467c478bd9Sstevel@tonic-gate 			if (!xdr_longlong_t(xdrs,
1247*0a701b1eSRobert Gordon 			    (longlong_t *)&atime.seconds))
12487c478bd9Sstevel@tonic-gate 				return (FALSE);
12497c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&atime.nseconds))
12507c478bd9Sstevel@tonic-gate 				return (FALSE);
12517c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&atime, &vap->va_atime);
12527c478bd9Sstevel@tonic-gate 			if (error) {
12537c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
12547c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
12557c478bd9Sstevel@tonic-gate 			}
12567c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_ATIME;
12577c478bd9Sstevel@tonic-gate 		}
12587c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
12597c478bd9Sstevel@tonic-gate 			ASSERT(0);
12607c478bd9Sstevel@tonic-gate 		}
12617c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
12627c478bd9Sstevel@tonic-gate 			ASSERT(0);
12637c478bd9Sstevel@tonic-gate 		}
12647c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
12657c478bd9Sstevel@tonic-gate 			ASSERT(0);
12667c478bd9Sstevel@tonic-gate 		}
12677c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
12687c478bd9Sstevel@tonic-gate 			if ((!xdr_u_longlong_t(xdrs,
12697c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_delta.seconds)) ||
12707c478bd9Sstevel@tonic-gate 			    (!xdr_u_int(xdrs, &gesp->n4g_delta.nseconds)))
12717c478bd9Sstevel@tonic-gate 				return (FALSE);
12727c478bd9Sstevel@tonic-gate 		}
12737c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
12747c478bd9Sstevel@tonic-gate 			nfstime4 mdt;
12757c478bd9Sstevel@tonic-gate 			int error;
12767c478bd9Sstevel@tonic-gate 
12777c478bd9Sstevel@tonic-gate 			if (!xdr_longlong_t(xdrs, (longlong_t *)&mdt.seconds))
12787c478bd9Sstevel@tonic-gate 				return (FALSE);
12797c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&mdt.nseconds))
12807c478bd9Sstevel@tonic-gate 				return (FALSE);
12817c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
12827c478bd9Sstevel@tonic-gate 			if (error) {
12837c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
12847c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
12857c478bd9Sstevel@tonic-gate 			}
12867c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_CTIME;
12877c478bd9Sstevel@tonic-gate 		}
12887c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
12897c478bd9Sstevel@tonic-gate 			nfstime4 mtime;
12907c478bd9Sstevel@tonic-gate 			int error;
12917c478bd9Sstevel@tonic-gate 
12927c478bd9Sstevel@tonic-gate 			if (!xdr_longlong_t(xdrs,
1293*0a701b1eSRobert Gordon 			    (longlong_t *)&mtime.seconds))
12947c478bd9Sstevel@tonic-gate 				return (FALSE);
12957c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&mtime.nseconds))
12967c478bd9Sstevel@tonic-gate 				return (FALSE);
12977c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
12987c478bd9Sstevel@tonic-gate 			if (error) {
12997c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
13007c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
13017c478bd9Sstevel@tonic-gate 			}
13027c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MTIME;
13037c478bd9Sstevel@tonic-gate 		}
13047c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
13057c478bd9Sstevel@tonic-gate 			ASSERT(0);
13067c478bd9Sstevel@tonic-gate 		}
13077c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
13087c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
1309*0a701b1eSRobert Gordon 			    (u_longlong_t *)&garp->n4g_mon_fid))
13107c478bd9Sstevel@tonic-gate 				return (FALSE);
13117c478bd9Sstevel@tonic-gate 			garp->n4g_mon_fid_valid = 1;
13127c478bd9Sstevel@tonic-gate 		}
13137c478bd9Sstevel@tonic-gate 	}
13147c478bd9Sstevel@tonic-gate 
13157c478bd9Sstevel@tonic-gate 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
13167c478bd9Sstevel@tonic-gate 		/* copy only if not provided */
13177c478bd9Sstevel@tonic-gate 		if (garp->n4g_ext_res == NULL) {
13187c478bd9Sstevel@tonic-gate 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
13197c478bd9Sstevel@tonic-gate 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
13207c478bd9Sstevel@tonic-gate 		}
13217c478bd9Sstevel@tonic-gate 	}
13227c478bd9Sstevel@tonic-gate 
13237c478bd9Sstevel@tonic-gate 	return (TRUE);
13247c478bd9Sstevel@tonic-gate }
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate /*
13277c478bd9Sstevel@tonic-gate  * Inlined version of get_bitmap4 processing
13287c478bd9Sstevel@tonic-gate  */
13297c478bd9Sstevel@tonic-gate bitmap4
13307c478bd9Sstevel@tonic-gate xdr_get_bitmap4_inline(uint32_t **iptr)
13317c478bd9Sstevel@tonic-gate {
13327c478bd9Sstevel@tonic-gate 	uint32_t resbmaplen;
13337c478bd9Sstevel@tonic-gate 	bitmap4 bm;
13347c478bd9Sstevel@tonic-gate 	uint32_t *ptr = *iptr;
13357c478bd9Sstevel@tonic-gate 
13367c478bd9Sstevel@tonic-gate 	/* bitmap LENGTH */
13377c478bd9Sstevel@tonic-gate 	resbmaplen = IXDR_GET_U_INT32(ptr);
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate 	/* Inline the bitmap and attrlen for common case of two word map */
13407c478bd9Sstevel@tonic-gate 	if (resbmaplen == 2) {
13417c478bd9Sstevel@tonic-gate 		IXDR_GET_HYPER(ptr, bm);
13427c478bd9Sstevel@tonic-gate 		*iptr = ptr;
13437c478bd9Sstevel@tonic-gate 		return (bm);
13447c478bd9Sstevel@tonic-gate 	}
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
13477c478bd9Sstevel@tonic-gate 	bm = IXDR_GET_U_INT32(ptr);
13487c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
13497c478bd9Sstevel@tonic-gate 		*iptr = ptr;
13507c478bd9Sstevel@tonic-gate 		return (bm);
13517c478bd9Sstevel@tonic-gate 	}
13527c478bd9Sstevel@tonic-gate 	*((uint32_t *)&bm) |= IXDR_GET_U_INT32(ptr);
13537c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
13547c478bd9Sstevel@tonic-gate 		*iptr = ptr;
13557c478bd9Sstevel@tonic-gate 		return (bm);
13567c478bd9Sstevel@tonic-gate 	}
13577c478bd9Sstevel@tonic-gate 	ptr += resbmaplen;
13587c478bd9Sstevel@tonic-gate 	*iptr = ptr;
13597c478bd9Sstevel@tonic-gate 	return (bm);
13607c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
13617c478bd9Sstevel@tonic-gate 	*((uint32_t *)&bm) = IXDR_GET_U_INT32(ptr);
13627c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
13637c478bd9Sstevel@tonic-gate 		*iptr = ptr;
13647c478bd9Sstevel@tonic-gate 		return (bm);
13657c478bd9Sstevel@tonic-gate 	}
13667c478bd9Sstevel@tonic-gate 	bm |= IXDR_GET_U_INT32(ptr);
13677c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
13687c478bd9Sstevel@tonic-gate 		*iptr = ptr;
13697c478bd9Sstevel@tonic-gate 		return (bm);
13707c478bd9Sstevel@tonic-gate 	}
13717c478bd9Sstevel@tonic-gate 	ptr += resbmaplen;
13727c478bd9Sstevel@tonic-gate 	*iptr = ptr;
13737c478bd9Sstevel@tonic-gate 	return (bm);
13747c478bd9Sstevel@tonic-gate #else
13757c478bd9Sstevel@tonic-gate 	ASSERT(0);
13767c478bd9Sstevel@tonic-gate 	ptr += resbmaplen;
13777c478bd9Sstevel@tonic-gate 	*iptr = ptr;
13787c478bd9Sstevel@tonic-gate 	return (0);
13797c478bd9Sstevel@tonic-gate #endif
13807c478bd9Sstevel@tonic-gate }
13817c478bd9Sstevel@tonic-gate 
13827c478bd9Sstevel@tonic-gate static bool_t
13837c478bd9Sstevel@tonic-gate xdr_ga_fattr_res_inline(uint32_t *ptr, struct nfs4_ga_res *garp,
13847c478bd9Sstevel@tonic-gate 			bitmap4 resbmap, bitmap4 argbmap, struct mntinfo4 *mi,
13857c478bd9Sstevel@tonic-gate 			ug_cache_t *pug)
13867c478bd9Sstevel@tonic-gate {
13877c478bd9Sstevel@tonic-gate 	int truefalse;
13887c478bd9Sstevel@tonic-gate 	struct nfs4_ga_ext_res ges, *gesp;
13897c478bd9Sstevel@tonic-gate 	vattr_t *vap = &garp->n4g_va;
13907c478bd9Sstevel@tonic-gate 
13917c478bd9Sstevel@tonic-gate 	if (garp->n4g_ext_res)
13927c478bd9Sstevel@tonic-gate 		gesp = garp->n4g_ext_res;
13937c478bd9Sstevel@tonic-gate 	else
13947c478bd9Sstevel@tonic-gate 		gesp = &ges;
13957c478bd9Sstevel@tonic-gate 
13967c478bd9Sstevel@tonic-gate 	vap->va_mask = 0;
13977c478bd9Sstevel@tonic-gate 
13987c478bd9Sstevel@tonic-gate 	/* Check to see if the vattr should be pre-filled */
13997c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_VATTR_MASK)
14007c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_vattr(garp, mi);
14017c478bd9Sstevel@tonic-gate 
14027c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_STATFS_ATTR_MASK)
14037c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_statvfs(gesp, mi);
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate 	if (resbmap &
14067c478bd9Sstevel@tonic-gate 	    (FATTR4_SUPPORTED_ATTRS_MASK |
14077c478bd9Sstevel@tonic-gate 	    FATTR4_TYPE_MASK |
14087c478bd9Sstevel@tonic-gate 	    FATTR4_FH_EXPIRE_TYPE_MASK |
14097c478bd9Sstevel@tonic-gate 	    FATTR4_CHANGE_MASK |
14107c478bd9Sstevel@tonic-gate 	    FATTR4_SIZE_MASK |
14117c478bd9Sstevel@tonic-gate 	    FATTR4_LINK_SUPPORT_MASK |
14127c478bd9Sstevel@tonic-gate 	    FATTR4_SYMLINK_SUPPORT_MASK |
14137c478bd9Sstevel@tonic-gate 	    FATTR4_NAMED_ATTR_MASK)) {
14147c478bd9Sstevel@tonic-gate 
14157c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
14167c478bd9Sstevel@tonic-gate 			gesp->n4g_suppattrs = xdr_get_bitmap4_inline(&ptr);
14177c478bd9Sstevel@tonic-gate 		}
14187c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TYPE_MASK) {
14197c478bd9Sstevel@tonic-gate 			vap->va_type = IXDR_GET_U_INT32(ptr);
14207c478bd9Sstevel@tonic-gate 
14217c478bd9Sstevel@tonic-gate 			if (vap->va_type < NF4REG ||
14227c478bd9Sstevel@tonic-gate 			    vap->va_type > NF4NAMEDATTR)
14237c478bd9Sstevel@tonic-gate 				vap->va_type = VBAD;
14247c478bd9Sstevel@tonic-gate 			else
14257c478bd9Sstevel@tonic-gate 				vap->va_type = nf4_to_vt[vap->va_type];
14267c478bd9Sstevel@tonic-gate 			if (vap->va_type == VBLK)
14277c478bd9Sstevel@tonic-gate 				vap->va_blksize = DEV_BSIZE;
14287c478bd9Sstevel@tonic-gate 
14297c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_TYPE;
14307c478bd9Sstevel@tonic-gate 		}
14317c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
14327c478bd9Sstevel@tonic-gate 			gesp->n4g_fet = IXDR_GET_U_INT32(ptr);
14337c478bd9Sstevel@tonic-gate 		}
14347c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHANGE_MASK) {
14357c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_change);
14367c478bd9Sstevel@tonic-gate 			garp->n4g_change_valid = 1;
14377c478bd9Sstevel@tonic-gate 		}
14387c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SIZE_MASK) {
14397c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, vap->va_size);
14407c478bd9Sstevel@tonic-gate 
14417c478bd9Sstevel@tonic-gate 			if (!NFS4_SIZE_OK(vap->va_size)) {
14427c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = EFBIG;
14437c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
14447c478bd9Sstevel@tonic-gate 			} else {
14457c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_SIZE;
14467c478bd9Sstevel@tonic-gate 			}
14477c478bd9Sstevel@tonic-gate 		}
14487c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
14497c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
14507c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_link_support =
1451*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
14527c478bd9Sstevel@tonic-gate 		}
14537c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
14547c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
14557c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_symlink_support =
1456*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
14577c478bd9Sstevel@tonic-gate 		}
14587c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
14597c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
14607c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
14617c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists =
1462*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
14637c478bd9Sstevel@tonic-gate 		}
14647c478bd9Sstevel@tonic-gate 	}
14657c478bd9Sstevel@tonic-gate 	if (resbmap &
14667c478bd9Sstevel@tonic-gate 	    (FATTR4_FSID_MASK |
14677c478bd9Sstevel@tonic-gate 	    FATTR4_UNIQUE_HANDLES_MASK |
14687c478bd9Sstevel@tonic-gate 	    FATTR4_LEASE_TIME_MASK |
14697c478bd9Sstevel@tonic-gate 	    FATTR4_RDATTR_ERROR_MASK)) {
14707c478bd9Sstevel@tonic-gate 
14717c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FSID_MASK) {
14727c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.major);
14737c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.minor);
14747c478bd9Sstevel@tonic-gate 			garp->n4g_fsid_valid = 1;
14757c478bd9Sstevel@tonic-gate 		}
14767c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
14777c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
14787c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_unique_handles =
1479*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
14807c478bd9Sstevel@tonic-gate 		}
14817c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
14827c478bd9Sstevel@tonic-gate 			gesp->n4g_leasetime = IXDR_GET_U_INT32(ptr);
14837c478bd9Sstevel@tonic-gate 		}
14847c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
14857c478bd9Sstevel@tonic-gate 			gesp->n4g_rdattr_error = IXDR_GET_U_INT32(ptr);
14867c478bd9Sstevel@tonic-gate 		}
14877c478bd9Sstevel@tonic-gate 	}
14887c478bd9Sstevel@tonic-gate 	if (resbmap &
14897c478bd9Sstevel@tonic-gate 	    (FATTR4_ACL_MASK |
14907c478bd9Sstevel@tonic-gate 	    FATTR4_ACLSUPPORT_MASK |
14917c478bd9Sstevel@tonic-gate 	    FATTR4_ARCHIVE_MASK |
14927c478bd9Sstevel@tonic-gate 	    FATTR4_CANSETTIME_MASK)) {
14937c478bd9Sstevel@tonic-gate 
14947c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACL_MASK) {
14957c478bd9Sstevel@tonic-gate 			ASSERT(0);
14967c478bd9Sstevel@tonic-gate 		}
14977c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
14987c478bd9Sstevel@tonic-gate 			gesp->n4g_aclsupport = IXDR_GET_U_INT32(ptr);
14997c478bd9Sstevel@tonic-gate 		}
15007c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ARCHIVE_MASK) {
15017c478bd9Sstevel@tonic-gate 			ASSERT(0);
15027c478bd9Sstevel@tonic-gate 		}
15037c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CANSETTIME_MASK) {
15047c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
15057c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_cansettime =
1506*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
15077c478bd9Sstevel@tonic-gate 		}
15087c478bd9Sstevel@tonic-gate 	}
15097c478bd9Sstevel@tonic-gate 	if (resbmap &
15107c478bd9Sstevel@tonic-gate 	    (FATTR4_CASE_INSENSITIVE_MASK |
15117c478bd9Sstevel@tonic-gate 	    FATTR4_CASE_PRESERVING_MASK |
15127c478bd9Sstevel@tonic-gate 	    FATTR4_CHOWN_RESTRICTED_MASK |
15137c478bd9Sstevel@tonic-gate 	    FATTR4_FILEHANDLE_MASK |
15147c478bd9Sstevel@tonic-gate 	    FATTR4_FILEID_MASK |
15157c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_AVAIL_MASK |
15167c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_FREE_MASK |
15177c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_TOTAL_MASK)) {
15187c478bd9Sstevel@tonic-gate 
15197c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
15207c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
15217c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_insensitive =
1522*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
15237c478bd9Sstevel@tonic-gate 		}
15247c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
15257c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
15267c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_preserving =
1527*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
15287c478bd9Sstevel@tonic-gate 		}
15297c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
15307c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
15317c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_chown_restricted =
1532*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
15337c478bd9Sstevel@tonic-gate 		}
15347c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
15357c478bd9Sstevel@tonic-gate 			int len = IXDR_GET_U_INT32(ptr);
15367c478bd9Sstevel@tonic-gate 
15377c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
15387c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.val =
1539*0a701b1eSRobert Gordon 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
15407c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.n4g_fh.nfs_fh4_len = len;
15417c478bd9Sstevel@tonic-gate 
15427c478bd9Sstevel@tonic-gate 			bcopy(ptr, gesp->n4g_fh_u.n4g_fh.nfs_fh4_val, len);
15437c478bd9Sstevel@tonic-gate 
15447c478bd9Sstevel@tonic-gate 			ptr += RNDUP(len) / BYTES_PER_XDR_UNIT;
15457c478bd9Sstevel@tonic-gate 		}
15467c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEID_MASK) {
15477c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
15487c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NODEID;
15497c478bd9Sstevel@tonic-gate 		}
15507c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
15517c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_favail);
15527c478bd9Sstevel@tonic-gate 		}
15537c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_FREE_MASK) {
15547c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_ffree);
15557c478bd9Sstevel@tonic-gate 		}
15567c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
15577c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_files);
15587c478bd9Sstevel@tonic-gate 		}
15597c478bd9Sstevel@tonic-gate 	}
15607c478bd9Sstevel@tonic-gate 	if (resbmap &
15617c478bd9Sstevel@tonic-gate 	    (FATTR4_FS_LOCATIONS_MASK |
15627c478bd9Sstevel@tonic-gate 	    FATTR4_HIDDEN_MASK |
15637c478bd9Sstevel@tonic-gate 	    FATTR4_HOMOGENEOUS_MASK)) {
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
15667c478bd9Sstevel@tonic-gate 			ASSERT(0);
15677c478bd9Sstevel@tonic-gate 		}
15687c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HIDDEN_MASK) {
15697c478bd9Sstevel@tonic-gate 			ASSERT(0);
15707c478bd9Sstevel@tonic-gate 		}
15717c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
15727c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
15737c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_homogeneous =
1574*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
15757c478bd9Sstevel@tonic-gate 		}
15767c478bd9Sstevel@tonic-gate 	}
15777c478bd9Sstevel@tonic-gate 	if (resbmap &
15787c478bd9Sstevel@tonic-gate 	    (FATTR4_MAXFILESIZE_MASK |
15797c478bd9Sstevel@tonic-gate 	    FATTR4_MAXLINK_MASK |
15807c478bd9Sstevel@tonic-gate 	    FATTR4_MAXNAME_MASK |
15817c478bd9Sstevel@tonic-gate 	    FATTR4_MAXREAD_MASK |
15827c478bd9Sstevel@tonic-gate 	    FATTR4_MAXWRITE_MASK)) {
15837c478bd9Sstevel@tonic-gate 
15847c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
15857c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxfilesize);
15867c478bd9Sstevel@tonic-gate 		}
15877c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXLINK_MASK) {
15887c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_link_max = IXDR_GET_U_INT32(ptr);
15897c478bd9Sstevel@tonic-gate 		}
15907c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXNAME_MASK) {
15917c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_name_max = IXDR_GET_U_INT32(ptr);
15927c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
15937c478bd9Sstevel@tonic-gate 		}
15947c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXREAD_MASK) {
15957c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxread);
15967c478bd9Sstevel@tonic-gate 		}
15977c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXWRITE_MASK) {
15987c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxwrite);
15997c478bd9Sstevel@tonic-gate 		}
16007c478bd9Sstevel@tonic-gate 	}
16017c478bd9Sstevel@tonic-gate 	if (resbmap &
16027c478bd9Sstevel@tonic-gate 	    (FATTR4_MIMETYPE_MASK |
16037c478bd9Sstevel@tonic-gate 	    FATTR4_MODE_MASK |
16047c478bd9Sstevel@tonic-gate 	    FATTR4_NO_TRUNC_MASK |
16057c478bd9Sstevel@tonic-gate 	    FATTR4_NUMLINKS_MASK)) {
16067c478bd9Sstevel@tonic-gate 
16077c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MIMETYPE_MASK) {
16087c478bd9Sstevel@tonic-gate 			ASSERT(0);
16097c478bd9Sstevel@tonic-gate 		}
16107c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MODE_MASK) {
16117c478bd9Sstevel@tonic-gate 			vap->va_mode = IXDR_GET_U_INT32(ptr);
16127c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MODE;
16137c478bd9Sstevel@tonic-gate 		}
16147c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
16157c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16167c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_no_trunc =
1617*0a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
16187c478bd9Sstevel@tonic-gate 		}
16197c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NUMLINKS_MASK) {
16207c478bd9Sstevel@tonic-gate 			vap->va_nlink = IXDR_GET_U_INT32(ptr);
16217c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NLINK;
16227c478bd9Sstevel@tonic-gate 		}
16237c478bd9Sstevel@tonic-gate 	}
16247c478bd9Sstevel@tonic-gate 	if (resbmap &
16257c478bd9Sstevel@tonic-gate 	    (FATTR4_OWNER_MASK |
16267c478bd9Sstevel@tonic-gate 	    FATTR4_OWNER_GROUP_MASK |
16277c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
16287c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
16297c478bd9Sstevel@tonic-gate 
16307c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_MASK) {
16317c478bd9Sstevel@tonic-gate 			uint_t *owner_length, ol;
16327c478bd9Sstevel@tonic-gate 			char *owner_val = NULL;
16337c478bd9Sstevel@tonic-gate 			utf8string ov;
16347c478bd9Sstevel@tonic-gate 			int error;
16357c478bd9Sstevel@tonic-gate 
16367c478bd9Sstevel@tonic-gate 			/* get the OWNER_LENGTH */
16377c478bd9Sstevel@tonic-gate 			ol = IXDR_GET_U_INT32(ptr);
16387c478bd9Sstevel@tonic-gate 
16397c478bd9Sstevel@tonic-gate 			/* Manage the owner length location */
16407c478bd9Sstevel@tonic-gate 			if (pug && ol <= MAX_OG_NAME) {
16417c478bd9Sstevel@tonic-gate 				owner_length = &pug->u_curr.utf8string_len;
16427c478bd9Sstevel@tonic-gate 				*owner_length = ol;
16437c478bd9Sstevel@tonic-gate 			} else {
16447c478bd9Sstevel@tonic-gate 				owner_length = &ol;
16457c478bd9Sstevel@tonic-gate 			}
16467c478bd9Sstevel@tonic-gate 
16477c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
16487c478bd9Sstevel@tonic-gate 			if (*owner_length > MAX_OG_NAME || pug == NULL)
16497c478bd9Sstevel@tonic-gate 				owner_val = (char *)ptr;
16507c478bd9Sstevel@tonic-gate 			else
16517c478bd9Sstevel@tonic-gate 				owner_val = (char *)ptr;
16527c478bd9Sstevel@tonic-gate 
16537c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
16547c478bd9Sstevel@tonic-gate 			if (pug &&
16557c478bd9Sstevel@tonic-gate 			    *owner_length == pug->u_last.utf8string_len &&
16567c478bd9Sstevel@tonic-gate 			    bcmp(owner_val, pug->u_last.utf8string_val,
1657*0a701b1eSRobert Gordon 			    *owner_length) == 0) {
16587c478bd9Sstevel@tonic-gate 				vap->va_uid = pug->uid;
16597c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_UID;
16607c478bd9Sstevel@tonic-gate 			} else {
16617c478bd9Sstevel@tonic-gate 				uid_t uid;
16627c478bd9Sstevel@tonic-gate 
16637c478bd9Sstevel@tonic-gate 				ov.utf8string_len = *owner_length;
16647c478bd9Sstevel@tonic-gate 				ov.utf8string_val = owner_val;
16657c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
16667c478bd9Sstevel@tonic-gate 				/*
16677c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
16687c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
16697c478bd9Sstevel@tonic-gate 				 * be cached.
16707c478bd9Sstevel@tonic-gate 				 */
16717c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
16727c478bd9Sstevel@tonic-gate 					error = 0;
16737c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
1674*0a701b1eSRobert Gordon 					    NFS4_GETATTR_NOCACHE_OK;
16757c478bd9Sstevel@tonic-gate 				}
16767c478bd9Sstevel@tonic-gate 
16777c478bd9Sstevel@tonic-gate 				if (error) {
16787c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
16797c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
1680*0a701b1eSRobert Gordon 					    NFS4_GETATTR_ATUID_ERR;
16817c478bd9Sstevel@tonic-gate 				} else {
16827c478bd9Sstevel@tonic-gate 					vap->va_uid = uid;
16837c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_UID;
16847c478bd9Sstevel@tonic-gate 					/* save the results for next time */
16857c478bd9Sstevel@tonic-gate 					if (pug && ol <= MAX_OG_NAME) {
16867c478bd9Sstevel@tonic-gate 						pug->uid = uid;
16877c478bd9Sstevel@tonic-gate 						pug->u_curr.utf8string_len =
1688*0a701b1eSRobert Gordon 						    ov.utf8string_len;
16897c478bd9Sstevel@tonic-gate 						bcopy(owner_val,
1690*0a701b1eSRobert Gordon 						    pug->u_curr.utf8string_val,
1691*0a701b1eSRobert Gordon 						    ol);
16927c478bd9Sstevel@tonic-gate 						U_SWAP_CURR_LAST(pug);
16937c478bd9Sstevel@tonic-gate 					}
16947c478bd9Sstevel@tonic-gate 				}
16957c478bd9Sstevel@tonic-gate 			}
16967c478bd9Sstevel@tonic-gate 			ptr += RNDUP(ol) / BYTES_PER_XDR_UNIT;
16977c478bd9Sstevel@tonic-gate 		}
16987c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
16997c478bd9Sstevel@tonic-gate 			uint_t *group_length, gl;
17007c478bd9Sstevel@tonic-gate 			char *group_val = NULL;
17017c478bd9Sstevel@tonic-gate 			utf8string gv;
17027c478bd9Sstevel@tonic-gate 			int error;
17037c478bd9Sstevel@tonic-gate 
17047c478bd9Sstevel@tonic-gate 			/* get the OWNER_GROUP_LENGTH */
17057c478bd9Sstevel@tonic-gate 			gl = IXDR_GET_U_INT32(ptr);
17067c478bd9Sstevel@tonic-gate 
17077c478bd9Sstevel@tonic-gate 			/* Manage the group length location */
17087c478bd9Sstevel@tonic-gate 			if (pug && gl <= MAX_OG_NAME) {
17097c478bd9Sstevel@tonic-gate 				group_length = &pug->g_curr.utf8string_len;
17107c478bd9Sstevel@tonic-gate 				*group_length = gl;
17117c478bd9Sstevel@tonic-gate 			} else {
17127c478bd9Sstevel@tonic-gate 				group_length = &gl;
17137c478bd9Sstevel@tonic-gate 			}
17147c478bd9Sstevel@tonic-gate 
17157c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
17167c478bd9Sstevel@tonic-gate 			if (*group_length > MAX_OG_NAME || pug == NULL)
17177c478bd9Sstevel@tonic-gate 				group_val = (char *)ptr;
17187c478bd9Sstevel@tonic-gate 			else
17197c478bd9Sstevel@tonic-gate 				group_val = (char *)ptr;
17207c478bd9Sstevel@tonic-gate 
17217c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
17227c478bd9Sstevel@tonic-gate 			if (pug &&
17237c478bd9Sstevel@tonic-gate 			    *group_length == pug->g_last.utf8string_len &&
17247c478bd9Sstevel@tonic-gate 			    bcmp(group_val, pug->g_last.utf8string_val,
1725*0a701b1eSRobert Gordon 			    *group_length) == 0) {
17267c478bd9Sstevel@tonic-gate 				vap->va_gid = pug->gid;
17277c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_GID;
17287c478bd9Sstevel@tonic-gate 			} else {
17297c478bd9Sstevel@tonic-gate 				uid_t gid;
17307c478bd9Sstevel@tonic-gate 
17317c478bd9Sstevel@tonic-gate 				gv.utf8string_len = *group_length;
17327c478bd9Sstevel@tonic-gate 				gv.utf8string_val = group_val;
17337c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
17347c478bd9Sstevel@tonic-gate 				/*
17357c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
17367c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
17377c478bd9Sstevel@tonic-gate 				 * be cached.
17387c478bd9Sstevel@tonic-gate 				 */
17397c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
17407c478bd9Sstevel@tonic-gate 					error = 0;
17417c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
1742*0a701b1eSRobert Gordon 					    NFS4_GETATTR_NOCACHE_OK;
17437c478bd9Sstevel@tonic-gate 				}
17447c478bd9Sstevel@tonic-gate 
17457c478bd9Sstevel@tonic-gate 				if (error) {
17467c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
17477c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
1748*0a701b1eSRobert Gordon 					    NFS4_GETATTR_ATGID_ERR;
17497c478bd9Sstevel@tonic-gate 				} else {
17507c478bd9Sstevel@tonic-gate 					vap->va_gid = gid;
17517c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_GID;
17527c478bd9Sstevel@tonic-gate 					if (pug && gl <= MAX_OG_NAME) {
17537c478bd9Sstevel@tonic-gate 						pug->gid = gid;
17547c478bd9Sstevel@tonic-gate 						pug->g_curr.utf8string_len =
1755*0a701b1eSRobert Gordon 						    gv.utf8string_len;
17567c478bd9Sstevel@tonic-gate 						bcopy(group_val,
17577c478bd9Sstevel@tonic-gate 						    pug->g_curr.utf8string_val,
17587c478bd9Sstevel@tonic-gate 						    gl);
17597c478bd9Sstevel@tonic-gate 						G_SWAP_CURR_LAST(pug);
17607c478bd9Sstevel@tonic-gate 					}
17617c478bd9Sstevel@tonic-gate 				}
17627c478bd9Sstevel@tonic-gate 			}
17637c478bd9Sstevel@tonic-gate 			ptr += RNDUP(gl) / BYTES_PER_XDR_UNIT;
17647c478bd9Sstevel@tonic-gate 		}
17657c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
17667c478bd9Sstevel@tonic-gate 			ASSERT(0);
17677c478bd9Sstevel@tonic-gate 		}
17687c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
17697c478bd9Sstevel@tonic-gate 			ASSERT(0);
17707c478bd9Sstevel@tonic-gate 		}
17717c478bd9Sstevel@tonic-gate 	}
17727c478bd9Sstevel@tonic-gate 	if (resbmap &
17737c478bd9Sstevel@tonic-gate 	    (FATTR4_QUOTA_USED_MASK |
17747c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_AVAIL_MASK |
17757c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_FREE_MASK |
17767c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_TOTAL_MASK |
17777c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_USED_MASK |
17787c478bd9Sstevel@tonic-gate 	    FATTR4_SYSTEM_MASK)) {
17797c478bd9Sstevel@tonic-gate 
17807c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
17817c478bd9Sstevel@tonic-gate 			ASSERT(0);
17827c478bd9Sstevel@tonic-gate 		}
17837c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RAWDEV_MASK) {
17847c478bd9Sstevel@tonic-gate 			fattr4_rawdev rawdev;
17857c478bd9Sstevel@tonic-gate 
17867c478bd9Sstevel@tonic-gate 			rawdev.specdata1 = IXDR_GET_U_INT32(ptr);
17877c478bd9Sstevel@tonic-gate 			rawdev.specdata2 = IXDR_GET_U_INT32(ptr);
17887c478bd9Sstevel@tonic-gate 
17897c478bd9Sstevel@tonic-gate 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
17907c478bd9Sstevel@tonic-gate 				vap->va_rdev = makedevice(rawdev.specdata1,
1791*0a701b1eSRobert Gordon 				    rawdev.specdata2);
17927c478bd9Sstevel@tonic-gate 			} else {
17937c478bd9Sstevel@tonic-gate 				vap->va_rdev = 0;
17947c478bd9Sstevel@tonic-gate 			}
17957c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_RDEV;
17967c478bd9Sstevel@tonic-gate 		}
17977c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
17987c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bavail);
17997c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
18007c478bd9Sstevel@tonic-gate 		}
18017c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
18027c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bfree);
18037c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
18047c478bd9Sstevel@tonic-gate 		}
18057c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
18067c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_blocks);
18077c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
18087c478bd9Sstevel@tonic-gate 		}
18097c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_USED_MASK) {
18107c478bd9Sstevel@tonic-gate 			uint64_t space_used;
18117c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, space_used);
18127c478bd9Sstevel@tonic-gate 
18137c478bd9Sstevel@tonic-gate 			/* Compute space depending on device type */
18147c478bd9Sstevel@tonic-gate 			ASSERT((vap->va_mask & AT_TYPE));
18157c478bd9Sstevel@tonic-gate 			if (vap->va_type == VREG || vap->va_type == VDIR ||
18167c478bd9Sstevel@tonic-gate 			    vap->va_type == VLNK) {
18177c478bd9Sstevel@tonic-gate 				vap->va_nblocks = (u_longlong_t)
1818*0a701b1eSRobert Gordon 				    ((space_used + (offset4)DEV_BSIZE -
1819*0a701b1eSRobert Gordon 				    (offset4)1) / (offset4)DEV_BSIZE);
18207c478bd9Sstevel@tonic-gate 			} else {
18217c478bd9Sstevel@tonic-gate 				vap->va_nblocks = 0;
18227c478bd9Sstevel@tonic-gate 			}
18237c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NBLOCKS;
18247c478bd9Sstevel@tonic-gate 		}
18257c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYSTEM_MASK) {
18267c478bd9Sstevel@tonic-gate 			ASSERT(0);
18277c478bd9Sstevel@tonic-gate 		}
18287c478bd9Sstevel@tonic-gate 	}
18297c478bd9Sstevel@tonic-gate 	if (resbmap &
18307c478bd9Sstevel@tonic-gate 	    (FATTR4_TIME_ACCESS_MASK |
18317c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_ACCESS_SET_MASK |
18327c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_BACKUP_MASK |
18337c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_CREATE_MASK |
18347c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_DELTA_MASK |
18357c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_METADATA_MASK |
18367c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_MASK |
18377c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_SET_MASK |
18387c478bd9Sstevel@tonic-gate 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
18397c478bd9Sstevel@tonic-gate 
18407c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
18417c478bd9Sstevel@tonic-gate 			nfstime4 atime;
18427c478bd9Sstevel@tonic-gate 			int error;
18437c478bd9Sstevel@tonic-gate 
18447c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, atime.seconds);
18457c478bd9Sstevel@tonic-gate 			atime.nseconds = IXDR_GET_U_INT32(ptr);
18467c478bd9Sstevel@tonic-gate 
18477c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&atime, &vap->va_atime);
18487c478bd9Sstevel@tonic-gate 			if (error) {
18497c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
18507c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
18517c478bd9Sstevel@tonic-gate 			}
18527c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_ATIME;
18537c478bd9Sstevel@tonic-gate 		}
18547c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
18557c478bd9Sstevel@tonic-gate 			ASSERT(0);
18567c478bd9Sstevel@tonic-gate 		}
18577c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
18587c478bd9Sstevel@tonic-gate 			ASSERT(0);
18597c478bd9Sstevel@tonic-gate 		}
18607c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
18617c478bd9Sstevel@tonic-gate 			ASSERT(0);
18627c478bd9Sstevel@tonic-gate 		}
18637c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
18647c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_delta.seconds);
18657c478bd9Sstevel@tonic-gate 			gesp->n4g_delta.nseconds = IXDR_GET_U_INT32(ptr);
18667c478bd9Sstevel@tonic-gate 		}
18677c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
18687c478bd9Sstevel@tonic-gate 			nfstime4 mdt;
18697c478bd9Sstevel@tonic-gate 			int error;
18707c478bd9Sstevel@tonic-gate 
18717c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, mdt.seconds);
18727c478bd9Sstevel@tonic-gate 			mdt.nseconds = IXDR_GET_U_INT32(ptr);
18737c478bd9Sstevel@tonic-gate 
18747c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
18757c478bd9Sstevel@tonic-gate 			if (error) {
18767c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
18777c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
18787c478bd9Sstevel@tonic-gate 			}
18797c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_CTIME;
18807c478bd9Sstevel@tonic-gate 		}
18817c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
18827c478bd9Sstevel@tonic-gate 			nfstime4 mtime;
18837c478bd9Sstevel@tonic-gate 			int error;
18847c478bd9Sstevel@tonic-gate 
18857c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, mtime.seconds);
18867c478bd9Sstevel@tonic-gate 			mtime.nseconds = IXDR_GET_U_INT32(ptr);
18877c478bd9Sstevel@tonic-gate 
18887c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
18897c478bd9Sstevel@tonic-gate 			if (error) {
18907c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
18917c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
18927c478bd9Sstevel@tonic-gate 			}
18937c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MTIME;
18947c478bd9Sstevel@tonic-gate 		}
18957c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
18967c478bd9Sstevel@tonic-gate 			ASSERT(0);
18977c478bd9Sstevel@tonic-gate 		}
18987c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
18997c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_mon_fid);
19007c478bd9Sstevel@tonic-gate 			garp->n4g_mon_fid_valid = 1;
19017c478bd9Sstevel@tonic-gate 		}
19027c478bd9Sstevel@tonic-gate 	}
19037c478bd9Sstevel@tonic-gate 
19047c478bd9Sstevel@tonic-gate 	/*
19057c478bd9Sstevel@tonic-gate 	 * FATTR4_ACL_MASK is not yet supported by this function, but
19067c478bd9Sstevel@tonic-gate 	 * we check against it anyway, in case it ever is.
19077c478bd9Sstevel@tonic-gate 	 */
19087c478bd9Sstevel@tonic-gate 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
19097c478bd9Sstevel@tonic-gate 		/* copy only if not provided */
19107c478bd9Sstevel@tonic-gate 		if (garp->n4g_ext_res == NULL) {
19117c478bd9Sstevel@tonic-gate 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
19127c478bd9Sstevel@tonic-gate 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
19137c478bd9Sstevel@tonic-gate 		}
19147c478bd9Sstevel@tonic-gate 	}
19157c478bd9Sstevel@tonic-gate 
19167c478bd9Sstevel@tonic-gate 	return (TRUE);
19177c478bd9Sstevel@tonic-gate }
19187c478bd9Sstevel@tonic-gate 
19197c478bd9Sstevel@tonic-gate 
19207c478bd9Sstevel@tonic-gate /*
19217c478bd9Sstevel@tonic-gate  * "." and ".." buffers for filling in on read and readdir
19227c478bd9Sstevel@tonic-gate  * calls. Intialize the first time and fill in on every
19237c478bd9Sstevel@tonic-gate  * call to to readdir.
19247c478bd9Sstevel@tonic-gate  */
19257c478bd9Sstevel@tonic-gate char	*nfs4_dot_entries;
19267c478bd9Sstevel@tonic-gate char	*nfs4_dot_dot_entry;
19277c478bd9Sstevel@tonic-gate 
19287c478bd9Sstevel@tonic-gate /*
19297c478bd9Sstevel@tonic-gate  * Create the "." or ".." and pad the buffer once so they are
19307c478bd9Sstevel@tonic-gate  * copied out as required into the user supplied buffer everytime.
19317c478bd9Sstevel@tonic-gate  * DIRENT64_RECLEN(sizeof (".") - 1) = DIRENT64_RECLEN(1)
19327c478bd9Sstevel@tonic-gate  * DIRENT64_RECLEN(sizeof ("..") - 1) = DIRENT64_RECLEN(2)
19337c478bd9Sstevel@tonic-gate  */
19347c478bd9Sstevel@tonic-gate void
19357c478bd9Sstevel@tonic-gate nfs4_init_dot_entries()
19367c478bd9Sstevel@tonic-gate {
19377c478bd9Sstevel@tonic-gate 	struct dirent64 *odp;
19387c478bd9Sstevel@tonic-gate 
19397c478bd9Sstevel@tonic-gate 	/*
19407c478bd9Sstevel@tonic-gate 	 * zalloc it so it zeros the buffer out. Need
19417c478bd9Sstevel@tonic-gate 	 * to just do it once.
19427c478bd9Sstevel@tonic-gate 	 */
19437c478bd9Sstevel@tonic-gate 	nfs4_dot_entries = kmem_zalloc(DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2),
19447c478bd9Sstevel@tonic-gate 	    KM_SLEEP);
19457c478bd9Sstevel@tonic-gate 
19467c478bd9Sstevel@tonic-gate 	odp = (struct dirent64 *)nfs4_dot_entries;
19477c478bd9Sstevel@tonic-gate 	odp->d_off = 1; /* magic cookie for "." entry */
19487c478bd9Sstevel@tonic-gate 	odp->d_reclen = DIRENT64_RECLEN(1);
19497c478bd9Sstevel@tonic-gate 	odp->d_name[0] = '.';
19507c478bd9Sstevel@tonic-gate 	odp->d_name[1] = '\0';
19517c478bd9Sstevel@tonic-gate 
19527c478bd9Sstevel@tonic-gate 	nfs4_dot_dot_entry = nfs4_dot_entries + DIRENT64_RECLEN(1);
19537c478bd9Sstevel@tonic-gate 	odp = (struct dirent64 *)nfs4_dot_dot_entry;
19547c478bd9Sstevel@tonic-gate 
19557c478bd9Sstevel@tonic-gate 	odp->d_off = 2;
19567c478bd9Sstevel@tonic-gate 	odp->d_reclen = DIRENT64_RECLEN(2);
19577c478bd9Sstevel@tonic-gate 	odp->d_name[0] = '.';
19587c478bd9Sstevel@tonic-gate 	odp->d_name[1] = '.';
19597c478bd9Sstevel@tonic-gate 	odp->d_name[2] = '\0';
19607c478bd9Sstevel@tonic-gate }
19617c478bd9Sstevel@tonic-gate 
19627c478bd9Sstevel@tonic-gate void
19637c478bd9Sstevel@tonic-gate nfs4_destroy_dot_entries()
19647c478bd9Sstevel@tonic-gate {
19657c478bd9Sstevel@tonic-gate 	if (nfs4_dot_entries)
19667c478bd9Sstevel@tonic-gate 		kmem_free(nfs4_dot_entries, DIRENT64_RECLEN(1) +
19677c478bd9Sstevel@tonic-gate 		    DIRENT64_RECLEN(2));
19687c478bd9Sstevel@tonic-gate 
19697c478bd9Sstevel@tonic-gate 	nfs4_dot_entries = nfs4_dot_dot_entry = NULL;
19707c478bd9Sstevel@tonic-gate }
19717c478bd9Sstevel@tonic-gate 
19727c478bd9Sstevel@tonic-gate bool_t
19737c478bd9Sstevel@tonic-gate xdr_READDIR4res_clnt(XDR *xdrs, READDIR4res_clnt *objp, READDIR4args *aobjp)
19747c478bd9Sstevel@tonic-gate {
19757c478bd9Sstevel@tonic-gate 	bool_t more_data;
19767c478bd9Sstevel@tonic-gate 	rddir4_cache *rdc = aobjp->rdc;
19777c478bd9Sstevel@tonic-gate 	dirent64_t *dp = NULL;
19787c478bd9Sstevel@tonic-gate 	int entry_length = 0;
19797c478bd9Sstevel@tonic-gate 	int space_left = 0;
19807c478bd9Sstevel@tonic-gate 	bitmap4 resbmap;
19817c478bd9Sstevel@tonic-gate 	uint32_t attrlen;
19827c478bd9Sstevel@tonic-gate 	nfs4_ga_res_t gar;
19837c478bd9Sstevel@tonic-gate 	struct nfs4_ga_ext_res ges;
19847c478bd9Sstevel@tonic-gate 	uint64_t last_cookie = 0;
19857c478bd9Sstevel@tonic-gate 	int skip_to_end;
19867c478bd9Sstevel@tonic-gate 	ug_cache_t *pug = NULL;
19877c478bd9Sstevel@tonic-gate 
19887c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
19897c478bd9Sstevel@tonic-gate 	ASSERT(rdc->entries == NULL);
19907c478bd9Sstevel@tonic-gate 	ASSERT(aobjp->dircount > 0);
19917c478bd9Sstevel@tonic-gate 
19927c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
19937c478bd9Sstevel@tonic-gate 		return (FALSE);
19947c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
19957c478bd9Sstevel@tonic-gate 		return (TRUE);
19967c478bd9Sstevel@tonic-gate 
19977c478bd9Sstevel@tonic-gate 	gar.n4g_va.va_mask = 0;
19987c478bd9Sstevel@tonic-gate 	gar.n4g_change_valid = 0;
19997c478bd9Sstevel@tonic-gate 	gar.n4g_mon_fid_valid = 0;
20007c478bd9Sstevel@tonic-gate 	gar.n4g_fsid_valid = 0;
20017c478bd9Sstevel@tonic-gate 	gar.n4g_vsa.vsa_mask = 0;
20027c478bd9Sstevel@tonic-gate 	gar.n4g_attrwhy = NFS4_GETATTR_OP_OK;
20037c478bd9Sstevel@tonic-gate 	ges.n4g_pc4.pc4_cache_valid = 0;
20047c478bd9Sstevel@tonic-gate 	ges.n4g_pc4.pc4_xattr_valid = 0;
20057c478bd9Sstevel@tonic-gate 	gar.n4g_ext_res = &ges;
20067c478bd9Sstevel@tonic-gate 
20077c478bd9Sstevel@tonic-gate 	/* READDIR4res_clnt_free needs to kmem_free this buffer */
20087c478bd9Sstevel@tonic-gate 	rdc->entries = kmem_alloc(aobjp->dircount, KM_SLEEP);
20097c478bd9Sstevel@tonic-gate 
20107c478bd9Sstevel@tonic-gate 	dp = (dirent64_t *)rdc->entries;
20117c478bd9Sstevel@tonic-gate 	rdc->entlen = rdc->buflen = space_left = aobjp->dircount;
20127c478bd9Sstevel@tonic-gate 
20137c478bd9Sstevel@tonic-gate 	/* Fill in dot and dot-dot if needed */
20147c478bd9Sstevel@tonic-gate 	if (rdc->nfs4_cookie == (nfs_cookie4) 0 ||
2015*0a701b1eSRobert Gordon 	    rdc->nfs4_cookie == (nfs_cookie4) 1) {
20167c478bd9Sstevel@tonic-gate 
20177c478bd9Sstevel@tonic-gate 		if (rdc->nfs4_cookie == (nfs_cookie4)0) {
20187c478bd9Sstevel@tonic-gate 			bcopy(nfs4_dot_entries, rdc->entries,
2019*0a701b1eSRobert Gordon 			    DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2));
20207c478bd9Sstevel@tonic-gate 			objp->dotp = dp;
20217c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((char *)dp) +
2022*0a701b1eSRobert Gordon 			    DIRENT64_RECLEN(1));
20237c478bd9Sstevel@tonic-gate 			objp->dotdotp = dp;
20247c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((char *)dp) +
2025*0a701b1eSRobert Gordon 			    DIRENT64_RECLEN(2));
20267c478bd9Sstevel@tonic-gate 			space_left -= DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2);
20277c478bd9Sstevel@tonic-gate 
20287c478bd9Sstevel@tonic-gate 		} else	{	/* for ".." entry */
20297c478bd9Sstevel@tonic-gate 			bcopy(nfs4_dot_dot_entry, rdc->entries,
2030*0a701b1eSRobert Gordon 			    DIRENT64_RECLEN(2));
20317c478bd9Sstevel@tonic-gate 			objp->dotp = NULL;
20327c478bd9Sstevel@tonic-gate 			objp->dotdotp = dp;
20337c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((char *)dp) +
2034*0a701b1eSRobert Gordon 			    DIRENT64_RECLEN(2));
20357c478bd9Sstevel@tonic-gate 			space_left -= DIRENT64_RECLEN(2);
20367c478bd9Sstevel@tonic-gate 		}
20377c478bd9Sstevel@tonic-gate 		/* Magic NFSv4 number for entry after start */
20387c478bd9Sstevel@tonic-gate 		last_cookie = 2;
20397c478bd9Sstevel@tonic-gate 	}
20407c478bd9Sstevel@tonic-gate 
20417c478bd9Sstevel@tonic-gate 	/* Get the cookie VERIFIER */
20427c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
20437c478bd9Sstevel@tonic-gate 		goto noentries;
20447c478bd9Sstevel@tonic-gate 
20457c478bd9Sstevel@tonic-gate 	/* Get the do-we-have-a-next-entry BOOL */
20467c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &more_data))
20477c478bd9Sstevel@tonic-gate 		goto noentries;
20487c478bd9Sstevel@tonic-gate 
20497c478bd9Sstevel@tonic-gate 	if (aobjp->attr_request & (FATTR4_OWNER_MASK | FATTR4_OWNER_GROUP_MASK))
20507c478bd9Sstevel@tonic-gate 		pug = alloc_ugcache();
20517c478bd9Sstevel@tonic-gate 
20527c478bd9Sstevel@tonic-gate 	skip_to_end = 0;
20537c478bd9Sstevel@tonic-gate 	while (more_data) {
20547c478bd9Sstevel@tonic-gate 		uint_t namelen;
20557c478bd9Sstevel@tonic-gate 		uint64_t cookie;
20567c478bd9Sstevel@tonic-gate 
20577c478bd9Sstevel@tonic-gate 		/* Get the COOKIE */
20587c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&cookie))
20597c478bd9Sstevel@tonic-gate 			goto noentries;
20607c478bd9Sstevel@tonic-gate 
20617c478bd9Sstevel@tonic-gate 		/* Get the LENGTH of the entry name */
20627c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &namelen))
20637c478bd9Sstevel@tonic-gate 			goto noentries;
20647c478bd9Sstevel@tonic-gate 
20657c478bd9Sstevel@tonic-gate 		if (!skip_to_end) {
20667c478bd9Sstevel@tonic-gate 			/*
20677c478bd9Sstevel@tonic-gate 			 * With the length of the directory entry name
20687c478bd9Sstevel@tonic-gate 			 * in hand, figure out if there is room left
20697c478bd9Sstevel@tonic-gate 			 * to encode it for the requestor.  If not,
20707c478bd9Sstevel@tonic-gate 			 * that is okay, but the rest of the readdir
20717c478bd9Sstevel@tonic-gate 			 * operation result must be decoded in the
20727c478bd9Sstevel@tonic-gate 			 * case there are following operations
20737c478bd9Sstevel@tonic-gate 			 * in the compound request.  Therefore, mark
20747c478bd9Sstevel@tonic-gate 			 * the rest of the response as "skip" and
20757c478bd9Sstevel@tonic-gate 			 * decode or skip the remaining data
20767c478bd9Sstevel@tonic-gate 			 */
20777c478bd9Sstevel@tonic-gate 			entry_length = DIRENT64_RECLEN(namelen);
20787c478bd9Sstevel@tonic-gate 			if (space_left < entry_length)
20797c478bd9Sstevel@tonic-gate 				skip_to_end = 1;
20807c478bd9Sstevel@tonic-gate 		}
20817c478bd9Sstevel@tonic-gate 
20827c478bd9Sstevel@tonic-gate 		/* Get the NAME of the entry */
20837c478bd9Sstevel@tonic-gate 		if (!skip_to_end) {
20847c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, dp->d_name, namelen))
20857c478bd9Sstevel@tonic-gate 				goto noentries;
20867c478bd9Sstevel@tonic-gate 			bzero(&dp->d_name[namelen],
2087*0a701b1eSRobert Gordon 			    DIRENT64_NAMELEN(entry_length) - namelen);
20887c478bd9Sstevel@tonic-gate 			dp->d_off = last_cookie = cookie;
20897c478bd9Sstevel@tonic-gate 			dp->d_reclen = entry_length;
20907c478bd9Sstevel@tonic-gate 		} else {
20917c478bd9Sstevel@tonic-gate 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &namelen))
20927c478bd9Sstevel@tonic-gate 				goto noentries;
20937c478bd9Sstevel@tonic-gate 		}
20947c478bd9Sstevel@tonic-gate 
20957c478bd9Sstevel@tonic-gate 		/* Get the attribute BITMAP */
20967c478bd9Sstevel@tonic-gate 		if (!xdr_bitmap4(xdrs, &resbmap))
20977c478bd9Sstevel@tonic-gate 			goto noentries;
20987c478bd9Sstevel@tonic-gate 		/* Get the LENGTH of the attributes */
20997c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, (uint_t *)&attrlen))
21007c478bd9Sstevel@tonic-gate 			goto noentries;
21017c478bd9Sstevel@tonic-gate 
21027c478bd9Sstevel@tonic-gate 		/* Get the ATTRIBUTES */
21037c478bd9Sstevel@tonic-gate 		if (!skip_to_end) {
21047c478bd9Sstevel@tonic-gate 			uint32_t *ptr;
21057c478bd9Sstevel@tonic-gate 
21067c478bd9Sstevel@tonic-gate 			if (!(resbmap & FATTR4_ACL_MASK) &&
21077c478bd9Sstevel@tonic-gate 			    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen))
21087c478bd9Sstevel@tonic-gate 			    != NULL) {
21097c478bd9Sstevel@tonic-gate 				if (!xdr_ga_fattr_res_inline(ptr, &gar, resbmap,
2110*0a701b1eSRobert Gordon 				    aobjp->attr_request, aobjp->mi, pug))
21117c478bd9Sstevel@tonic-gate 					goto noentries;
21127c478bd9Sstevel@tonic-gate 			} else {
21137c478bd9Sstevel@tonic-gate 				if (!xdr_ga_fattr_res(xdrs, &gar, resbmap,
2114*0a701b1eSRobert Gordon 				    aobjp->attr_request, aobjp->mi, pug))
21157c478bd9Sstevel@tonic-gate 					goto noentries;
21167c478bd9Sstevel@tonic-gate 			}
21177c478bd9Sstevel@tonic-gate 
21187c478bd9Sstevel@tonic-gate 			/* Fill in the d_ino per the server's fid values */
21197c478bd9Sstevel@tonic-gate 			/*
21207c478bd9Sstevel@tonic-gate 			 * Important to note that the mounted on fileid
21217c478bd9Sstevel@tonic-gate 			 * is returned in d_ino if supported.  This is
21227c478bd9Sstevel@tonic-gate 			 * expected, readdir returns the mounted on fileid
21237c478bd9Sstevel@tonic-gate 			 * while stat() returns the fileid of the object
21247c478bd9Sstevel@tonic-gate 			 * on "top" of the mount.
21257c478bd9Sstevel@tonic-gate 			 */
21267c478bd9Sstevel@tonic-gate 			if (gar.n4g_mon_fid_valid)
21277c478bd9Sstevel@tonic-gate 				dp->d_ino = gar.n4g_mon_fid;
21287c478bd9Sstevel@tonic-gate 			else if (gar.n4g_va.va_mask & AT_NODEID)
21297c478bd9Sstevel@tonic-gate 				dp->d_ino = gar.n4g_va.va_nodeid;
21307c478bd9Sstevel@tonic-gate 			else
21317c478bd9Sstevel@tonic-gate 				dp->d_ino = 0;
21327c478bd9Sstevel@tonic-gate 
21337c478bd9Sstevel@tonic-gate 			/* See about creating an rnode for this entry */
21347c478bd9Sstevel@tonic-gate 			if ((resbmap &
21357c478bd9Sstevel@tonic-gate 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) ==
21367c478bd9Sstevel@tonic-gate 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) {
21377c478bd9Sstevel@tonic-gate 				nfs4_sharedfh_t *sfhp;
21387c478bd9Sstevel@tonic-gate 				vnode_t *vp;
21397c478bd9Sstevel@tonic-gate 
21407c478bd9Sstevel@tonic-gate 				sfhp = sfh4_put(&ges.n4g_fh_u.n4g_fh,
2141*0a701b1eSRobert Gordon 				    aobjp->mi, NULL);
21427c478bd9Sstevel@tonic-gate 				vp = makenfs4node(sfhp, &gar,
2143*0a701b1eSRobert Gordon 				    aobjp->dvp->v_vfsp,
2144*0a701b1eSRobert Gordon 				    aobjp->t,
2145*0a701b1eSRobert Gordon 				    aobjp->cr,
2146*0a701b1eSRobert Gordon 				    aobjp->dvp,
2147*0a701b1eSRobert Gordon 				    fn_get(VTOSV(aobjp->dvp)->sv_name,
2148*0a701b1eSRobert Gordon 				    dp->d_name));
21497c478bd9Sstevel@tonic-gate 				sfh4_rele(&sfhp);
21507c478bd9Sstevel@tonic-gate 				dnlc_update(aobjp->dvp, dp->d_name, vp);
21517c478bd9Sstevel@tonic-gate 				VN_RELE(vp);
21527c478bd9Sstevel@tonic-gate 			}
21537c478bd9Sstevel@tonic-gate 
21547c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((caddr_t)dp) + dp->d_reclen);
21557c478bd9Sstevel@tonic-gate 
21567c478bd9Sstevel@tonic-gate 			space_left -= entry_length;
21577c478bd9Sstevel@tonic-gate 
21587c478bd9Sstevel@tonic-gate 		} else {
21597c478bd9Sstevel@tonic-gate 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &attrlen))
21607c478bd9Sstevel@tonic-gate 				goto noentries;
21617c478bd9Sstevel@tonic-gate 		}
21627c478bd9Sstevel@tonic-gate 
21637c478bd9Sstevel@tonic-gate 		/* Get the do-we-have-a-next-entry BOOL */
21647c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &more_data))
21657c478bd9Sstevel@tonic-gate 			goto noentries;
21667c478bd9Sstevel@tonic-gate 	}
21677c478bd9Sstevel@tonic-gate 
21687c478bd9Sstevel@tonic-gate 	if (pug) {
21697c478bd9Sstevel@tonic-gate 		kmem_free(pug, sizeof (ug_cache_t));
21707c478bd9Sstevel@tonic-gate 		pug = NULL;
21717c478bd9Sstevel@tonic-gate 	}
21727c478bd9Sstevel@tonic-gate 
21737c478bd9Sstevel@tonic-gate 	/*
21747c478bd9Sstevel@tonic-gate 	 * Finish up the rddir cache
21757c478bd9Sstevel@tonic-gate 	 * If no entries were returned, free up buffer &
21767c478bd9Sstevel@tonic-gate 	 * set ncookie to the starting cookie for this
21777c478bd9Sstevel@tonic-gate 	 * readdir request so that the direof caching
21787c478bd9Sstevel@tonic-gate 	 * will work properly.
21797c478bd9Sstevel@tonic-gate 	 */
21807c478bd9Sstevel@tonic-gate 	ASSERT(rdc->entries);
21817c478bd9Sstevel@tonic-gate 	if (last_cookie == 0) {
21827c478bd9Sstevel@tonic-gate 		kmem_free(rdc->entries, rdc->entlen);
21837c478bd9Sstevel@tonic-gate 		rdc->entries = NULL;
21847c478bd9Sstevel@tonic-gate 		last_cookie = rdc->nfs4_cookie;
21857c478bd9Sstevel@tonic-gate 	}
21867c478bd9Sstevel@tonic-gate 
21877c478bd9Sstevel@tonic-gate 	rdc->actlen = rdc->entlen - space_left;
21887c478bd9Sstevel@tonic-gate 	rdc->nfs4_ncookie = last_cookie;
21897c478bd9Sstevel@tonic-gate 
21907c478bd9Sstevel@tonic-gate 	/* Get the EOF marker */
21917c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->eof))
21927c478bd9Sstevel@tonic-gate 		goto noentries;
21937c478bd9Sstevel@tonic-gate 
21947c478bd9Sstevel@tonic-gate 	/*
21957c478bd9Sstevel@tonic-gate 	 * If the server returns eof and there were no
21967c478bd9Sstevel@tonic-gate 	 * skipped entries, set eof
21977c478bd9Sstevel@tonic-gate 	 */
21987c478bd9Sstevel@tonic-gate 	rdc->eof = (objp->eof && !skip_to_end) ? TRUE : FALSE;
21997c478bd9Sstevel@tonic-gate 
22007c478bd9Sstevel@tonic-gate 	/*
22017c478bd9Sstevel@tonic-gate 	 * If we encoded entries we are done
22027c478bd9Sstevel@tonic-gate 	 */
22037c478bd9Sstevel@tonic-gate 	if (rdc->entries) {
22047c478bd9Sstevel@tonic-gate 		rdc->error = 0;
22057c478bd9Sstevel@tonic-gate 		return (TRUE);
22067c478bd9Sstevel@tonic-gate 	}
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate 	/*
22097c478bd9Sstevel@tonic-gate 	 * If there were no entries and we skipped because
22107c478bd9Sstevel@tonic-gate 	 * there was not enough space, return EINVAL
22117c478bd9Sstevel@tonic-gate 	 */
22127c478bd9Sstevel@tonic-gate 	if (skip_to_end) {
22137c478bd9Sstevel@tonic-gate 		rdc->error = EINVAL;
22147c478bd9Sstevel@tonic-gate 		return (TRUE);
22157c478bd9Sstevel@tonic-gate 	}
22167c478bd9Sstevel@tonic-gate 
22177c478bd9Sstevel@tonic-gate 	/*
22187c478bd9Sstevel@tonic-gate 	 * No entries, nothing skipped, and EOF, return OK.
22197c478bd9Sstevel@tonic-gate 	 */
22207c478bd9Sstevel@tonic-gate 	if (objp->eof == TRUE) {
22217c478bd9Sstevel@tonic-gate 		rdc->error = 0;
22227c478bd9Sstevel@tonic-gate 		return (TRUE);
22237c478bd9Sstevel@tonic-gate 	}
22247c478bd9Sstevel@tonic-gate 
22257c478bd9Sstevel@tonic-gate 	/*
22267c478bd9Sstevel@tonic-gate 	 * No entries, nothing skipped, and not EOF
22277c478bd9Sstevel@tonic-gate 	 * probably a bad cookie, return ENOENT.
22287c478bd9Sstevel@tonic-gate 	 */
22297c478bd9Sstevel@tonic-gate 	rdc->error = ENOENT;
22307c478bd9Sstevel@tonic-gate 	return (TRUE);
22317c478bd9Sstevel@tonic-gate 
22327c478bd9Sstevel@tonic-gate noentries:
22337c478bd9Sstevel@tonic-gate 	if (rdc->entries) {
22347c478bd9Sstevel@tonic-gate 		kmem_free(rdc->entries, rdc->entlen);
22357c478bd9Sstevel@tonic-gate 		rdc->entries = NULL;
22367c478bd9Sstevel@tonic-gate 	}
22377c478bd9Sstevel@tonic-gate 	if (pug)
22387c478bd9Sstevel@tonic-gate 		kmem_free(pug, sizeof (ug_cache_t));
22397c478bd9Sstevel@tonic-gate 	rdc->error = EIO;
22407c478bd9Sstevel@tonic-gate 	return (FALSE);
22417c478bd9Sstevel@tonic-gate }
22427c478bd9Sstevel@tonic-gate 
22437c478bd9Sstevel@tonic-gate /*
22447c478bd9Sstevel@tonic-gate  * xdr_ga_res
22457c478bd9Sstevel@tonic-gate  *
22467c478bd9Sstevel@tonic-gate  * Returns: FALSE on raw data processing errors, TRUE otherwise.
22477c478bd9Sstevel@tonic-gate  *
22487c478bd9Sstevel@tonic-gate  * This function pre-processes the OP_GETATTR response, and then
22497c478bd9Sstevel@tonic-gate  * calls common routines to process the GETATTR fattr4 results into
22507c478bd9Sstevel@tonic-gate  * vnode attributes and other components that the client is interested
22517c478bd9Sstevel@tonic-gate  * in. If an error other than an RPC error is encountered, the details
22527c478bd9Sstevel@tonic-gate  * of the error are filled into objp, although the result of the
22537c478bd9Sstevel@tonic-gate  * processing is set to TRUE.
22547c478bd9Sstevel@tonic-gate  */
22557c478bd9Sstevel@tonic-gate static bool_t
22567c478bd9Sstevel@tonic-gate xdr_ga_res(XDR *xdrs, GETATTR4res *objp, GETATTR4args *aobjp)
22577c478bd9Sstevel@tonic-gate {
22587c478bd9Sstevel@tonic-gate 	uint32_t *ptr;
22597c478bd9Sstevel@tonic-gate 	bitmap4 resbmap;
22607c478bd9Sstevel@tonic-gate 	uint32_t attrlen;
22617c478bd9Sstevel@tonic-gate 
22627c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
22637c478bd9Sstevel@tonic-gate 
22647c478bd9Sstevel@tonic-gate 	/* Initialize objp attribute error values */
22657c478bd9Sstevel@tonic-gate 	objp->ga_res.n4g_attrerr =
2266*0a701b1eSRobert Gordon 	    objp->ga_res.n4g_attrwhy = NFS4_GETATTR_OP_OK;
22677c478bd9Sstevel@tonic-gate 
22687c478bd9Sstevel@tonic-gate 	if (!xdr_bitmap4(xdrs, &resbmap))
22697c478bd9Sstevel@tonic-gate 		return (FALSE);
22707c478bd9Sstevel@tonic-gate 
22717c478bd9Sstevel@tonic-gate 	/* save the response bitmap for the caller */
22727c478bd9Sstevel@tonic-gate 	objp->ga_res.n4g_resbmap = resbmap;
22737c478bd9Sstevel@tonic-gate 
22747c478bd9Sstevel@tonic-gate 	/* attrlen */
22757c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&attrlen))
22767c478bd9Sstevel@tonic-gate 		return (FALSE);
22777c478bd9Sstevel@tonic-gate 
22787c478bd9Sstevel@tonic-gate 	/*
22797c478bd9Sstevel@tonic-gate 	 * Handle case where request and response bitmaps don't match.
22807c478bd9Sstevel@tonic-gate 	 */
22817c478bd9Sstevel@tonic-gate 	if (aobjp->attr_request && aobjp->attr_request != resbmap) {
22827c478bd9Sstevel@tonic-gate 		bitmap4 deltabmap;
22837c478bd9Sstevel@tonic-gate 
22847c478bd9Sstevel@tonic-gate 		/*
22857c478bd9Sstevel@tonic-gate 		 * Return error for case where server sent extra attributes
22867c478bd9Sstevel@tonic-gate 		 * because the "unknown" attributes may be anywhere in the
22877c478bd9Sstevel@tonic-gate 		 * xdr stream and can't be properly processed.
22887c478bd9Sstevel@tonic-gate 		 */
22897c478bd9Sstevel@tonic-gate 		deltabmap = ((aobjp->attr_request ^ resbmap) & resbmap);
22907c478bd9Sstevel@tonic-gate 		if (deltabmap) {
22917c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrerr = EINVAL;
22927c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_BITMAP_ERR;
22937c478bd9Sstevel@tonic-gate 			return (TRUE);
22947c478bd9Sstevel@tonic-gate 		}
22957c478bd9Sstevel@tonic-gate 
22967c478bd9Sstevel@tonic-gate 		/*
22977c478bd9Sstevel@tonic-gate 		 * Return error for case where there is a mandatory
22987c478bd9Sstevel@tonic-gate 		 * attribute missing in the server response. Note that
22997c478bd9Sstevel@tonic-gate 		 * missing recommended attributes are evaluated in the
23007c478bd9Sstevel@tonic-gate 		 * specific routines that decode the server response.
23017c478bd9Sstevel@tonic-gate 		 */
23027c478bd9Sstevel@tonic-gate 		deltabmap = ((aobjp->attr_request ^ resbmap)
2303*0a701b1eSRobert Gordon 		    & aobjp->attr_request);
23047c478bd9Sstevel@tonic-gate 		if ((deltabmap & FATTR4_MANDATTR_MASK)) {
23057c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrerr = EINVAL;
23067c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_MANDATTR_ERR;
23077c478bd9Sstevel@tonic-gate 			return (TRUE);
23087c478bd9Sstevel@tonic-gate 		}
23097c478bd9Sstevel@tonic-gate 	}
23107c478bd9Sstevel@tonic-gate 
23117c478bd9Sstevel@tonic-gate 	/* Check to see if the attrs can be inlined and go for it if so */
23127c478bd9Sstevel@tonic-gate 	if (!(resbmap & FATTR4_ACL_MASK) &&
23137c478bd9Sstevel@tonic-gate 	    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen)) != NULL)
23147c478bd9Sstevel@tonic-gate 		return (xdr_ga_fattr_res_inline(ptr, &objp->ga_res,
2315*0a701b1eSRobert Gordon 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
23167c478bd9Sstevel@tonic-gate 	else
23177c478bd9Sstevel@tonic-gate 		return (xdr_ga_fattr_res(xdrs, &objp->ga_res,
2318*0a701b1eSRobert Gordon 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
23197c478bd9Sstevel@tonic-gate }
23207c478bd9Sstevel@tonic-gate 
23217c478bd9Sstevel@tonic-gate #if defined(DEBUG) && !defined(lint)
23227c478bd9Sstevel@tonic-gate /*
23237c478bd9Sstevel@tonic-gate  * We assume that an enum is a 32-bit value, check it once
23247c478bd9Sstevel@tonic-gate  */
23257c478bd9Sstevel@tonic-gate static enum szchk { SZVAL } szchkvar;
23267c478bd9Sstevel@tonic-gate #endif
23277c478bd9Sstevel@tonic-gate 
23287c478bd9Sstevel@tonic-gate bool_t
23297c478bd9Sstevel@tonic-gate xdr_settime4(XDR *xdrs, settime4 *objp)
23307c478bd9Sstevel@tonic-gate {
23317c478bd9Sstevel@tonic-gate #if defined(DEBUG) && !defined(lint)
23327c478bd9Sstevel@tonic-gate 	ASSERT(sizeof (szchkvar) == sizeof (int32_t));
23337c478bd9Sstevel@tonic-gate #endif
23347c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
23357c478bd9Sstevel@tonic-gate 		return (TRUE);
23367c478bd9Sstevel@tonic-gate 
23377c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->set_it))
23387c478bd9Sstevel@tonic-gate 		return (FALSE);
23397c478bd9Sstevel@tonic-gate 	if (objp->set_it != SET_TO_CLIENT_TIME4)
23407c478bd9Sstevel@tonic-gate 		return (TRUE);
23417c478bd9Sstevel@tonic-gate 	/* xdr_nfstime4 */
23427c478bd9Sstevel@tonic-gate 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->time.seconds))
23437c478bd9Sstevel@tonic-gate 		return (FALSE);
23447c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->time.nseconds));
23457c478bd9Sstevel@tonic-gate }
23467c478bd9Sstevel@tonic-gate 
23477c478bd9Sstevel@tonic-gate static bool_t
23487c478bd9Sstevel@tonic-gate xdr_fattr4(XDR *xdrs, fattr4 *objp)
23497c478bd9Sstevel@tonic-gate {
23507c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
23517c478bd9Sstevel@tonic-gate 		if (!xdr_bitmap4(xdrs, &objp->attrmask))
23527c478bd9Sstevel@tonic-gate 			return (FALSE);
23537c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->attrlist4,
2354*0a701b1eSRobert Gordon 		    (uint_t *)&objp->attrlist4_len, NFS4_FATTR4_LIMIT));
23557c478bd9Sstevel@tonic-gate 	}
23567c478bd9Sstevel@tonic-gate 
23577c478bd9Sstevel@tonic-gate 	/*
23587c478bd9Sstevel@tonic-gate 	 * Optimized free case
23597c478bd9Sstevel@tonic-gate 	 */
23607c478bd9Sstevel@tonic-gate 	if (objp->attrlist4 != NULL)
23617c478bd9Sstevel@tonic-gate 		kmem_free(objp->attrlist4, objp->attrlist4_len);
23627c478bd9Sstevel@tonic-gate 	return (TRUE);
23637c478bd9Sstevel@tonic-gate }
23647c478bd9Sstevel@tonic-gate 
23657c478bd9Sstevel@tonic-gate static bool_t
23667c478bd9Sstevel@tonic-gate xdr_ACCESS4res(XDR *xdrs, ACCESS4res *objp)
23677c478bd9Sstevel@tonic-gate {
23687c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
23697c478bd9Sstevel@tonic-gate 		return (FALSE);
23707c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
23717c478bd9Sstevel@tonic-gate 		return (TRUE);
23727c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->supported))
23737c478bd9Sstevel@tonic-gate 		return (FALSE);
23747c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->access));
23757c478bd9Sstevel@tonic-gate }
23767c478bd9Sstevel@tonic-gate 
23777c478bd9Sstevel@tonic-gate static bool_t
23787c478bd9Sstevel@tonic-gate xdr_CLOSE4args(XDR *xdrs, CLOSE4args *objp)
23797c478bd9Sstevel@tonic-gate {
23807c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->seqid))
23817c478bd9Sstevel@tonic-gate 		return (FALSE);
23827c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
23837c478bd9Sstevel@tonic-gate 		return (FALSE);
23847c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
23857c478bd9Sstevel@tonic-gate }
23867c478bd9Sstevel@tonic-gate 
23877c478bd9Sstevel@tonic-gate static bool_t
23887c478bd9Sstevel@tonic-gate xdr_CLOSE4res(XDR *xdrs, CLOSE4res *objp)
23897c478bd9Sstevel@tonic-gate {
23907c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
23917c478bd9Sstevel@tonic-gate 		return (FALSE);
23927c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
23937c478bd9Sstevel@tonic-gate 		return (TRUE);
23947c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
23957c478bd9Sstevel@tonic-gate 		return (FALSE);
23967c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
23977c478bd9Sstevel@tonic-gate }
23987c478bd9Sstevel@tonic-gate 
23997c478bd9Sstevel@tonic-gate static bool_t
24007c478bd9Sstevel@tonic-gate xdr_CREATE4args(XDR *xdrs, CREATE4args *objp)
24017c478bd9Sstevel@tonic-gate {
24027c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
24037c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->type))
24047c478bd9Sstevel@tonic-gate 			return (FALSE);
24057c478bd9Sstevel@tonic-gate 		switch (objp->type) {
24067c478bd9Sstevel@tonic-gate 		case NF4LNK:
24077c478bd9Sstevel@tonic-gate 			if (!xdr_bytes(xdrs,
24087c478bd9Sstevel@tonic-gate 			    (char **)&objp->ftype4_u.linkdata.utf8string_val,
24097c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->ftype4_u.linkdata.utf8string_len,
24107c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING))
24117c478bd9Sstevel@tonic-gate 				return (FALSE);
24127c478bd9Sstevel@tonic-gate 			break;
24137c478bd9Sstevel@tonic-gate 		case NF4BLK:
24147c478bd9Sstevel@tonic-gate 		case NF4CHR:
24157c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata1))
24167c478bd9Sstevel@tonic-gate 				return (FALSE);
24177c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata2))
24187c478bd9Sstevel@tonic-gate 				return (FALSE);
24197c478bd9Sstevel@tonic-gate 			break;
24207c478bd9Sstevel@tonic-gate 		case NF4SOCK:
24217c478bd9Sstevel@tonic-gate 		case NF4FIFO:
24227c478bd9Sstevel@tonic-gate 		case NF4DIR:
24237c478bd9Sstevel@tonic-gate 		default:
24247c478bd9Sstevel@tonic-gate 			break;	/* server should return NFS4ERR_BADTYPE */
24257c478bd9Sstevel@tonic-gate 		}
24267c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->objname.utf8string_val,
2427*0a701b1eSRobert Gordon 		    (uint_t *)&objp->objname.utf8string_len,
2428*0a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING))
24297c478bd9Sstevel@tonic-gate 			return (FALSE);
24307c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs, &objp->createattrs));
24317c478bd9Sstevel@tonic-gate 	}
24327c478bd9Sstevel@tonic-gate 
24337c478bd9Sstevel@tonic-gate 	/*
24347c478bd9Sstevel@tonic-gate 	 * Optimized free case
24357c478bd9Sstevel@tonic-gate 	 */
24367c478bd9Sstevel@tonic-gate 	if (objp->type == NF4LNK) {
24377c478bd9Sstevel@tonic-gate 		if (objp->ftype4_u.linkdata.utf8string_val != NULL)
24387c478bd9Sstevel@tonic-gate 			kmem_free(objp->ftype4_u.linkdata.utf8string_val,
2439*0a701b1eSRobert Gordon 			    objp->ftype4_u.linkdata.utf8string_len);
24407c478bd9Sstevel@tonic-gate 	}
24417c478bd9Sstevel@tonic-gate 	if (objp->objname.utf8string_val != NULL)
24427c478bd9Sstevel@tonic-gate 		kmem_free(objp->objname.utf8string_val,
2443*0a701b1eSRobert Gordon 		    objp->objname.utf8string_len);
24447c478bd9Sstevel@tonic-gate 	return (xdr_fattr4(xdrs, &objp->createattrs));
24457c478bd9Sstevel@tonic-gate }
24467c478bd9Sstevel@tonic-gate 
24477c478bd9Sstevel@tonic-gate static bool_t
24487c478bd9Sstevel@tonic-gate xdr_CREATE4cargs(XDR *xdrs, CREATE4cargs *objp)
24497c478bd9Sstevel@tonic-gate {
24507c478bd9Sstevel@tonic-gate 	int len;
24517c478bd9Sstevel@tonic-gate 
24527c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
24537c478bd9Sstevel@tonic-gate 
24547c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->type))
24557c478bd9Sstevel@tonic-gate 		return (FALSE);
24567c478bd9Sstevel@tonic-gate 	switch (objp->type) {
24577c478bd9Sstevel@tonic-gate 	case NF4LNK:
24587c478bd9Sstevel@tonic-gate 		len = strlen(objp->ftype4_u.clinkdata);
24597c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
24607c478bd9Sstevel@tonic-gate 			return (FALSE);
24617c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len))
24627c478bd9Sstevel@tonic-gate 			return (FALSE);
24637c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->ftype4_u.clinkdata, len))
24647c478bd9Sstevel@tonic-gate 			return (FALSE);
24657c478bd9Sstevel@tonic-gate 		break;
24667c478bd9Sstevel@tonic-gate 	case NF4BLK:
24677c478bd9Sstevel@tonic-gate 	case NF4CHR:
24687c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs,
2469*0a701b1eSRobert Gordon 		    (int32_t *)&objp->ftype4_u.devdata.specdata1))
24707c478bd9Sstevel@tonic-gate 			return (FALSE);
24717c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs,
2472*0a701b1eSRobert Gordon 		    (int32_t *)&objp->ftype4_u.devdata.specdata2))
24737c478bd9Sstevel@tonic-gate 			return (FALSE);
24747c478bd9Sstevel@tonic-gate 		break;
24757c478bd9Sstevel@tonic-gate 	case NF4SOCK:
24767c478bd9Sstevel@tonic-gate 	case NF4FIFO:
24777c478bd9Sstevel@tonic-gate 	case NF4DIR:
24787c478bd9Sstevel@tonic-gate 	default:
24797c478bd9Sstevel@tonic-gate 		break;	/* server should return NFS4ERR_BADTYPE */
24807c478bd9Sstevel@tonic-gate 	}
24817c478bd9Sstevel@tonic-gate 
24827c478bd9Sstevel@tonic-gate 	len = strlen(objp->cname);
24837c478bd9Sstevel@tonic-gate 	if (len > NFS4_MAX_UTF8STRING)
24847c478bd9Sstevel@tonic-gate 		return (FALSE);
24857c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, &len))
24867c478bd9Sstevel@tonic-gate 		return (FALSE);
24877c478bd9Sstevel@tonic-gate 	if (!xdr_opaque(xdrs, objp->cname, len))
24887c478bd9Sstevel@tonic-gate 		return (FALSE);
24897c478bd9Sstevel@tonic-gate 
24907c478bd9Sstevel@tonic-gate 	return (xdr_fattr4(xdrs, &objp->createattrs));
24917c478bd9Sstevel@tonic-gate }
24927c478bd9Sstevel@tonic-gate 
24937c478bd9Sstevel@tonic-gate static bool_t
24947c478bd9Sstevel@tonic-gate xdr_CREATE4res(XDR *xdrs, CREATE4res *objp)
24957c478bd9Sstevel@tonic-gate {
24967c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
24977c478bd9Sstevel@tonic-gate 		return (FALSE);
24987c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
24997c478bd9Sstevel@tonic-gate 		return (TRUE);
25007c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
25017c478bd9Sstevel@tonic-gate 		return (FALSE);
25027c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
25037c478bd9Sstevel@tonic-gate 		return (FALSE);
25047c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
25057c478bd9Sstevel@tonic-gate 		return (FALSE);
25067c478bd9Sstevel@tonic-gate 	return (xdr_bitmap4(xdrs, &objp->attrset));
25077c478bd9Sstevel@tonic-gate }
25087c478bd9Sstevel@tonic-gate 
25097c478bd9Sstevel@tonic-gate static bool_t
25107c478bd9Sstevel@tonic-gate xdr_LINK4res(XDR *xdrs, LINK4res *objp)
25117c478bd9Sstevel@tonic-gate {
25127c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
25137c478bd9Sstevel@tonic-gate 		return (FALSE);
25147c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
25157c478bd9Sstevel@tonic-gate 		return (TRUE);
25167c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
25177c478bd9Sstevel@tonic-gate 		return (FALSE);
25187c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
25197c478bd9Sstevel@tonic-gate 		return (FALSE);
25207c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after));
25217c478bd9Sstevel@tonic-gate }
25227c478bd9Sstevel@tonic-gate 
25237c478bd9Sstevel@tonic-gate static bool_t
25247c478bd9Sstevel@tonic-gate xdr_LOCK4args(XDR *xdrs, LOCK4args *objp)
25257c478bd9Sstevel@tonic-gate {
25267c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
25277c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->locktype))
25287c478bd9Sstevel@tonic-gate 			return (FALSE);
25297c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->reclaim))
25307c478bd9Sstevel@tonic-gate 			return (FALSE);
25317c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
25327c478bd9Sstevel@tonic-gate 			return (FALSE);
25337c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
25347c478bd9Sstevel@tonic-gate 			return (FALSE);
25357c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->locker.new_lock_owner))
25367c478bd9Sstevel@tonic-gate 			return (FALSE);
25377c478bd9Sstevel@tonic-gate 		if (objp->locker.new_lock_owner == TRUE) {
25387c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
2539*0a701b1eSRobert Gordon 			    open_seqid))
25407c478bd9Sstevel@tonic-gate 				return (FALSE);
25417c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
2542*0a701b1eSRobert Gordon 			    open_stateid.seqid))
25437c478bd9Sstevel@tonic-gate 				return (FALSE);
25447c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->locker.locker4_u.open_owner.
2545*0a701b1eSRobert Gordon 			    open_stateid.other, 12))
25467c478bd9Sstevel@tonic-gate 				return (FALSE);
25477c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
2548*0a701b1eSRobert Gordon 			    lock_seqid))
25497c478bd9Sstevel@tonic-gate 				return (FALSE);
25507c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
2551*0a701b1eSRobert Gordon 			    (u_longlong_t *)&objp->locker.locker4_u.
2552*0a701b1eSRobert Gordon 			    open_owner.lock_owner.clientid))
25537c478bd9Sstevel@tonic-gate 				return (FALSE);
25547c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs,
2555*0a701b1eSRobert Gordon 			    (char **)&objp->locker.locker4_u.open_owner.
2556*0a701b1eSRobert Gordon 			    lock_owner.owner_val,
2557*0a701b1eSRobert Gordon 			    (uint_t *)&objp->locker.locker4_u.open_owner.
2558*0a701b1eSRobert Gordon 			    lock_owner.owner_len,
2559*0a701b1eSRobert Gordon 			    NFS4_OPAQUE_LIMIT));
25607c478bd9Sstevel@tonic-gate 		}
25617c478bd9Sstevel@tonic-gate 
25627c478bd9Sstevel@tonic-gate 		if (objp->locker.new_lock_owner != FALSE)
25637c478bd9Sstevel@tonic-gate 			return (FALSE);
25647c478bd9Sstevel@tonic-gate 
25657c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
2566*0a701b1eSRobert Gordon 		    lock_stateid.seqid))
25677c478bd9Sstevel@tonic-gate 			return (FALSE);
25687c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->locker.locker4_u.lock_owner.
2569*0a701b1eSRobert Gordon 		    lock_stateid.other, 12))
25707c478bd9Sstevel@tonic-gate 			return (FALSE);
25717c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
2572*0a701b1eSRobert Gordon 		    lock_seqid));
25737c478bd9Sstevel@tonic-gate 	}
25747c478bd9Sstevel@tonic-gate 
25757c478bd9Sstevel@tonic-gate 	/*
25767c478bd9Sstevel@tonic-gate 	 * Optimized free case
25777c478bd9Sstevel@tonic-gate 	 */
25787c478bd9Sstevel@tonic-gate 	if (objp->locker.new_lock_owner == TRUE) {
25797c478bd9Sstevel@tonic-gate 		if (objp->locker.locker4_u.open_owner.lock_owner.owner_val !=
2580*0a701b1eSRobert Gordon 		    NULL) {
25817c478bd9Sstevel@tonic-gate 			kmem_free(objp->locker.locker4_u.open_owner.lock_owner.
2582*0a701b1eSRobert Gordon 			    owner_val,
2583*0a701b1eSRobert Gordon 			    objp->locker.locker4_u.open_owner.lock_owner.
2584*0a701b1eSRobert Gordon 			    owner_len);
25857c478bd9Sstevel@tonic-gate 		}
25867c478bd9Sstevel@tonic-gate 	}
25877c478bd9Sstevel@tonic-gate 
25887c478bd9Sstevel@tonic-gate 	return (TRUE);
25897c478bd9Sstevel@tonic-gate }
25907c478bd9Sstevel@tonic-gate 
25917c478bd9Sstevel@tonic-gate static bool_t
25927c478bd9Sstevel@tonic-gate xdr_LOCK4res(XDR *xdrs, LOCK4res *objp)
25937c478bd9Sstevel@tonic-gate {
25947c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
25957c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
25967c478bd9Sstevel@tonic-gate 			return (FALSE);
25977c478bd9Sstevel@tonic-gate 		if (objp->status == NFS4_OK) {
25987c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs,
2599*0a701b1eSRobert Gordon 			    &objp->LOCK4res_u.lock_stateid.seqid))
26007c478bd9Sstevel@tonic-gate 				return (FALSE);
26017c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
2602*0a701b1eSRobert Gordon 			    objp->LOCK4res_u.lock_stateid.other, 12));
26037c478bd9Sstevel@tonic-gate 		}
26047c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4ERR_DENIED)
26057c478bd9Sstevel@tonic-gate 			return (TRUE);
26067c478bd9Sstevel@tonic-gate 
26077c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
2608*0a701b1eSRobert Gordon 		    denied.offset))
26097c478bd9Sstevel@tonic-gate 			return (FALSE);
26107c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
2611*0a701b1eSRobert Gordon 		    denied.length))
26127c478bd9Sstevel@tonic-gate 			return (FALSE);
26137c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->LOCK4res_u.denied.locktype))
26147c478bd9Sstevel@tonic-gate 			return (FALSE);
26157c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
2616*0a701b1eSRobert Gordon 		    denied.owner.clientid))
26177c478bd9Sstevel@tonic-gate 			return (FALSE);
26187c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
2619*0a701b1eSRobert Gordon 		    (char **)&objp->LOCK4res_u.denied.owner.owner_val,
2620*0a701b1eSRobert Gordon 		    (uint_t *)&objp->LOCK4res_u.denied.owner.owner_len,
2621*0a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT));
26227c478bd9Sstevel@tonic-gate 	}
26237c478bd9Sstevel@tonic-gate 
26247c478bd9Sstevel@tonic-gate 	/*
26257c478bd9Sstevel@tonic-gate 	 * Optimized free case
26267c478bd9Sstevel@tonic-gate 	 */
26277c478bd9Sstevel@tonic-gate 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
26287c478bd9Sstevel@tonic-gate 		return (TRUE);
26297c478bd9Sstevel@tonic-gate 
26307c478bd9Sstevel@tonic-gate 	if (objp->LOCK4res_u.denied.owner.owner_val != NULL)
26317c478bd9Sstevel@tonic-gate 		kmem_free(objp->LOCK4res_u.denied.owner.owner_val,
2632*0a701b1eSRobert Gordon 		    objp->LOCK4res_u.denied.owner.owner_len);
26337c478bd9Sstevel@tonic-gate 	return (TRUE);
26347c478bd9Sstevel@tonic-gate }
26357c478bd9Sstevel@tonic-gate 
26367c478bd9Sstevel@tonic-gate static bool_t
26377c478bd9Sstevel@tonic-gate xdr_LOCKT4args(XDR *xdrs, LOCKT4args *objp)
26387c478bd9Sstevel@tonic-gate {
26397c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
26407c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->locktype))
26417c478bd9Sstevel@tonic-gate 			return (FALSE);
26427c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
26437c478bd9Sstevel@tonic-gate 			return (FALSE);
26447c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
26457c478bd9Sstevel@tonic-gate 			return (FALSE);
26467c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
2647*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->owner.clientid))
26487c478bd9Sstevel@tonic-gate 			return (FALSE);
26497c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
2650*0a701b1eSRobert Gordon 		    (uint_t *)&objp->owner.owner_len,
2651*0a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT));
26527c478bd9Sstevel@tonic-gate 	}
26537c478bd9Sstevel@tonic-gate 
26547c478bd9Sstevel@tonic-gate 	/*
26557c478bd9Sstevel@tonic-gate 	 * Optimized free case
26567c478bd9Sstevel@tonic-gate 	 */
26577c478bd9Sstevel@tonic-gate 	if (objp->owner.owner_val != NULL)
26587c478bd9Sstevel@tonic-gate 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
26597c478bd9Sstevel@tonic-gate 	return (TRUE);
26607c478bd9Sstevel@tonic-gate }
26617c478bd9Sstevel@tonic-gate 
26627c478bd9Sstevel@tonic-gate static bool_t
26637c478bd9Sstevel@tonic-gate xdr_LOCKT4res(XDR *xdrs, LOCKT4res *objp)
26647c478bd9Sstevel@tonic-gate {
26657c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
26667c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
26677c478bd9Sstevel@tonic-gate 			return (FALSE);
26687c478bd9Sstevel@tonic-gate 		if (objp->status == NFS4_OK)
26697c478bd9Sstevel@tonic-gate 			return (TRUE);
26707c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4ERR_DENIED)
26717c478bd9Sstevel@tonic-gate 			return (TRUE);
26727c478bd9Sstevel@tonic-gate 		/* xdr_LOCK4denied */
26737c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
2674*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->denied.offset))
26757c478bd9Sstevel@tonic-gate 			return (FALSE);
26767c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
2677*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->denied.length))
26787c478bd9Sstevel@tonic-gate 			return (FALSE);
26797c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->denied.locktype))
26807c478bd9Sstevel@tonic-gate 			return (FALSE);
26817c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
2682*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->denied.owner.clientid))
26837c478bd9Sstevel@tonic-gate 			return (FALSE);
26847c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
26857c478bd9Sstevel@tonic-gate 		    (char **)&objp->denied.owner.owner_val,
26867c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->denied.owner.owner_len,
26877c478bd9Sstevel@tonic-gate 		    NFS4_OPAQUE_LIMIT));
26887c478bd9Sstevel@tonic-gate 	}
26897c478bd9Sstevel@tonic-gate 
26907c478bd9Sstevel@tonic-gate 	/*
26917c478bd9Sstevel@tonic-gate 	 * Optimized free case
26927c478bd9Sstevel@tonic-gate 	 */
26937c478bd9Sstevel@tonic-gate 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
26947c478bd9Sstevel@tonic-gate 		return (TRUE);
26957c478bd9Sstevel@tonic-gate 	if (objp->denied.owner.owner_val != NULL)
26967c478bd9Sstevel@tonic-gate 		kmem_free(objp->denied.owner.owner_val,
2697*0a701b1eSRobert Gordon 		    objp->denied.owner.owner_len);
26987c478bd9Sstevel@tonic-gate 	return (TRUE);
26997c478bd9Sstevel@tonic-gate }
27007c478bd9Sstevel@tonic-gate 
27017c478bd9Sstevel@tonic-gate static bool_t
27027c478bd9Sstevel@tonic-gate xdr_LOCKU4args(XDR *xdrs, LOCKU4args *objp)
27037c478bd9Sstevel@tonic-gate {
27047c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->locktype))
27057c478bd9Sstevel@tonic-gate 		return (FALSE);
27067c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->seqid))
27077c478bd9Sstevel@tonic-gate 		return (FALSE);
27087c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->lock_stateid.seqid))
27097c478bd9Sstevel@tonic-gate 		return (FALSE);
27107c478bd9Sstevel@tonic-gate 	if (!xdr_opaque(xdrs, objp->lock_stateid.other, 12))
27117c478bd9Sstevel@tonic-gate 		return (FALSE);
27127c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
27137c478bd9Sstevel@tonic-gate 		return (FALSE);
27147c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length));
27157c478bd9Sstevel@tonic-gate }
27167c478bd9Sstevel@tonic-gate 
27177c478bd9Sstevel@tonic-gate static bool_t
27187c478bd9Sstevel@tonic-gate xdr_OPEN4args(XDR *xdrs, OPEN4args *objp)
27197c478bd9Sstevel@tonic-gate {
27207c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
27217c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->seqid))
27227c478bd9Sstevel@tonic-gate 			return (FALSE);
27237c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->share_access))
27247c478bd9Sstevel@tonic-gate 			return (FALSE);
27257c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->share_deny))
27267c478bd9Sstevel@tonic-gate 			return (FALSE);
27277c478bd9Sstevel@tonic-gate 
27287c478bd9Sstevel@tonic-gate 		/* xdr_open_owner4 */
27297c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
2730*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->owner.clientid))
27317c478bd9Sstevel@tonic-gate 			return (FALSE);
27327c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
2733*0a701b1eSRobert Gordon 		    (uint_t *)&objp->owner.owner_len,
2734*0a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT))
27357c478bd9Sstevel@tonic-gate 			return (FALSE);
27367c478bd9Sstevel@tonic-gate 
27377c478bd9Sstevel@tonic-gate 		/* xdr_openflag4 */
27387c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->opentype))
27397c478bd9Sstevel@tonic-gate 			return (FALSE);
27407c478bd9Sstevel@tonic-gate 		if (objp->opentype == OPEN4_CREATE) {
27417c478bd9Sstevel@tonic-gate 
27427c478bd9Sstevel@tonic-gate 			/* xdr_createhow4 */
27437c478bd9Sstevel@tonic-gate 			if (!xdr_int(xdrs, (int *)&objp->mode))
27447c478bd9Sstevel@tonic-gate 				return (FALSE);
27457c478bd9Sstevel@tonic-gate 			switch (objp->mode) {
27467c478bd9Sstevel@tonic-gate 			case UNCHECKED4:
27477c478bd9Sstevel@tonic-gate 			case GUARDED4:
27487c478bd9Sstevel@tonic-gate 				if (!xdr_fattr4(xdrs,
2749*0a701b1eSRobert Gordon 				    &objp->createhow4_u.createattrs))
27507c478bd9Sstevel@tonic-gate 					return (FALSE);
27517c478bd9Sstevel@tonic-gate 				break;
27527c478bd9Sstevel@tonic-gate 			case EXCLUSIVE4:
27537c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs,
27547c478bd9Sstevel@tonic-gate 				    (u_longlong_t *)&objp->createhow4_u.
27557c478bd9Sstevel@tonic-gate 				    createverf))
27567c478bd9Sstevel@tonic-gate 					return (FALSE);
27577c478bd9Sstevel@tonic-gate 				break;
27587c478bd9Sstevel@tonic-gate 			default:
27597c478bd9Sstevel@tonic-gate 				return (FALSE);
27607c478bd9Sstevel@tonic-gate 			}
27617c478bd9Sstevel@tonic-gate 		}
27627c478bd9Sstevel@tonic-gate 
27637c478bd9Sstevel@tonic-gate 		/* xdr_open_claim4 */
27647c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->claim))
27657c478bd9Sstevel@tonic-gate 			return (FALSE);
27667c478bd9Sstevel@tonic-gate 
27677c478bd9Sstevel@tonic-gate 		switch (objp->claim) {
27687c478bd9Sstevel@tonic-gate 		case CLAIM_NULL:
27697c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
2770*0a701b1eSRobert Gordon 			    file.utf8string_val,
2771*0a701b1eSRobert Gordon 			    (uint_t *)&objp->open_claim4_u.file.
2772*0a701b1eSRobert Gordon 			    utf8string_len,
2773*0a701b1eSRobert Gordon 			    NFS4_MAX_UTF8STRING));
27747c478bd9Sstevel@tonic-gate 		case CLAIM_PREVIOUS:
27757c478bd9Sstevel@tonic-gate 			return (xdr_int(xdrs,
2776*0a701b1eSRobert Gordon 			    (int *)&objp->open_claim4_u.delegate_type));
27777c478bd9Sstevel@tonic-gate 		case CLAIM_DELEGATE_CUR:
27787c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (uint_t *)&objp->open_claim4_u.
2779*0a701b1eSRobert Gordon 			    delegate_cur_info.delegate_stateid.seqid))
27807c478bd9Sstevel@tonic-gate 				return (FALSE);
27817c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->open_claim4_u.
2782*0a701b1eSRobert Gordon 			    delegate_cur_info.delegate_stateid.other,
2783*0a701b1eSRobert Gordon 			    12))
27847c478bd9Sstevel@tonic-gate 				return (FALSE);
27857c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
2786*0a701b1eSRobert Gordon 			    delegate_cur_info.file.utf8string_val,
27877c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->open_claim4_u.
2788*0a701b1eSRobert Gordon 			    delegate_cur_info.file.utf8string_len,
27897c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING));
27907c478bd9Sstevel@tonic-gate 		case CLAIM_DELEGATE_PREV:
27917c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
2792*0a701b1eSRobert Gordon 			    file_delegate_prev.utf8string_val,
27937c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->open_claim4_u.
2794*0a701b1eSRobert Gordon 			    file_delegate_prev.utf8string_len,
27957c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING));
27967c478bd9Sstevel@tonic-gate 		default:
27977c478bd9Sstevel@tonic-gate 			return (FALSE);
27987c478bd9Sstevel@tonic-gate 		}
27997c478bd9Sstevel@tonic-gate 	}
28007c478bd9Sstevel@tonic-gate 
28017c478bd9Sstevel@tonic-gate 	/*
28027c478bd9Sstevel@tonic-gate 	 * Optimized free case
28037c478bd9Sstevel@tonic-gate 	 */
28047c478bd9Sstevel@tonic-gate 	if (objp->owner.owner_val != NULL)
28057c478bd9Sstevel@tonic-gate 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
28067c478bd9Sstevel@tonic-gate 
28077c478bd9Sstevel@tonic-gate 	if (objp->opentype == OPEN4_CREATE) {
28087c478bd9Sstevel@tonic-gate 		switch (objp->mode) {
28097c478bd9Sstevel@tonic-gate 		case UNCHECKED4:
28107c478bd9Sstevel@tonic-gate 		case GUARDED4:
28117c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
2812*0a701b1eSRobert Gordon 			    &objp->createhow4_u.createattrs);
28137c478bd9Sstevel@tonic-gate 			break;
28147c478bd9Sstevel@tonic-gate 		case EXCLUSIVE4:
28157c478bd9Sstevel@tonic-gate 		default:
28167c478bd9Sstevel@tonic-gate 			break;
28177c478bd9Sstevel@tonic-gate 		}
28187c478bd9Sstevel@tonic-gate 	}
28197c478bd9Sstevel@tonic-gate 
28207c478bd9Sstevel@tonic-gate 	switch (objp->claim) {
28217c478bd9Sstevel@tonic-gate 	case CLAIM_NULL:
28227c478bd9Sstevel@tonic-gate 		if (objp->open_claim4_u.file.utf8string_val != NULL)
28237c478bd9Sstevel@tonic-gate 			kmem_free(objp->open_claim4_u.file.utf8string_val,
2824*0a701b1eSRobert Gordon 			    objp->open_claim4_u.file.utf8string_len);
28257c478bd9Sstevel@tonic-gate 		return (TRUE);
28267c478bd9Sstevel@tonic-gate 	case CLAIM_PREVIOUS:
28277c478bd9Sstevel@tonic-gate 		return (TRUE);
28287c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_CUR:
28297c478bd9Sstevel@tonic-gate 		if (objp->open_claim4_u.delegate_cur_info.file.utf8string_val !=
2830*0a701b1eSRobert Gordon 		    NULL) {
28317c478bd9Sstevel@tonic-gate 			kmem_free(objp->open_claim4_u.delegate_cur_info.file.
2832*0a701b1eSRobert Gordon 			    utf8string_val,
2833*0a701b1eSRobert Gordon 			    objp->open_claim4_u.delegate_cur_info.file.
2834*0a701b1eSRobert Gordon 			    utf8string_len);
28357c478bd9Sstevel@tonic-gate 		}
28367c478bd9Sstevel@tonic-gate 		return (TRUE);
28377c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_PREV:
28387c478bd9Sstevel@tonic-gate 		if (objp->open_claim4_u.file_delegate_prev.utf8string_val !=
2839*0a701b1eSRobert Gordon 		    NULL) {
28407c478bd9Sstevel@tonic-gate 			kmem_free(objp->open_claim4_u.file_delegate_prev.
2841*0a701b1eSRobert Gordon 			    utf8string_val,
2842*0a701b1eSRobert Gordon 			    objp->open_claim4_u.file_delegate_prev.
2843*0a701b1eSRobert Gordon 			    utf8string_len);
28447c478bd9Sstevel@tonic-gate 		}
28457c478bd9Sstevel@tonic-gate 		return (TRUE);
28467c478bd9Sstevel@tonic-gate 	default:
28477c478bd9Sstevel@tonic-gate 		return (TRUE);
28487c478bd9Sstevel@tonic-gate 	}
28497c478bd9Sstevel@tonic-gate }
28507c478bd9Sstevel@tonic-gate 
28517c478bd9Sstevel@tonic-gate static bool_t
28527c478bd9Sstevel@tonic-gate xdr_OPEN4cargs(XDR *xdrs, OPEN4cargs *objp)
28537c478bd9Sstevel@tonic-gate {
28547c478bd9Sstevel@tonic-gate 	int op;
28557c478bd9Sstevel@tonic-gate 	int len;
28567c478bd9Sstevel@tonic-gate 	rpc_inline_t *ptr;
28577c478bd9Sstevel@tonic-gate 
28587c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
28597c478bd9Sstevel@tonic-gate 
28607c478bd9Sstevel@tonic-gate 	/*
28617c478bd9Sstevel@tonic-gate 	 * We must always define the client's open_owner to be
28627c478bd9Sstevel@tonic-gate 	 * 4 byte aligned and sized.
28637c478bd9Sstevel@tonic-gate 	 */
28647c478bd9Sstevel@tonic-gate 	ASSERT(objp->owner.owner_len <= NFS4_OPAQUE_LIMIT);
28657c478bd9Sstevel@tonic-gate 	ASSERT(!(objp->owner.owner_len % BYTES_PER_XDR_UNIT));
28667c478bd9Sstevel@tonic-gate 
28677c478bd9Sstevel@tonic-gate 	len = objp->owner.owner_len;
28687c478bd9Sstevel@tonic-gate 	if ((ptr = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + len)) != NULL) {
28697c478bd9Sstevel@tonic-gate 		int i;
28707c478bd9Sstevel@tonic-gate 		int32_t *ip;
28717c478bd9Sstevel@tonic-gate 
28727c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, OP_OPEN);
28737c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->seqid);
28747c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->share_access);
28757c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->share_deny);
28767c478bd9Sstevel@tonic-gate 
28777c478bd9Sstevel@tonic-gate 		/* xdr_open_owner4 */
28787c478bd9Sstevel@tonic-gate 		IXDR_PUT_HYPER(ptr, objp->owner.clientid);
28797c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->owner.owner_len);
28807c478bd9Sstevel@tonic-gate 		/* We know this is very short so don't bcopy */
28817c478bd9Sstevel@tonic-gate 		ip = (int32_t *)objp->owner.owner_val;
28827c478bd9Sstevel@tonic-gate 		len /= BYTES_PER_XDR_UNIT;
28837c478bd9Sstevel@tonic-gate 		for (i = 0; i < len; i++)
28847c478bd9Sstevel@tonic-gate 			*ptr++ = *ip++;
28857c478bd9Sstevel@tonic-gate 
28867c478bd9Sstevel@tonic-gate 		/* xdr_openflag4 */
28877c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->opentype);
28887c478bd9Sstevel@tonic-gate 	} else {
28897c478bd9Sstevel@tonic-gate 		op = OP_OPEN;
28907c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&op))
28917c478bd9Sstevel@tonic-gate 			return (FALSE);
28927c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->seqid))
28937c478bd9Sstevel@tonic-gate 			return (FALSE);
28947c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_access))
28957c478bd9Sstevel@tonic-gate 			return (FALSE);
28967c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_deny))
28977c478bd9Sstevel@tonic-gate 			return (FALSE);
28987c478bd9Sstevel@tonic-gate 
28997c478bd9Sstevel@tonic-gate 		/* xdr_open_owner4 */
29007c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
2901*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->owner.clientid))
29027c478bd9Sstevel@tonic-gate 			return (FALSE);
29037c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->owner.owner_len))
29047c478bd9Sstevel@tonic-gate 			return (FALSE);
29057c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->owner.owner_val,
2906*0a701b1eSRobert Gordon 		    objp->owner.owner_len))
29077c478bd9Sstevel@tonic-gate 			return (FALSE);
29087c478bd9Sstevel@tonic-gate 
29097c478bd9Sstevel@tonic-gate 		/* xdr_openflag4 */
29107c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->opentype))
29117c478bd9Sstevel@tonic-gate 			return (FALSE);
29127c478bd9Sstevel@tonic-gate 	}
29137c478bd9Sstevel@tonic-gate 
29147c478bd9Sstevel@tonic-gate 	if (objp->opentype == OPEN4_CREATE) {
29157c478bd9Sstevel@tonic-gate 		/* xdr_createhow4 */
29167c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->mode))
29177c478bd9Sstevel@tonic-gate 			return (FALSE);
29187c478bd9Sstevel@tonic-gate 		switch (objp->mode) {
29197c478bd9Sstevel@tonic-gate 		case UNCHECKED4:
29207c478bd9Sstevel@tonic-gate 		case GUARDED4:
29217c478bd9Sstevel@tonic-gate 			if (!xdr_fattr4(xdrs,
2922*0a701b1eSRobert Gordon 			    &objp->createhow4_u.createattrs))
29237c478bd9Sstevel@tonic-gate 				return (FALSE);
29247c478bd9Sstevel@tonic-gate 			break;
29257c478bd9Sstevel@tonic-gate 		case EXCLUSIVE4:
29267c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
29277c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->createhow4_u.
29287c478bd9Sstevel@tonic-gate 			    createverf))
29297c478bd9Sstevel@tonic-gate 				return (FALSE);
29307c478bd9Sstevel@tonic-gate 			break;
29317c478bd9Sstevel@tonic-gate 		default:
29327c478bd9Sstevel@tonic-gate 			return (FALSE);
29337c478bd9Sstevel@tonic-gate 		}
29347c478bd9Sstevel@tonic-gate 	}
29357c478bd9Sstevel@tonic-gate 
29367c478bd9Sstevel@tonic-gate 	/* xdr_open_claim4 */
29377c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->claim))
29387c478bd9Sstevel@tonic-gate 		return (FALSE);
29397c478bd9Sstevel@tonic-gate 
29407c478bd9Sstevel@tonic-gate 	switch (objp->claim) {
29417c478bd9Sstevel@tonic-gate 	case CLAIM_NULL:
29427c478bd9Sstevel@tonic-gate 		len = strlen(objp->open_claim4_u.cfile);
29437c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
29447c478bd9Sstevel@tonic-gate 			return (FALSE);
29457c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
29467c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
2947*0a701b1eSRobert Gordon 			    objp->open_claim4_u.cfile, len));
29487c478bd9Sstevel@tonic-gate 		}
29497c478bd9Sstevel@tonic-gate 		return (FALSE);
29507c478bd9Sstevel@tonic-gate 	case CLAIM_PREVIOUS:
29517c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs,
2952*0a701b1eSRobert Gordon 		    (int32_t *)&objp->open_claim4_u.delegate_type));
29537c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_CUR:
29547c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->open_claim4_u.
2955*0a701b1eSRobert Gordon 		    delegate_cur_info.delegate_stateid.seqid))
29567c478bd9Sstevel@tonic-gate 			return (FALSE);
29577c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->open_claim4_u.
2958*0a701b1eSRobert Gordon 		    delegate_cur_info.delegate_stateid.other,
2959*0a701b1eSRobert Gordon 		    12))
29607c478bd9Sstevel@tonic-gate 			return (FALSE);
29617c478bd9Sstevel@tonic-gate 		len = strlen(objp->open_claim4_u.delegate_cur_info.cfile);
29627c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
29637c478bd9Sstevel@tonic-gate 			return (FALSE);
29647c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
29657c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
2966*0a701b1eSRobert Gordon 			    objp->open_claim4_u.delegate_cur_info.cfile,
2967*0a701b1eSRobert Gordon 			    len));
29687c478bd9Sstevel@tonic-gate 		}
29697c478bd9Sstevel@tonic-gate 		return (FALSE);
29707c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_PREV:
29717c478bd9Sstevel@tonic-gate 		len = strlen(objp->open_claim4_u.cfile_delegate_prev);
29727c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
29737c478bd9Sstevel@tonic-gate 			return (FALSE);
29747c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
29757c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
2976*0a701b1eSRobert Gordon 			    objp->open_claim4_u.cfile_delegate_prev, len));
29777c478bd9Sstevel@tonic-gate 		}
29787c478bd9Sstevel@tonic-gate 		return (FALSE);
29797c478bd9Sstevel@tonic-gate 	default:
29807c478bd9Sstevel@tonic-gate 		return (FALSE);
29817c478bd9Sstevel@tonic-gate 	}
29827c478bd9Sstevel@tonic-gate }
29837c478bd9Sstevel@tonic-gate 
29847c478bd9Sstevel@tonic-gate static bool_t
29857c478bd9Sstevel@tonic-gate xdr_OPEN4res(XDR *xdrs, OPEN4res *objp)
29867c478bd9Sstevel@tonic-gate {
29877c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
29887c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
29897c478bd9Sstevel@tonic-gate 			return (FALSE);
29907c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
29917c478bd9Sstevel@tonic-gate 			return (TRUE);
29927c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
29937c478bd9Sstevel@tonic-gate 			return (FALSE);
29947c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->stateid.other, 12))
29957c478bd9Sstevel@tonic-gate 			return (FALSE);
29967c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->cinfo.atomic))
29977c478bd9Sstevel@tonic-gate 			return (FALSE);
29987c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
2999*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->cinfo.before))
30007c478bd9Sstevel@tonic-gate 			return (FALSE);
30017c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
30027c478bd9Sstevel@tonic-gate 			return (FALSE);
30037c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->rflags))
30047c478bd9Sstevel@tonic-gate 			return (FALSE);
30057c478bd9Sstevel@tonic-gate 		if (!xdr_bitmap4(xdrs, &objp->attrset))
30067c478bd9Sstevel@tonic-gate 			return (FALSE);
30077c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
3008*0a701b1eSRobert Gordon 		    (int *)&objp->delegation.delegation_type))
30097c478bd9Sstevel@tonic-gate 			return (FALSE);
30107c478bd9Sstevel@tonic-gate 		switch (objp->delegation.delegation_type) {
30117c478bd9Sstevel@tonic-gate 		case OPEN_DELEGATE_NONE:
30127c478bd9Sstevel@tonic-gate 			return (TRUE);
30137c478bd9Sstevel@tonic-gate 		case OPEN_DELEGATE_READ:
30147c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->delegation.
3015*0a701b1eSRobert Gordon 			    open_delegation4_u.read.stateid.seqid))
30167c478bd9Sstevel@tonic-gate 				return (FALSE);
30177c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->delegation.
3018*0a701b1eSRobert Gordon 			    open_delegation4_u.read.stateid.other,
3019*0a701b1eSRobert Gordon 			    12))
30207c478bd9Sstevel@tonic-gate 				return (FALSE);
30217c478bd9Sstevel@tonic-gate 			if (!xdr_bool(xdrs, &objp->delegation.
3022*0a701b1eSRobert Gordon 			    open_delegation4_u.read.recall))
30237c478bd9Sstevel@tonic-gate 				return (FALSE);
30247c478bd9Sstevel@tonic-gate 			return (xdr_nfsace4(xdrs, &objp->delegation.
3025*0a701b1eSRobert Gordon 			    open_delegation4_u.read.permissions));
30267c478bd9Sstevel@tonic-gate 		case OPEN_DELEGATE_WRITE:
30277c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->delegation.
3028*0a701b1eSRobert Gordon 			    open_delegation4_u.write.stateid.seqid))
30297c478bd9Sstevel@tonic-gate 				return (FALSE);
30307c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->delegation.
3031*0a701b1eSRobert Gordon 			    open_delegation4_u.write.stateid.other,
3032*0a701b1eSRobert Gordon 			    12))
30337c478bd9Sstevel@tonic-gate 				return (FALSE);
30347c478bd9Sstevel@tonic-gate 			if (!xdr_bool(xdrs, &objp->delegation.
3035*0a701b1eSRobert Gordon 			    open_delegation4_u.write.recall))
30367c478bd9Sstevel@tonic-gate 				return (FALSE);
30377c478bd9Sstevel@tonic-gate 			if (!xdr_int(xdrs, (int *)&objp->delegation.
3038*0a701b1eSRobert Gordon 			    open_delegation4_u.write.space_limit.
3039*0a701b1eSRobert Gordon 			    limitby))
30407c478bd9Sstevel@tonic-gate 				return (FALSE);
30417c478bd9Sstevel@tonic-gate 			switch (objp->delegation.
3042*0a701b1eSRobert Gordon 			    open_delegation4_u.write.space_limit.
3043*0a701b1eSRobert Gordon 			    limitby) {
30447c478bd9Sstevel@tonic-gate 			case NFS_LIMIT_SIZE:
30457c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs,
30467c478bd9Sstevel@tonic-gate 				    (u_longlong_t *)&objp->delegation.
30477c478bd9Sstevel@tonic-gate 				    open_delegation4_u.write.space_limit.
30487c478bd9Sstevel@tonic-gate 				    nfs_space_limit4_u.filesize))
30497c478bd9Sstevel@tonic-gate 					return (FALSE);
30507c478bd9Sstevel@tonic-gate 				break;
30517c478bd9Sstevel@tonic-gate 			case NFS_LIMIT_BLOCKS:
30527c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs,
30537c478bd9Sstevel@tonic-gate 				    &objp->delegation.open_delegation4_u.write.
30547c478bd9Sstevel@tonic-gate 				    space_limit.nfs_space_limit4_u.
30557c478bd9Sstevel@tonic-gate 				    mod_blocks.num_blocks))
30567c478bd9Sstevel@tonic-gate 					return (FALSE);
30577c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &objp->delegation.
30587c478bd9Sstevel@tonic-gate 				    open_delegation4_u.write.space_limit.
30597c478bd9Sstevel@tonic-gate 				    nfs_space_limit4_u.mod_blocks.
30607c478bd9Sstevel@tonic-gate 				    bytes_per_block))
30617c478bd9Sstevel@tonic-gate 					return (FALSE);
30627c478bd9Sstevel@tonic-gate 				break;
30637c478bd9Sstevel@tonic-gate 			default:
30647c478bd9Sstevel@tonic-gate 				return (FALSE);
30657c478bd9Sstevel@tonic-gate 			}
30667c478bd9Sstevel@tonic-gate 			return (xdr_nfsace4(xdrs, &objp->delegation.
30677c478bd9Sstevel@tonic-gate 			    open_delegation4_u.write.permissions));
30687c478bd9Sstevel@tonic-gate 		}
30697c478bd9Sstevel@tonic-gate 		return (FALSE);
30707c478bd9Sstevel@tonic-gate 	}
30717c478bd9Sstevel@tonic-gate 
30727c478bd9Sstevel@tonic-gate 	/*
30737c478bd9Sstevel@tonic-gate 	 * Optimized free case
30747c478bd9Sstevel@tonic-gate 	 */
30757c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
30767c478bd9Sstevel@tonic-gate 		return (TRUE);
30777c478bd9Sstevel@tonic-gate 
30787c478bd9Sstevel@tonic-gate 	switch (objp->delegation.delegation_type) {
30797c478bd9Sstevel@tonic-gate 	case OPEN_DELEGATE_NONE:
30807c478bd9Sstevel@tonic-gate 		return (TRUE);
30817c478bd9Sstevel@tonic-gate 	case OPEN_DELEGATE_READ:
30827c478bd9Sstevel@tonic-gate 		return (xdr_nfsace4(xdrs, &objp->delegation.
3083*0a701b1eSRobert Gordon 		    open_delegation4_u.read.permissions));
30847c478bd9Sstevel@tonic-gate 	case OPEN_DELEGATE_WRITE:
30857c478bd9Sstevel@tonic-gate 		switch (objp->delegation.
3086*0a701b1eSRobert Gordon 		    open_delegation4_u.write.space_limit.limitby) {
30877c478bd9Sstevel@tonic-gate 		case NFS_LIMIT_SIZE:
30887c478bd9Sstevel@tonic-gate 		case NFS_LIMIT_BLOCKS:
30897c478bd9Sstevel@tonic-gate 			break;
30907c478bd9Sstevel@tonic-gate 		default:
30917c478bd9Sstevel@tonic-gate 			return (FALSE);
30927c478bd9Sstevel@tonic-gate 		}
30937c478bd9Sstevel@tonic-gate 		return (xdr_nfsace4(xdrs, &objp->delegation.
3094*0a701b1eSRobert Gordon 		    open_delegation4_u.write.permissions));
30957c478bd9Sstevel@tonic-gate 	}
30967c478bd9Sstevel@tonic-gate 	return (FALSE);
30977c478bd9Sstevel@tonic-gate }
30987c478bd9Sstevel@tonic-gate 
30997c478bd9Sstevel@tonic-gate static bool_t
31007c478bd9Sstevel@tonic-gate xdr_OPEN_CONFIRM4res(XDR *xdrs, OPEN_CONFIRM4res *objp)
31017c478bd9Sstevel@tonic-gate {
31027c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
31037c478bd9Sstevel@tonic-gate 		return (FALSE);
31047c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
31057c478bd9Sstevel@tonic-gate 		return (TRUE);
31067c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
31077c478bd9Sstevel@tonic-gate 		return (FALSE);
31087c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
31097c478bd9Sstevel@tonic-gate }
31107c478bd9Sstevel@tonic-gate 
31117c478bd9Sstevel@tonic-gate static bool_t
31127c478bd9Sstevel@tonic-gate xdr_OPEN_DOWNGRADE4args(XDR *xdrs, OPEN_DOWNGRADE4args *objp)
31137c478bd9Sstevel@tonic-gate {
31147c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
31157c478bd9Sstevel@tonic-gate 		return (FALSE);
31167c478bd9Sstevel@tonic-gate 	if (!xdr_opaque(xdrs, objp->open_stateid.other, 12))
31177c478bd9Sstevel@tonic-gate 		return (FALSE);
31187c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->seqid))
31197c478bd9Sstevel@tonic-gate 		return (FALSE);
31207c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->share_access))
31217c478bd9Sstevel@tonic-gate 		return (FALSE);
31227c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->share_deny));
31237c478bd9Sstevel@tonic-gate }
31247c478bd9Sstevel@tonic-gate 
31257c478bd9Sstevel@tonic-gate static bool_t
31267c478bd9Sstevel@tonic-gate xdr_OPEN_DOWNGRADE4res(XDR *xdrs, OPEN_DOWNGRADE4res *objp)
31277c478bd9Sstevel@tonic-gate {
31287c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
31297c478bd9Sstevel@tonic-gate 		return (FALSE);
31307c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
31317c478bd9Sstevel@tonic-gate 		return (TRUE);
31327c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
31337c478bd9Sstevel@tonic-gate 		return (FALSE);
31347c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
31357c478bd9Sstevel@tonic-gate }
31367c478bd9Sstevel@tonic-gate 
31377c478bd9Sstevel@tonic-gate static bool_t
31387c478bd9Sstevel@tonic-gate xdr_READ4args(XDR *xdrs, READ4args *objp)
31397c478bd9Sstevel@tonic-gate {
3140*0a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
3141*0a701b1eSRobert Gordon 	rdma_wlist_conn_info_t rwci;
3142*0a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
3143*0a701b1eSRobert Gordon 
31447c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->stateid.seqid))
31457c478bd9Sstevel@tonic-gate 		return (FALSE);
31467c478bd9Sstevel@tonic-gate 	if (!xdr_opaque(xdrs, objp->stateid.other, 12))
31477c478bd9Sstevel@tonic-gate 		return (FALSE);
31487c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
31497c478bd9Sstevel@tonic-gate 		return (FALSE);
3150*0a701b1eSRobert Gordon 	if (!xdr_u_int(xdrs, &objp->count))
3151*0a701b1eSRobert Gordon 		return (FALSE);
3152*0a701b1eSRobert Gordon 
3153*0a701b1eSRobert Gordon 	DTRACE_PROBE1(xdr__i__read4args_buf_len,
3154*0a701b1eSRobert Gordon 	    int, objp->count);
3155*0a701b1eSRobert Gordon 
3156*0a701b1eSRobert Gordon 	objp->wlist = NULL;
3157*0a701b1eSRobert Gordon 
3158*0a701b1eSRobert Gordon 	if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
3159*0a701b1eSRobert Gordon 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
3160*0a701b1eSRobert Gordon 		rci.rci_len = objp->count;
3161*0a701b1eSRobert Gordon 		(void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
3162*0a701b1eSRobert Gordon 	}
3163*0a701b1eSRobert Gordon 
3164*0a701b1eSRobert Gordon 	if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
3165*0a701b1eSRobert Gordon 		return (TRUE);
3166*0a701b1eSRobert Gordon 
3167*0a701b1eSRobert Gordon 	if (xdrs->x_op == XDR_ENCODE) {
3168*0a701b1eSRobert Gordon 		if (objp->res_uiop != NULL) {
3169*0a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_UIO_CHUNK;
3170*0a701b1eSRobert Gordon 			rci.rci_a.rci_uiop = objp->res_uiop;
3171*0a701b1eSRobert Gordon 			rci.rci_len = objp->count;
3172*0a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
3173*0a701b1eSRobert Gordon 		} else {
3174*0a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_ADDR_CHUNK;
3175*0a701b1eSRobert Gordon 			rci.rci_a.rci_addr = objp->res_data_val_alt;
3176*0a701b1eSRobert Gordon 			rci.rci_len = objp->count;
3177*0a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
3178*0a701b1eSRobert Gordon 		}
3179*0a701b1eSRobert Gordon 
3180*0a701b1eSRobert Gordon 		return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
3181*0a701b1eSRobert Gordon 	}
3182*0a701b1eSRobert Gordon 
3183*0a701b1eSRobert Gordon 	/* XDR_DECODE case */
3184*0a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
3185*0a701b1eSRobert Gordon 	objp->wlist = rwci.rwci_wlist;
3186*0a701b1eSRobert Gordon 	objp->conn = rwci.rwci_conn;
3187*0a701b1eSRobert Gordon 
3188*0a701b1eSRobert Gordon 	return (TRUE);
31897c478bd9Sstevel@tonic-gate }
31907c478bd9Sstevel@tonic-gate 
31917c478bd9Sstevel@tonic-gate static bool_t
31927c478bd9Sstevel@tonic-gate xdr_READ4res(XDR *xdrs, READ4res *objp)
31937c478bd9Sstevel@tonic-gate {
31947c478bd9Sstevel@tonic-gate 	int i, rndup;
31957c478bd9Sstevel@tonic-gate 	mblk_t *mp;
31967c478bd9Sstevel@tonic-gate 
31977c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
31987c478bd9Sstevel@tonic-gate 		return (FALSE);
31997c478bd9Sstevel@tonic-gate 
32007c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE) {
32017c478bd9Sstevel@tonic-gate 		/*
32027c478bd9Sstevel@tonic-gate 		 * Optimized free case
32037c478bd9Sstevel@tonic-gate 		 */
32047c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
32057c478bd9Sstevel@tonic-gate 			return (TRUE);
32067c478bd9Sstevel@tonic-gate 		if (objp->data_val != NULL)
32077c478bd9Sstevel@tonic-gate 			kmem_free(objp->data_val, objp->data_len);
32087c478bd9Sstevel@tonic-gate 		return (TRUE);
32097c478bd9Sstevel@tonic-gate 	}
32107c478bd9Sstevel@tonic-gate 
32117c478bd9Sstevel@tonic-gate 	/* on with ENCODE paths */
32127c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->status))
32137c478bd9Sstevel@tonic-gate 		return (FALSE);
32147c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
32157c478bd9Sstevel@tonic-gate 		return (TRUE);
32167c478bd9Sstevel@tonic-gate 
32177c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, &objp->eof))
32187c478bd9Sstevel@tonic-gate 		return (FALSE);
32197c478bd9Sstevel@tonic-gate 
32207c478bd9Sstevel@tonic-gate 	mp = objp->mblk;
32217c478bd9Sstevel@tonic-gate 	if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
32227c478bd9Sstevel@tonic-gate 		mp->b_wptr += objp->data_len;
32237c478bd9Sstevel@tonic-gate 		rndup = BYTES_PER_XDR_UNIT -
3224*0a701b1eSRobert Gordon 		    (objp->data_len % BYTES_PER_XDR_UNIT);
32257c478bd9Sstevel@tonic-gate 		if (rndup != BYTES_PER_XDR_UNIT)
32267c478bd9Sstevel@tonic-gate 			for (i = 0; i < rndup; i++)
32277c478bd9Sstevel@tonic-gate 				*mp->b_wptr++ = '\0';
32287c478bd9Sstevel@tonic-gate 		if (xdrmblk_putmblk(xdrs, mp, objp->data_len) == TRUE) {
32297c478bd9Sstevel@tonic-gate 			objp->mblk = NULL;
32307c478bd9Sstevel@tonic-gate 			return (TRUE);
32317c478bd9Sstevel@tonic-gate 		}
3232*0a701b1eSRobert Gordon 	} else if (mp == NULL) {
3233*0a701b1eSRobert Gordon 		if (xdr_u_int(xdrs, &objp->data_len) == FALSE) {
3234*0a701b1eSRobert Gordon 			return (FALSE);
3235*0a701b1eSRobert Gordon 		}
3236*0a701b1eSRobert Gordon 		/*
3237*0a701b1eSRobert Gordon 		 * If read data sent by wlist (RDMA_WRITE), don't do
3238*0a701b1eSRobert Gordon 		 * xdr_bytes() below.   RDMA_WRITE transfers the data.
3239*0a701b1eSRobert Gordon 		 * Note: this is encode-only because the client code
3240*0a701b1eSRobert Gordon 		 * uses xdr_READ4res_clnt to decode results.
3241*0a701b1eSRobert Gordon 		 */
3242*0a701b1eSRobert Gordon 		if (objp->wlist) {
3243*0a701b1eSRobert Gordon 			if (objp->wlist->c_len != objp->data_len) {
3244*0a701b1eSRobert Gordon 				objp->wlist->c_len = objp->data_len;
3245*0a701b1eSRobert Gordon 			}
3246*0a701b1eSRobert Gordon 			if (objp->data_len != 0) {
3247*0a701b1eSRobert Gordon 				return (xdrrdma_send_read_data(
3248*0a701b1eSRobert Gordon 				    xdrs, objp->wlist));
3249*0a701b1eSRobert Gordon 			}
3250*0a701b1eSRobert Gordon 			return (TRUE);
3251*0a701b1eSRobert Gordon 		}
32527c478bd9Sstevel@tonic-gate 	}
3253*0a701b1eSRobert Gordon 
32547c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, (char **)&objp->data_val,
3255*0a701b1eSRobert Gordon 	    (uint_t *)&objp->data_len,
3256*0a701b1eSRobert Gordon 	    objp->data_len));
32577c478bd9Sstevel@tonic-gate }
32587c478bd9Sstevel@tonic-gate 
32597c478bd9Sstevel@tonic-gate static bool_t
32607c478bd9Sstevel@tonic-gate xdr_READ4res_clnt(XDR *xdrs, READ4res *objp, READ4args *aobjp)
32617c478bd9Sstevel@tonic-gate {
32627c478bd9Sstevel@tonic-gate 	mblk_t *mp;
32637c478bd9Sstevel@tonic-gate 	size_t n;
32647c478bd9Sstevel@tonic-gate 	int error;
32657c478bd9Sstevel@tonic-gate 	uint_t size = aobjp->res_maxsize;
3266*0a701b1eSRobert Gordon 	count4 ocount;
32677c478bd9Sstevel@tonic-gate 
32687c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
32697c478bd9Sstevel@tonic-gate 		return (FALSE);
32707c478bd9Sstevel@tonic-gate 
32717c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE) {
32727c478bd9Sstevel@tonic-gate 		/*
32737c478bd9Sstevel@tonic-gate 		 * Optimized free case
32747c478bd9Sstevel@tonic-gate 		 */
32757c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
32767c478bd9Sstevel@tonic-gate 			return (TRUE);
32777c478bd9Sstevel@tonic-gate 		if (objp->data_val != NULL)
32787c478bd9Sstevel@tonic-gate 			kmem_free(objp->data_val, objp->data_len);
32797c478bd9Sstevel@tonic-gate 		return (TRUE);
32807c478bd9Sstevel@tonic-gate 	}
32817c478bd9Sstevel@tonic-gate 
32827c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
32837c478bd9Sstevel@tonic-gate 		return (FALSE);
32847c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
32857c478bd9Sstevel@tonic-gate 		return (TRUE);
32867c478bd9Sstevel@tonic-gate 
32877c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, &objp->eof))
32887c478bd9Sstevel@tonic-gate 		return (FALSE);
32897c478bd9Sstevel@tonic-gate 
32907c478bd9Sstevel@tonic-gate 
32917c478bd9Sstevel@tonic-gate 	/*
32927c478bd9Sstevel@tonic-gate 	 * This is a special case such that the caller is providing a
32937c478bd9Sstevel@tonic-gate 	 * uio as a guide to eventual data location; this is used for
32947c478bd9Sstevel@tonic-gate 	 * handling DIRECTIO reads.
32957c478bd9Sstevel@tonic-gate 	 */
32967c478bd9Sstevel@tonic-gate 	if (aobjp->res_uiop != NULL) {
32977c478bd9Sstevel@tonic-gate 		struct uio *uiop = aobjp->res_uiop;
32987c478bd9Sstevel@tonic-gate 		int32_t *ptr;
32997c478bd9Sstevel@tonic-gate 
33007c478bd9Sstevel@tonic-gate 		if (xdrs->x_ops == &xdrmblk_ops) {
33017c478bd9Sstevel@tonic-gate 			if (!xdrmblk_getmblk(xdrs, &mp, &objp->data_len))
33027c478bd9Sstevel@tonic-gate 				return (FALSE);
33037c478bd9Sstevel@tonic-gate 
33047c478bd9Sstevel@tonic-gate 			if (objp->data_len == 0)
33057c478bd9Sstevel@tonic-gate 				return (TRUE);
33067c478bd9Sstevel@tonic-gate 
33077c478bd9Sstevel@tonic-gate 			if (objp->data_len > size)
33087c478bd9Sstevel@tonic-gate 				return (FALSE);
33097c478bd9Sstevel@tonic-gate 
33107c478bd9Sstevel@tonic-gate 			size = objp->data_len;
33117c478bd9Sstevel@tonic-gate 			do {
33127c478bd9Sstevel@tonic-gate 				n = MIN(size, mp->b_wptr - mp->b_rptr);
33137c478bd9Sstevel@tonic-gate 				if ((n = MIN(uiop->uio_resid, n)) != 0) {
33147c478bd9Sstevel@tonic-gate 
33157c478bd9Sstevel@tonic-gate 					error =	uiomove((char *)mp->b_rptr, n,
3316*0a701b1eSRobert Gordon 					    UIO_READ, uiop);
33177c478bd9Sstevel@tonic-gate 					if (error)
33187c478bd9Sstevel@tonic-gate 						return (FALSE);
33197c478bd9Sstevel@tonic-gate 					mp->b_rptr += n;
33207c478bd9Sstevel@tonic-gate 					size -= n;
33217c478bd9Sstevel@tonic-gate 				}
33227c478bd9Sstevel@tonic-gate 
33237c478bd9Sstevel@tonic-gate 				while (mp && (mp->b_rptr >= mp->b_wptr))
33247c478bd9Sstevel@tonic-gate 					mp = mp->b_cont;
33257c478bd9Sstevel@tonic-gate 			} while (mp && size > 0 && uiop->uio_resid > 0);
33267c478bd9Sstevel@tonic-gate 
33277c478bd9Sstevel@tonic-gate 			return (TRUE);
33287c478bd9Sstevel@tonic-gate 		}
33297c478bd9Sstevel@tonic-gate 
3330*0a701b1eSRobert Gordon 		if (xdrs->x_ops == &xdrrdma_ops) {
3331*0a701b1eSRobert Gordon 			struct clist *cl;
3332*0a701b1eSRobert Gordon 
3333*0a701b1eSRobert Gordon 			XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
3334*0a701b1eSRobert Gordon 
3335*0a701b1eSRobert Gordon 			objp->wlist = cl;
3336*0a701b1eSRobert Gordon 
3337*0a701b1eSRobert Gordon 			if (objp->wlist) {
3338*0a701b1eSRobert Gordon 				/* opaque count */
3339*0a701b1eSRobert Gordon 				if (!xdr_u_int(xdrs, &ocount)) {
3340*0a701b1eSRobert Gordon 					objp->wlist = NULL;
3341*0a701b1eSRobert Gordon 					return (FALSE);
3342*0a701b1eSRobert Gordon 				}
3343*0a701b1eSRobert Gordon 
3344*0a701b1eSRobert Gordon 				objp->wlist_len = cl->c_len;
3345*0a701b1eSRobert Gordon 				objp->data_len = objp->wlist_len;
3346*0a701b1eSRobert Gordon 
3347*0a701b1eSRobert Gordon 				if (ocount != objp->data_len) {
3348*0a701b1eSRobert Gordon 					DTRACE_PROBE2(
3349*0a701b1eSRobert Gordon 					    xdr__e__read4resuio_clnt_fail,
3350*0a701b1eSRobert Gordon 					    int, ocount,
3351*0a701b1eSRobert Gordon 					    int, objp->data_len);
3352*0a701b1eSRobert Gordon 					objp->wlist = NULL;
3353*0a701b1eSRobert Gordon 					return (FALSE);
3354*0a701b1eSRobert Gordon 				}
3355*0a701b1eSRobert Gordon 
3356*0a701b1eSRobert Gordon 				uiop->uio_resid -= objp->data_len;
3357*0a701b1eSRobert Gordon 				uiop->uio_iov->iov_len -= objp->data_len;
3358*0a701b1eSRobert Gordon 				uiop->uio_iov->iov_base += objp->data_len;
3359*0a701b1eSRobert Gordon 				uiop->uio_loffset += objp->data_len;
3360*0a701b1eSRobert Gordon 
3361*0a701b1eSRobert Gordon 				objp->wlist = NULL;
3362*0a701b1eSRobert Gordon 				return (TRUE);
3363*0a701b1eSRobert Gordon 			}
3364*0a701b1eSRobert Gordon 		}
3365*0a701b1eSRobert Gordon 
33667c478bd9Sstevel@tonic-gate 		/*
3367*0a701b1eSRobert Gordon 		 * This isn't an xdrmblk stream nor RDMA.
3368*0a701b1eSRobert Gordon 		 * Handle the likely case that it can be
3369*0a701b1eSRobert Gordon 		 * inlined (ex. xdrmem).
33707c478bd9Sstevel@tonic-gate 		 */
33717c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&objp->data_len))
33727c478bd9Sstevel@tonic-gate 			return (FALSE);
33737c478bd9Sstevel@tonic-gate 
33747c478bd9Sstevel@tonic-gate 		if (objp->data_len == 0)
33757c478bd9Sstevel@tonic-gate 			return (TRUE);
33767c478bd9Sstevel@tonic-gate 
33777c478bd9Sstevel@tonic-gate 		if (objp->data_len > size)
33787c478bd9Sstevel@tonic-gate 			return (FALSE);
33797c478bd9Sstevel@tonic-gate 
33807c478bd9Sstevel@tonic-gate 		size = (int)objp->data_len;
33817c478bd9Sstevel@tonic-gate 		if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
33827c478bd9Sstevel@tonic-gate 			return (uiomove(ptr, size, UIO_READ, uiop) ?
3383*0a701b1eSRobert Gordon 			    FALSE : TRUE);
33847c478bd9Sstevel@tonic-gate 
33857c478bd9Sstevel@tonic-gate 		/*
33867c478bd9Sstevel@tonic-gate 		 * Handle some other (unlikely) stream type that will
33877c478bd9Sstevel@tonic-gate 		 * need a copy.
33887c478bd9Sstevel@tonic-gate 		 */
33897c478bd9Sstevel@tonic-gate 		if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
33907c478bd9Sstevel@tonic-gate 			return (FALSE);
33917c478bd9Sstevel@tonic-gate 
33927c478bd9Sstevel@tonic-gate 		if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
33937c478bd9Sstevel@tonic-gate 			kmem_free(ptr, size);
33947c478bd9Sstevel@tonic-gate 			return (FALSE);
33957c478bd9Sstevel@tonic-gate 		}
33967c478bd9Sstevel@tonic-gate 		error = uiomove(ptr, size, UIO_READ, uiop);
33977c478bd9Sstevel@tonic-gate 		kmem_free(ptr, size);
33987c478bd9Sstevel@tonic-gate 
33997c478bd9Sstevel@tonic-gate 		return (error ? FALSE : TRUE);
34007c478bd9Sstevel@tonic-gate 	}
34017c478bd9Sstevel@tonic-gate 
34027c478bd9Sstevel@tonic-gate 	/*
34037c478bd9Sstevel@tonic-gate 	 * Check for the other special case of the caller providing
34047c478bd9Sstevel@tonic-gate 	 * the target area for the data.
34057c478bd9Sstevel@tonic-gate 	 */
3406*0a701b1eSRobert Gordon 	if (aobjp->res_data_val_alt == NULL)
3407*0a701b1eSRobert Gordon 		return (FALSE);
34087c478bd9Sstevel@tonic-gate 
3409*0a701b1eSRobert Gordon 	/*
3410*0a701b1eSRobert Gordon 	 * If read data received via RDMA_WRITE, don't do xdr_bytes().
3411*0a701b1eSRobert Gordon 	 * RDMA_WRITE already moved the data so decode length of
3412*0a701b1eSRobert Gordon 	 * RDMA_WRITE.
3413*0a701b1eSRobert Gordon 	 */
3414*0a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops) {
3415*0a701b1eSRobert Gordon 		struct clist *cl;
3416*0a701b1eSRobert Gordon 
3417*0a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
3418*0a701b1eSRobert Gordon 
3419*0a701b1eSRobert Gordon 		objp->wlist = cl;
3420*0a701b1eSRobert Gordon 
3421*0a701b1eSRobert Gordon 		/*
3422*0a701b1eSRobert Gordon 		 * Data transferred through inline if
3423*0a701b1eSRobert Gordon 		 * objp->wlist == NULL
3424*0a701b1eSRobert Gordon 		 */
3425*0a701b1eSRobert Gordon 		if (objp->wlist) {
3426*0a701b1eSRobert Gordon 			/* opaque count */
3427*0a701b1eSRobert Gordon 			if (!xdr_u_int(xdrs, &ocount)) {
3428*0a701b1eSRobert Gordon 				objp->wlist = NULL;
3429*0a701b1eSRobert Gordon 				return (FALSE);
3430*0a701b1eSRobert Gordon 			}
3431*0a701b1eSRobert Gordon 
3432*0a701b1eSRobert Gordon 			objp->wlist_len = cl->c_len;
3433*0a701b1eSRobert Gordon 			objp->data_len = objp->wlist_len;
3434*0a701b1eSRobert Gordon 
3435*0a701b1eSRobert Gordon 			if (ocount != objp->data_len) {
3436*0a701b1eSRobert Gordon 				DTRACE_PROBE2(
3437*0a701b1eSRobert Gordon 				    xdr__e__read4res_clnt_fail,
3438*0a701b1eSRobert Gordon 				    int, ocount,
3439*0a701b1eSRobert Gordon 				    int, objp->data_len);
3440*0a701b1eSRobert Gordon 				objp->wlist = NULL;
3441*0a701b1eSRobert Gordon 				return (FALSE);
3442*0a701b1eSRobert Gordon 			}
3443*0a701b1eSRobert Gordon 
3444*0a701b1eSRobert Gordon 			objp->wlist = NULL;
3445*0a701b1eSRobert Gordon 			return (TRUE);
3446*0a701b1eSRobert Gordon 		}
3447*0a701b1eSRobert Gordon 	}
3448*0a701b1eSRobert Gordon 
3449*0a701b1eSRobert Gordon 	return (xdr_bytes(xdrs, (char **)&aobjp->res_data_val_alt,
3450*0a701b1eSRobert Gordon 	    (uint_t *)&objp->data_len,
3451*0a701b1eSRobert Gordon 	    aobjp->res_maxsize));
34527c478bd9Sstevel@tonic-gate }
34537c478bd9Sstevel@tonic-gate 
34547c478bd9Sstevel@tonic-gate static bool_t
34557c478bd9Sstevel@tonic-gate xdr_READDIR4args(XDR *xdrs, READDIR4args *objp)
34567c478bd9Sstevel@tonic-gate {
3457*0a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
3458*0a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
3459*0a701b1eSRobert Gordon 
3460*0a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
3461*0a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
3462*0a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
3463*0a701b1eSRobert Gordon 		rci.rci_len = objp->maxcount;
3464*0a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
3465*0a701b1eSRobert Gordon 	}
3466*0a701b1eSRobert Gordon 
34677c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookie))
34687c478bd9Sstevel@tonic-gate 		return (FALSE);
34697c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
34707c478bd9Sstevel@tonic-gate 		return (FALSE);
34717c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->dircount))
34727c478bd9Sstevel@tonic-gate 		return (FALSE);
34737c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->maxcount))
34747c478bd9Sstevel@tonic-gate 		return (FALSE);
34757c478bd9Sstevel@tonic-gate 	return (xdr_bitmap4(xdrs, &objp->attr_request));
34767c478bd9Sstevel@tonic-gate }
34777c478bd9Sstevel@tonic-gate 
34787c478bd9Sstevel@tonic-gate /* ARGSUSED */
34797c478bd9Sstevel@tonic-gate static bool_t
34807c478bd9Sstevel@tonic-gate xdrmblk_putmblk_rd(XDR *xdrs, mblk_t *m)
34817c478bd9Sstevel@tonic-gate {
34827c478bd9Sstevel@tonic-gate 	if (((m->b_wptr - m->b_rptr) % BYTES_PER_XDR_UNIT) != 0)
34837c478bd9Sstevel@tonic-gate 		return (FALSE);
34847c478bd9Sstevel@tonic-gate 
34857c478bd9Sstevel@tonic-gate 	/* LINTED pointer alignment */
34867c478bd9Sstevel@tonic-gate 	((mblk_t *)xdrs->x_base)->b_cont = m;
34877c478bd9Sstevel@tonic-gate 	xdrs->x_base = (caddr_t)m;
34887c478bd9Sstevel@tonic-gate 	xdrs->x_handy = 0;
34897c478bd9Sstevel@tonic-gate 	return (TRUE);
34907c478bd9Sstevel@tonic-gate }
34917c478bd9Sstevel@tonic-gate 
34927c478bd9Sstevel@tonic-gate bool_t
34937c478bd9Sstevel@tonic-gate xdr_READDIR4res(XDR *xdrs, READDIR4res *objp)
34947c478bd9Sstevel@tonic-gate {
34957c478bd9Sstevel@tonic-gate 	mblk_t *mp = objp->mblk;
34967c478bd9Sstevel@tonic-gate 	bool_t ret_val;
34977c478bd9Sstevel@tonic-gate 	uint_t flags = 0;
34987c478bd9Sstevel@tonic-gate 
34997c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
35007c478bd9Sstevel@tonic-gate 
35017c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
35027c478bd9Sstevel@tonic-gate 		return (FALSE);
35037c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
35047c478bd9Sstevel@tonic-gate 		return (TRUE);
35057c478bd9Sstevel@tonic-gate 	if (mp == NULL)
35067c478bd9Sstevel@tonic-gate 		return (FALSE);
35077c478bd9Sstevel@tonic-gate 
35087c478bd9Sstevel@tonic-gate 	if (xdrs->x_ops == &xdrmblk_ops) {
35097c478bd9Sstevel@tonic-gate 		if (xdrmblk_putmblk_rd(xdrs, mp)
3510*0a701b1eSRobert Gordon 		    == TRUE) {
35117c478bd9Sstevel@tonic-gate 			/* mblk successfully inserted into outgoing chain */
35127c478bd9Sstevel@tonic-gate 			objp->mblk = NULL;
35137c478bd9Sstevel@tonic-gate 			return (TRUE);
35147c478bd9Sstevel@tonic-gate 		}
35157c478bd9Sstevel@tonic-gate 	}
35167c478bd9Sstevel@tonic-gate 
35177c478bd9Sstevel@tonic-gate 	ASSERT(mp->b_cont == NULL);
35187c478bd9Sstevel@tonic-gate 
35197c478bd9Sstevel@tonic-gate 	/*
3520*0a701b1eSRobert Gordon 	 * If transport is RDMA, the pre-encoded m_blk needs to be moved
35217c478bd9Sstevel@tonic-gate 	 * without being chunked.
3522*0a701b1eSRobert Gordon 	 * Check if chunking is enabled for the xdr stream.
3523*0a701b1eSRobert Gordon 	 * If it is enabled, disable it temporarily for this op,
3524*0a701b1eSRobert Gordon 	 * then re-enable.
35257c478bd9Sstevel@tonic-gate 	 */
3526*0a701b1eSRobert Gordon 	XDR_CONTROL(xdrs, XDR_RDMA_GET_FLAGS, &flags);
3527*0a701b1eSRobert Gordon 
3528*0a701b1eSRobert Gordon 	if (!(flags & XDR_RDMA_CHUNK))
35297c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len));
35307c478bd9Sstevel@tonic-gate 
3531*0a701b1eSRobert Gordon 	flags &= ~XDR_RDMA_CHUNK;
3532*0a701b1eSRobert Gordon 
3533*0a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
3534*0a701b1eSRobert Gordon 
35357c478bd9Sstevel@tonic-gate 	ret_val = xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len);
3536*0a701b1eSRobert Gordon 
3537*0a701b1eSRobert Gordon 	flags |= XDR_RDMA_CHUNK;
3538*0a701b1eSRobert Gordon 
3539*0a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
3540*0a701b1eSRobert Gordon 
35417c478bd9Sstevel@tonic-gate 	return (ret_val);
35427c478bd9Sstevel@tonic-gate }
35437c478bd9Sstevel@tonic-gate 
35447c478bd9Sstevel@tonic-gate static bool_t
35457c478bd9Sstevel@tonic-gate xdr_READLINK4res(XDR *xdrs, READLINK4res *objp)
35467c478bd9Sstevel@tonic-gate {
35477c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
35487c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
35497c478bd9Sstevel@tonic-gate 			return (FALSE);
35507c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
35517c478bd9Sstevel@tonic-gate 			return (TRUE);
35527c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->link.utf8string_val,
3553*0a701b1eSRobert Gordon 		    (uint_t *)&objp->link.utf8string_len,
3554*0a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
35557c478bd9Sstevel@tonic-gate 	}
35567c478bd9Sstevel@tonic-gate 
35577c478bd9Sstevel@tonic-gate 	/*
35587c478bd9Sstevel@tonic-gate 	 * Optimized free case
35597c478bd9Sstevel@tonic-gate 	 */
35607c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
35617c478bd9Sstevel@tonic-gate 		return (TRUE);
35627c478bd9Sstevel@tonic-gate 	if (objp->link.utf8string_val != NULL)
35637c478bd9Sstevel@tonic-gate 		kmem_free(objp->link.utf8string_val, objp->link.utf8string_len);
35647c478bd9Sstevel@tonic-gate 	return (TRUE);
35657c478bd9Sstevel@tonic-gate }
35667c478bd9Sstevel@tonic-gate 
35677c478bd9Sstevel@tonic-gate static bool_t
35687c478bd9Sstevel@tonic-gate xdr_REMOVE4res(XDR *xdrs, REMOVE4res *objp)
35697c478bd9Sstevel@tonic-gate {
35707c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
35717c478bd9Sstevel@tonic-gate 		return (FALSE);
35727c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
35737c478bd9Sstevel@tonic-gate 		return (TRUE);
35747c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
35757c478bd9Sstevel@tonic-gate 		return (FALSE);
35767c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
35777c478bd9Sstevel@tonic-gate 		return (FALSE);
35787c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs,
3579*0a701b1eSRobert Gordon 	    (u_longlong_t *)&objp->cinfo.after));
35807c478bd9Sstevel@tonic-gate }
35817c478bd9Sstevel@tonic-gate 
35827c478bd9Sstevel@tonic-gate static bool_t
35837c478bd9Sstevel@tonic-gate xdr_RENAME4res(XDR *xdrs, RENAME4res *objp)
35847c478bd9Sstevel@tonic-gate {
35857c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
35867c478bd9Sstevel@tonic-gate 		return (FALSE);
35877c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
35887c478bd9Sstevel@tonic-gate 		return (TRUE);
35897c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->source_cinfo.atomic))
35907c478bd9Sstevel@tonic-gate 		return (FALSE);
35917c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs,
35927c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->source_cinfo.before))
35937c478bd9Sstevel@tonic-gate 		return (FALSE);
35947c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs,
35957c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->source_cinfo.after))
35967c478bd9Sstevel@tonic-gate 		return (FALSE);
35977c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->target_cinfo.atomic))
35987c478bd9Sstevel@tonic-gate 		return (FALSE);
35997c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs,
36007c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->target_cinfo.before))
36017c478bd9Sstevel@tonic-gate 		return (FALSE);
36027c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs,
3603*0a701b1eSRobert Gordon 	    (u_longlong_t *)&objp->target_cinfo.after));
36047c478bd9Sstevel@tonic-gate }
36057c478bd9Sstevel@tonic-gate 
36067c478bd9Sstevel@tonic-gate static bool_t
36077c478bd9Sstevel@tonic-gate xdr_secinfo4(XDR *xdrs, secinfo4 *objp)
36087c478bd9Sstevel@tonic-gate {
36097c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
36107c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->flavor))
36117c478bd9Sstevel@tonic-gate 			return (FALSE);
36127c478bd9Sstevel@tonic-gate 		if (objp->flavor != RPCSEC_GSS)
36137c478bd9Sstevel@tonic-gate 			return (TRUE);
36147c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs,
3615*0a701b1eSRobert Gordon 		    (char **)&objp->flavor_info.oid.sec_oid4_val,
3616*0a701b1eSRobert Gordon 		    (uint_t *)&objp->flavor_info.oid.sec_oid4_len,
3617*0a701b1eSRobert Gordon 		    NFS4_MAX_SECOID4))
36187c478bd9Sstevel@tonic-gate 			return (FALSE);
36197c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->flavor_info.qop))
36207c478bd9Sstevel@tonic-gate 			return (FALSE);
36217c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs, (int *)&objp->flavor_info.service));
36227c478bd9Sstevel@tonic-gate 	}
36237c478bd9Sstevel@tonic-gate 
36247c478bd9Sstevel@tonic-gate 	/*
36257c478bd9Sstevel@tonic-gate 	 * Optimized free path
36267c478bd9Sstevel@tonic-gate 	 */
36277c478bd9Sstevel@tonic-gate 	if (objp->flavor != RPCSEC_GSS)
36287c478bd9Sstevel@tonic-gate 		return (TRUE);
36297c478bd9Sstevel@tonic-gate 
36307c478bd9Sstevel@tonic-gate 	if (objp->flavor_info.oid.sec_oid4_val != NULL)
36317c478bd9Sstevel@tonic-gate 		kmem_free(objp->flavor_info.oid.sec_oid4_val,
3632*0a701b1eSRobert Gordon 		    objp->flavor_info.oid.sec_oid4_len);
36337c478bd9Sstevel@tonic-gate 	return (TRUE);
36347c478bd9Sstevel@tonic-gate }
36357c478bd9Sstevel@tonic-gate 
36367c478bd9Sstevel@tonic-gate static bool_t
36377c478bd9Sstevel@tonic-gate xdr_SETCLIENTID4args(XDR *xdrs, SETCLIENTID4args *objp)
36387c478bd9Sstevel@tonic-gate {
36397c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
36407c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
3641*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->client.verifier))
36427c478bd9Sstevel@tonic-gate 			return (FALSE);
36437c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->client.id_val,
3644*0a701b1eSRobert Gordon 		    (uint_t *)&objp->client.id_len, NFS4_OPAQUE_LIMIT))
36457c478bd9Sstevel@tonic-gate 			return (FALSE);
36467c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->callback.cb_program))
36477c478bd9Sstevel@tonic-gate 			return (FALSE);
36487c478bd9Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_netid,
3649*0a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT))
36507c478bd9Sstevel@tonic-gate 			return (FALSE);
36517c478bd9Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_addr,
3652*0a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT))
36537c478bd9Sstevel@tonic-gate 			return (FALSE);
36547c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->callback_ident));
36557c478bd9Sstevel@tonic-gate 	}
36567c478bd9Sstevel@tonic-gate 
36577c478bd9Sstevel@tonic-gate 	/*
36587c478bd9Sstevel@tonic-gate 	 * Optimized free case
36597c478bd9Sstevel@tonic-gate 	 */
36607c478bd9Sstevel@tonic-gate 	if (objp->client.id_val != NULL)
36617c478bd9Sstevel@tonic-gate 		kmem_free(objp->client.id_val, objp->client.id_len);
36627c478bd9Sstevel@tonic-gate 	(void) xdr_string(xdrs, &objp->callback.cb_location.r_netid,
3663*0a701b1eSRobert Gordon 	    NFS4_OPAQUE_LIMIT);
36647c478bd9Sstevel@tonic-gate 	return (xdr_string(xdrs, &objp->callback.cb_location.r_addr,
3665*0a701b1eSRobert Gordon 	    NFS4_OPAQUE_LIMIT));
36667c478bd9Sstevel@tonic-gate }
36677c478bd9Sstevel@tonic-gate 
36687c478bd9Sstevel@tonic-gate static bool_t
36697c478bd9Sstevel@tonic-gate xdr_SETCLIENTID4res(XDR *xdrs, SETCLIENTID4res *objp)
36707c478bd9Sstevel@tonic-gate {
36717c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
36727c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
36737c478bd9Sstevel@tonic-gate 			return (FALSE);
36747c478bd9Sstevel@tonic-gate 		switch (objp->status) {
36757c478bd9Sstevel@tonic-gate 		case NFS4_OK:
36767c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
36777c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.resok4.
36787c478bd9Sstevel@tonic-gate 			    clientid))
36797c478bd9Sstevel@tonic-gate 				return (FALSE);
36807c478bd9Sstevel@tonic-gate 			return (xdr_u_longlong_t(xdrs,
36817c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.
3682*0a701b1eSRobert Gordon 			    resok4.setclientid_confirm));
36837c478bd9Sstevel@tonic-gate 		case NFS4ERR_CLID_INUSE:
36847c478bd9Sstevel@tonic-gate 			if (!xdr_string(xdrs,
3685*0a701b1eSRobert Gordon 			    &objp->SETCLIENTID4res_u.client_using.
3686*0a701b1eSRobert Gordon 			    r_netid, NFS4_OPAQUE_LIMIT))
36877c478bd9Sstevel@tonic-gate 				return (FALSE);
36887c478bd9Sstevel@tonic-gate 			return (xdr_string(xdrs,
3689*0a701b1eSRobert Gordon 			    &objp->SETCLIENTID4res_u.client_using.
3690*0a701b1eSRobert Gordon 			    r_addr, NFS4_OPAQUE_LIMIT));
36917c478bd9Sstevel@tonic-gate 		}
36927c478bd9Sstevel@tonic-gate 		return (TRUE);
36937c478bd9Sstevel@tonic-gate 	}
36947c478bd9Sstevel@tonic-gate 
36957c478bd9Sstevel@tonic-gate 	/*
36967c478bd9Sstevel@tonic-gate 	 * Optimized free case
36977c478bd9Sstevel@tonic-gate 	 */
36987c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4ERR_CLID_INUSE)
36997c478bd9Sstevel@tonic-gate 		return (TRUE);
37007c478bd9Sstevel@tonic-gate 
37017c478bd9Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_netid,
3702*0a701b1eSRobert Gordon 	    NFS4_OPAQUE_LIMIT))
37037c478bd9Sstevel@tonic-gate 		return (FALSE);
37047c478bd9Sstevel@tonic-gate 	return (xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_addr,
3705*0a701b1eSRobert Gordon 	    NFS4_OPAQUE_LIMIT));
37067c478bd9Sstevel@tonic-gate }
37077c478bd9Sstevel@tonic-gate 
37087c478bd9Sstevel@tonic-gate static bool_t
37097c478bd9Sstevel@tonic-gate xdr_WRITE4args(XDR *xdrs, WRITE4args *objp)
37107c478bd9Sstevel@tonic-gate {
37117c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
37127c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
37137c478bd9Sstevel@tonic-gate 			return (FALSE);
37147c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->stateid.other, 12))
37157c478bd9Sstevel@tonic-gate 			return (FALSE);
37167c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
37177c478bd9Sstevel@tonic-gate 			return (FALSE);
37187c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->stable))
37197c478bd9Sstevel@tonic-gate 			return (FALSE);
37207c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
37217c478bd9Sstevel@tonic-gate 			if (xdrs->x_ops == &xdrmblk_ops) {
37227c478bd9Sstevel@tonic-gate 				objp->data_val = NULL;
37237c478bd9Sstevel@tonic-gate 				return (xdrmblk_getmblk(xdrs, &objp->mblk,
3724*0a701b1eSRobert Gordon 				    &objp->data_len));
37257c478bd9Sstevel@tonic-gate 			}
37267c478bd9Sstevel@tonic-gate 			objp->mblk = NULL;
3727*0a701b1eSRobert Gordon 			if (xdrs->x_ops == &xdrrdmablk_ops) {
3728*0a701b1eSRobert Gordon 				int retval;
3729*0a701b1eSRobert Gordon 				retval = xdrrdma_getrdmablk(xdrs,
3730*0a701b1eSRobert Gordon 				    &objp->rlist,
3731*0a701b1eSRobert Gordon 				    &objp->data_len,
3732*0a701b1eSRobert Gordon 				    &objp->conn, NFS4_DATA_LIMIT);
3733*0a701b1eSRobert Gordon 				if (retval == FALSE)
3734*0a701b1eSRobert Gordon 					return (FALSE);
3735*0a701b1eSRobert Gordon 				return (xdrrdma_read_from_client(&objp->rlist,
3736*0a701b1eSRobert Gordon 				    &objp->conn, objp->data_len));
3737*0a701b1eSRobert Gordon 			}
37387c478bd9Sstevel@tonic-gate 		}
3739*0a701b1eSRobert Gordon 		/* Else fall thru for the xdr_bytes(). */
37407c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->data_val,
3741*0a701b1eSRobert Gordon 		    (uint_t *)&objp->data_len, NFS4_DATA_LIMIT));
3742*0a701b1eSRobert Gordon 	}
3743*0a701b1eSRobert Gordon 	if (objp->rlist != NULL) {
3744*0a701b1eSRobert Gordon 		(void) xdrrdma_free_clist(objp->conn, objp->rlist);
3745*0a701b1eSRobert Gordon 		objp->rlist = NULL;
3746*0a701b1eSRobert Gordon 		objp->data_val = NULL;
3747*0a701b1eSRobert Gordon 
3748*0a701b1eSRobert Gordon 		return (TRUE);
37497c478bd9Sstevel@tonic-gate 	}
37507c478bd9Sstevel@tonic-gate 
37517c478bd9Sstevel@tonic-gate 	/*
37527c478bd9Sstevel@tonic-gate 	 * Optimized free case
37537c478bd9Sstevel@tonic-gate 	 */
37547c478bd9Sstevel@tonic-gate 	if (objp->data_val != NULL)
37557c478bd9Sstevel@tonic-gate 		kmem_free(objp->data_val, objp->data_len);
37567c478bd9Sstevel@tonic-gate 	return (TRUE);
37577c478bd9Sstevel@tonic-gate }
37587c478bd9Sstevel@tonic-gate 
37597c478bd9Sstevel@tonic-gate static bool_t
37607c478bd9Sstevel@tonic-gate xdr_WRITE4res(XDR *xdrs, WRITE4res *objp)
37617c478bd9Sstevel@tonic-gate {
37627c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
37637c478bd9Sstevel@tonic-gate 		return (FALSE);
37647c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
37657c478bd9Sstevel@tonic-gate 		return (TRUE);
37667c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->count))
37677c478bd9Sstevel@tonic-gate 		return (FALSE);
37687c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->committed))
37697c478bd9Sstevel@tonic-gate 		return (FALSE);
37707c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs,
3771*0a701b1eSRobert Gordon 	    (u_longlong_t *)&objp->writeverf));
37727c478bd9Sstevel@tonic-gate }
37737c478bd9Sstevel@tonic-gate 
37747c478bd9Sstevel@tonic-gate static bool_t
37757c46fb7fSek xdr_snfs_argop4_free(XDR *xdrs, nfs_argop4 **arrayp, int len)
37767c478bd9Sstevel@tonic-gate {
37777c478bd9Sstevel@tonic-gate 	int i;
37787c478bd9Sstevel@tonic-gate 	nfs_argop4 *array = *arrayp;
37797c478bd9Sstevel@tonic-gate 
37807c478bd9Sstevel@tonic-gate 	/*
37817c478bd9Sstevel@tonic-gate 	 * Optimized XDR_FREE only args array
37827c478bd9Sstevel@tonic-gate 	 */
37837c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_FREE);
37847c478bd9Sstevel@tonic-gate 
37857c478bd9Sstevel@tonic-gate 	/*
37867c478bd9Sstevel@tonic-gate 	 * Nothing to do?
37877c478bd9Sstevel@tonic-gate 	 */
37887c478bd9Sstevel@tonic-gate 	if (array == NULL)
37897c478bd9Sstevel@tonic-gate 		return (TRUE);
37907c478bd9Sstevel@tonic-gate 
37917c478bd9Sstevel@tonic-gate 	for (i = 0; i < len; i++) {
37927c478bd9Sstevel@tonic-gate 		/*
37937c478bd9Sstevel@tonic-gate 		 * These should be ordered by frequency of use
37947c478bd9Sstevel@tonic-gate 		 */
37957c478bd9Sstevel@tonic-gate 		switch (array[i].argop) {
37967c478bd9Sstevel@tonic-gate 		case OP_PUTFH:
37977c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.opputfh.object.nfs_fh4_val !=
3798*0a701b1eSRobert Gordon 			    NULL) {
37997c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.opputfh.object.
3800*0a701b1eSRobert Gordon 				    nfs_fh4_val,
3801*0a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.opputfh.object.
3802*0a701b1eSRobert Gordon 				    nfs_fh4_len);
38037c478bd9Sstevel@tonic-gate 			}
38047c478bd9Sstevel@tonic-gate 			continue;
38057c478bd9Sstevel@tonic-gate 		case OP_GETATTR:
38067c478bd9Sstevel@tonic-gate 		case OP_GETFH:
38077c478bd9Sstevel@tonic-gate 			continue;
38087c478bd9Sstevel@tonic-gate 		case OP_LOOKUP:
38097c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oplookup.objname.
3810*0a701b1eSRobert Gordon 			    utf8string_val != NULL) {
38117c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oplookup.
3812*0a701b1eSRobert Gordon 				    objname.utf8string_val,
3813*0a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.oplookup.
3814*0a701b1eSRobert Gordon 				    objname.utf8string_len);
38157c478bd9Sstevel@tonic-gate 			}
38167c478bd9Sstevel@tonic-gate 			continue;
38177c478bd9Sstevel@tonic-gate 		case OP_OPEN:
38187c478bd9Sstevel@tonic-gate 			(void) xdr_OPEN4args(xdrs,
3819*0a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opopen);
38207c478bd9Sstevel@tonic-gate 			continue;
38217c478bd9Sstevel@tonic-gate 		case OP_CLOSE:
38227c478bd9Sstevel@tonic-gate 		case OP_ACCESS:
38237c478bd9Sstevel@tonic-gate 		case OP_READ:
38247c478bd9Sstevel@tonic-gate 			continue;
38257c478bd9Sstevel@tonic-gate 		case OP_WRITE:
38267c478bd9Sstevel@tonic-gate 			(void) xdr_WRITE4args(xdrs,
3827*0a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opwrite);
38287c478bd9Sstevel@tonic-gate 			continue;
38297c478bd9Sstevel@tonic-gate 		case OP_DELEGRETURN:
38307c478bd9Sstevel@tonic-gate 		case OP_LOOKUPP:
38317c478bd9Sstevel@tonic-gate 		case OP_READDIR:
38327c478bd9Sstevel@tonic-gate 			continue;
38337c478bd9Sstevel@tonic-gate 		case OP_REMOVE:
38347c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.opremove.target.
3835*0a701b1eSRobert Gordon 			    utf8string_val != NULL) {
38367c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.opremove.target.
3837*0a701b1eSRobert Gordon 				    utf8string_val,
3838*0a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.opremove.target.
3839*0a701b1eSRobert Gordon 				    utf8string_len);
38407c478bd9Sstevel@tonic-gate 			}
38417c478bd9Sstevel@tonic-gate 			continue;
38427c478bd9Sstevel@tonic-gate 		case OP_COMMIT:
38437c478bd9Sstevel@tonic-gate 			continue;
38447c478bd9Sstevel@tonic-gate 		case OP_CREATE:
38457c478bd9Sstevel@tonic-gate 			(void) xdr_CREATE4args(xdrs,
3846*0a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opcreate);
38477c478bd9Sstevel@tonic-gate 			continue;
38487c478bd9Sstevel@tonic-gate 		case OP_DELEGPURGE:
38497c478bd9Sstevel@tonic-gate 			continue;
38507c478bd9Sstevel@tonic-gate 		case OP_LINK:
38517c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oplink.newname.
3852*0a701b1eSRobert Gordon 			    utf8string_val != NULL) {
38537c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oplink.newname.
3854*0a701b1eSRobert Gordon 				    utf8string_val,
3855*0a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.oplink.newname.
3856*0a701b1eSRobert Gordon 				    utf8string_len);
38577c478bd9Sstevel@tonic-gate 			}
38587c478bd9Sstevel@tonic-gate 			continue;
38597c478bd9Sstevel@tonic-gate 		case OP_LOCK:
38607c478bd9Sstevel@tonic-gate 			(void) xdr_LOCK4args(xdrs,
3861*0a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.oplock);
38627c478bd9Sstevel@tonic-gate 			continue;
38637c478bd9Sstevel@tonic-gate 		case OP_LOCKT:
38647c478bd9Sstevel@tonic-gate 			(void) xdr_LOCKT4args(xdrs,
3865*0a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.oplockt);
38667c478bd9Sstevel@tonic-gate 			continue;
38677c478bd9Sstevel@tonic-gate 		case OP_LOCKU:
38687c478bd9Sstevel@tonic-gate 			continue;
38697c478bd9Sstevel@tonic-gate 		case OP_NVERIFY:
38707c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
38717c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opnverify.obj_attributes);
38727c478bd9Sstevel@tonic-gate 			continue;
38737c478bd9Sstevel@tonic-gate 		case OP_OPENATTR:
38747c478bd9Sstevel@tonic-gate 		case OP_OPEN_CONFIRM:
38757c478bd9Sstevel@tonic-gate 		case OP_OPEN_DOWNGRADE:
38767c478bd9Sstevel@tonic-gate 		case OP_PUTPUBFH:
38777c478bd9Sstevel@tonic-gate 		case OP_PUTROOTFH:
38787c478bd9Sstevel@tonic-gate 		case OP_READLINK:
38797c478bd9Sstevel@tonic-gate 			continue;
38807c478bd9Sstevel@tonic-gate 		case OP_RENAME:
38817c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oprename.oldname.
3882*0a701b1eSRobert Gordon 			    utf8string_val != NULL) {
38837c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oprename.
3884*0a701b1eSRobert Gordon 				    oldname.utf8string_val,
3885*0a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.oprename.
3886*0a701b1eSRobert Gordon 				    oldname.utf8string_len);
38877c478bd9Sstevel@tonic-gate 			}
38887c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oprename.newname.
3889*0a701b1eSRobert Gordon 			    utf8string_val != NULL) {
38907c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oprename.
3891*0a701b1eSRobert Gordon 				    newname.utf8string_val,
3892*0a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.oprename.
3893*0a701b1eSRobert Gordon 				    newname.utf8string_len);
38947c478bd9Sstevel@tonic-gate 			}
38957c478bd9Sstevel@tonic-gate 			continue;
38967c478bd9Sstevel@tonic-gate 		case OP_RENEW:
38977c478bd9Sstevel@tonic-gate 		case OP_RESTOREFH:
38987c478bd9Sstevel@tonic-gate 		case OP_SAVEFH:
38997c478bd9Sstevel@tonic-gate 			continue;
39007c478bd9Sstevel@tonic-gate 		case OP_SECINFO:
39017c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.opsecinfo.name.
3902*0a701b1eSRobert Gordon 			    utf8string_val != NULL) {
39037c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.opsecinfo.name.
3904*0a701b1eSRobert Gordon 				    utf8string_val,
3905*0a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.opsecinfo.name.
3906*0a701b1eSRobert Gordon 				    utf8string_len);
39077c478bd9Sstevel@tonic-gate 			}
39087c478bd9Sstevel@tonic-gate 			continue;
39097c478bd9Sstevel@tonic-gate 		case OP_SETATTR:
39107c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
39117c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opsetattr.obj_attributes);
39127c478bd9Sstevel@tonic-gate 			continue;
39137c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID:
39147c478bd9Sstevel@tonic-gate 			(void) xdr_SETCLIENTID4args(xdrs,
3915*0a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opsetclientid);
39167c478bd9Sstevel@tonic-gate 			continue;
39177c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID_CONFIRM:
39187c478bd9Sstevel@tonic-gate 			continue;
39197c478bd9Sstevel@tonic-gate 		case OP_VERIFY:
39207c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
3921*0a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opverify.obj_attributes);
39227c478bd9Sstevel@tonic-gate 			continue;
39237c478bd9Sstevel@tonic-gate 		case OP_RELEASE_LOCKOWNER:
39247c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oprelease_lockowner.
3925*0a701b1eSRobert Gordon 			    lock_owner.owner_val != NULL) {
39267c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.
39277c478bd9Sstevel@tonic-gate 				    oprelease_lockowner.lock_owner.owner_val,
3928*0a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.
39297c478bd9Sstevel@tonic-gate 				    oprelease_lockowner.lock_owner.owner_len);
39307c478bd9Sstevel@tonic-gate 			}
39317c478bd9Sstevel@tonic-gate 			continue;
39327c478bd9Sstevel@tonic-gate 		case OP_ILLEGAL:
39337c478bd9Sstevel@tonic-gate 			continue;
39347c478bd9Sstevel@tonic-gate 		default:
39357c478bd9Sstevel@tonic-gate 			/*
39367c478bd9Sstevel@tonic-gate 			 * An invalid op is a coding error, it should never
39377c478bd9Sstevel@tonic-gate 			 * have been decoded.
39387c478bd9Sstevel@tonic-gate 			 * Don't error because the caller cannot finish
39397c478bd9Sstevel@tonic-gate 			 * freeing the residual memory of the array.
39407c478bd9Sstevel@tonic-gate 			 */
39417c478bd9Sstevel@tonic-gate 			continue;
39427c478bd9Sstevel@tonic-gate 		}
39437c478bd9Sstevel@tonic-gate 	}
39447c478bd9Sstevel@tonic-gate 
39457c478bd9Sstevel@tonic-gate 	kmem_free(*arrayp, len * sizeof (nfs_argop4));
39467c478bd9Sstevel@tonic-gate 	*arrayp = NULL;
39477c478bd9Sstevel@tonic-gate 	return (TRUE);
39487c478bd9Sstevel@tonic-gate }
39497c478bd9Sstevel@tonic-gate 
39507c478bd9Sstevel@tonic-gate static bool_t
39517c478bd9Sstevel@tonic-gate xdr_nfs_argop4(XDR *xdrs, nfs_argop4 *objp)
39527c478bd9Sstevel@tonic-gate {
3953*0a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
3954*0a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
3955*0a701b1eSRobert Gordon 
39567c478bd9Sstevel@tonic-gate 	/*
39577c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
39587c478bd9Sstevel@tonic-gate 	 */
39597c478bd9Sstevel@tonic-gate 	switch (objp->argop) {
39607c478bd9Sstevel@tonic-gate 	case OP_PUTFH:
39617c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
39627c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_val,
39637c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_len,
39647c478bd9Sstevel@tonic-gate 		    NFS4_FHSIZE));
39657c478bd9Sstevel@tonic-gate 	case OP_GETATTR:
39667c478bd9Sstevel@tonic-gate 		return (xdr_bitmap4(xdrs,
3967*0a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opgetattr.attr_request));
39687c478bd9Sstevel@tonic-gate 	case OP_GETFH:
39697c478bd9Sstevel@tonic-gate 		return (TRUE);
39707c478bd9Sstevel@tonic-gate 	case OP_LOOKUP:
39717c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oplookup.
3972*0a701b1eSRobert Gordon 		    objname.utf8string_val,
3973*0a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.oplookup.
3974*0a701b1eSRobert Gordon 		    objname.utf8string_len,
3975*0a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
39767c478bd9Sstevel@tonic-gate 	case OP_OPEN:
39777c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4args(xdrs, &objp->nfs_argop4_u.opopen));
39787c478bd9Sstevel@tonic-gate 	case OP_CLOSE:
39797c478bd9Sstevel@tonic-gate 		return (xdr_CLOSE4args(xdrs, &objp->nfs_argop4_u.opclose));
39807c478bd9Sstevel@tonic-gate 	case OP_ACCESS:
39817c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs,
3982*0a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opaccess.access));
39837c478bd9Sstevel@tonic-gate 	case OP_READ:
39847c478bd9Sstevel@tonic-gate 		return (xdr_READ4args(xdrs, &objp->nfs_argop4_u.opread));
39857c478bd9Sstevel@tonic-gate 	case OP_WRITE:
39867c478bd9Sstevel@tonic-gate 		return (xdr_WRITE4args(xdrs, &objp->nfs_argop4_u.opwrite));
39877c478bd9Sstevel@tonic-gate 	case OP_DELEGRETURN:
39887c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs,
39897c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opdelegreturn.deleg_stateid.seqid))
39907c478bd9Sstevel@tonic-gate 			return (FALSE);
39917c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs,
39927c478bd9Sstevel@tonic-gate 		    objp->nfs_argop4_u.opdelegreturn.deleg_stateid.other, 12));
39937c478bd9Sstevel@tonic-gate 	case OP_LOOKUPP:
39947c478bd9Sstevel@tonic-gate 		return (TRUE);
39957c478bd9Sstevel@tonic-gate 	case OP_READDIR:
39967c478bd9Sstevel@tonic-gate 		return (xdr_READDIR4args(xdrs, &objp->nfs_argop4_u.opreaddir));
39977c478bd9Sstevel@tonic-gate 	case OP_REMOVE:
39987c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.opremove.
3999*0a701b1eSRobert Gordon 		    target.utf8string_val,
4000*0a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.opremove.
4001*0a701b1eSRobert Gordon 		    target.utf8string_len,
4002*0a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
40037c478bd9Sstevel@tonic-gate 	case OP_COMMIT:
40047c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
40057c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_argop4_u.opcommit.offset))
40067c478bd9Sstevel@tonic-gate 			return (FALSE);
40077c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opcommit.count));
40087c478bd9Sstevel@tonic-gate 	case OP_CREATE:
40097c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4args(xdrs, &objp->nfs_argop4_u.opcreate));
40107c478bd9Sstevel@tonic-gate 	case OP_DELEGPURGE:
40117c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
40127c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_argop4_u.opdelegpurge.clientid));
40137c478bd9Sstevel@tonic-gate 	case OP_LINK:
40147c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
40157c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.oplink.newname.utf8string_val,
40167c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.oplink.newname.utf8string_len,
40177c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
40187c478bd9Sstevel@tonic-gate 	case OP_LOCK:
40197c478bd9Sstevel@tonic-gate 		return (xdr_LOCK4args(xdrs, &objp->nfs_argop4_u.oplock));
40207c478bd9Sstevel@tonic-gate 	case OP_LOCKT:
40217c478bd9Sstevel@tonic-gate 		return (xdr_LOCKT4args(xdrs, &objp->nfs_argop4_u.oplockt));
40227c478bd9Sstevel@tonic-gate 	case OP_LOCKU:
40237c478bd9Sstevel@tonic-gate 		return (xdr_LOCKU4args(xdrs, &objp->nfs_argop4_u.oplocku));
40247c478bd9Sstevel@tonic-gate 	case OP_NVERIFY:
40257c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
4026*0a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opnverify.obj_attributes));
40277c478bd9Sstevel@tonic-gate 	case OP_OPENATTR:
40287c478bd9Sstevel@tonic-gate 		return (xdr_bool(xdrs,
4029*0a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opopenattr.createdir));
40307c478bd9Sstevel@tonic-gate 	case OP_OPEN_CONFIRM:
40317c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
4032*0a701b1eSRobert Gordon 		    open_stateid.seqid))
40337c478bd9Sstevel@tonic-gate 			return (FALSE);
40347c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opopen_confirm.
4035*0a701b1eSRobert Gordon 		    open_stateid.other, 12))
40367c478bd9Sstevel@tonic-gate 			return (FALSE);
40377c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
4038*0a701b1eSRobert Gordon 		    seqid));
40397c478bd9Sstevel@tonic-gate 	case OP_OPEN_DOWNGRADE:
40407c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_DOWNGRADE4args(xdrs,
4041*0a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opopen_downgrade));
40427c478bd9Sstevel@tonic-gate 	case OP_PUTPUBFH:
40437c478bd9Sstevel@tonic-gate 		return (TRUE);
40447c478bd9Sstevel@tonic-gate 	case OP_PUTROOTFH:
40457c478bd9Sstevel@tonic-gate 		return (TRUE);
40467c478bd9Sstevel@tonic-gate 	case OP_READLINK:
4047*0a701b1eSRobert Gordon 		if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
4048*0a701b1eSRobert Gordon 		    xdrs->x_op == XDR_ENCODE) {
4049*0a701b1eSRobert Gordon 			rci.rci_type = RCI_REPLY_CHUNK;
4050*0a701b1eSRobert Gordon 			rci.rci_len = MAXPATHLEN;
4051*0a701b1eSRobert Gordon 			XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
4052*0a701b1eSRobert Gordon 		}
40537c478bd9Sstevel@tonic-gate 		return (TRUE);
40547c478bd9Sstevel@tonic-gate 	case OP_RENAME:
40557c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
4056*0a701b1eSRobert Gordon 		    oldname.utf8string_val,
4057*0a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.oprename.
4058*0a701b1eSRobert Gordon 		    oldname.utf8string_len,
4059*0a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING))
40607c478bd9Sstevel@tonic-gate 			return (FALSE);
40617c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
4062*0a701b1eSRobert Gordon 		    newname.utf8string_val,
4063*0a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.oprename.
4064*0a701b1eSRobert Gordon 		    newname.utf8string_len,
4065*0a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
40667c478bd9Sstevel@tonic-gate 	case OP_RENEW:
40677c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
4068*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_argop4_u.oprenew.clientid));
40697c478bd9Sstevel@tonic-gate 	case OP_RESTOREFH:
40707c478bd9Sstevel@tonic-gate 		return (TRUE);
40717c478bd9Sstevel@tonic-gate 	case OP_SAVEFH:
40727c478bd9Sstevel@tonic-gate 		return (TRUE);
40737c478bd9Sstevel@tonic-gate 	case OP_SECINFO:
40747c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
40757c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.opsecinfo.name.utf8string_val,
40767c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.opsecinfo.name.utf8string_len,
40777c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
40787c478bd9Sstevel@tonic-gate 	case OP_SETATTR:
40797c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opsetattr.
4080*0a701b1eSRobert Gordon 		    stateid.seqid))
40817c478bd9Sstevel@tonic-gate 			return (FALSE);
40827c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opsetattr.
4083*0a701b1eSRobert Gordon 		    stateid.other, 12))
40847c478bd9Sstevel@tonic-gate 			return (FALSE);
40857c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs, &objp->nfs_argop4_u.opsetattr.
4086*0a701b1eSRobert Gordon 		    obj_attributes));
40877c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID:
40887c478bd9Sstevel@tonic-gate 		return (xdr_SETCLIENTID4args(xdrs,
4089*0a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opsetclientid));
40907c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID_CONFIRM:
40917c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->nfs_argop4_u.
4092*0a701b1eSRobert Gordon 		    opsetclientid_confirm.clientid))
40937c478bd9Sstevel@tonic-gate 			return (FALSE);
40947c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
4095*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_argop4_u.
4096*0a701b1eSRobert Gordon 		    opsetclientid_confirm.setclientid_confirm));
40977c478bd9Sstevel@tonic-gate 	case OP_VERIFY:
40987c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
4099*0a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opverify.obj_attributes));
41007c478bd9Sstevel@tonic-gate 	case OP_RELEASE_LOCKOWNER:
41017c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
4102*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_argop4_u.
4103*0a701b1eSRobert Gordon 		    oprelease_lockowner.lock_owner.clientid))
41047c478bd9Sstevel@tonic-gate 			return (FALSE);
41057c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
4106*0a701b1eSRobert Gordon 		    (char **)&objp->nfs_argop4_u.oprelease_lockowner.
4107*0a701b1eSRobert Gordon 		    lock_owner.owner_val,
4108*0a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.oprelease_lockowner.
4109*0a701b1eSRobert Gordon 		    lock_owner.owner_len, NFS4_OPAQUE_LIMIT));
41107c478bd9Sstevel@tonic-gate 	case OP_ILLEGAL:
41117c478bd9Sstevel@tonic-gate 		return (TRUE);
41127c478bd9Sstevel@tonic-gate 	}
41137c478bd9Sstevel@tonic-gate 	return (FALSE);
41147c478bd9Sstevel@tonic-gate }
41157c478bd9Sstevel@tonic-gate 
41167c46fb7fSek static bool_t
41177c46fb7fSek xdr_cnfs_argop4_wrap(XDR *xdrs, nfs_argop4 *objp)
41187c46fb7fSek {
41197c46fb7fSek 	if (!xdr_int(xdrs, (int *)&objp->argop))
41207c46fb7fSek 		return (FALSE);
41217c46fb7fSek 
41227c46fb7fSek 	return (xdr_nfs_argop4(xdrs, objp));
41237c46fb7fSek }
41247c46fb7fSek 
41257c46fb7fSek static bool_t
41267c46fb7fSek xdr_snfs_argop4(XDR *xdrs, nfs_argop4 *objp)
41277c46fb7fSek {
41287c46fb7fSek 	if (!xdr_int(xdrs, (int *)&objp->argop))
41297c46fb7fSek 		return (FALSE);
41307c46fb7fSek 
41317c46fb7fSek 	switch (objp->argop) {
41327c46fb7fSek 	case OP_PUTFH:
41337c46fb7fSek 		return (xdr_decode_nfs_fh4(xdrs,
4134*0a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opputfh.object));
41357c46fb7fSek 	default:
41367c46fb7fSek 		return (xdr_nfs_argop4(xdrs, objp));
41377c46fb7fSek 	}
41387c46fb7fSek }
41397c46fb7fSek 
41407c478bd9Sstevel@tonic-gate /*
41417c478bd9Sstevel@tonic-gate  * Client side encode only arg op processing
41427c478bd9Sstevel@tonic-gate  */
41437c478bd9Sstevel@tonic-gate static bool_t
41447c478bd9Sstevel@tonic-gate xdr_cnfs_argop4(XDR *xdrs, nfs_argop4 *objp)
41457c478bd9Sstevel@tonic-gate {
41467c478bd9Sstevel@tonic-gate 	int len;
41477c478bd9Sstevel@tonic-gate 	int op;
41487c478bd9Sstevel@tonic-gate 	nfs4_sharedfh_t *sfh;
41497c478bd9Sstevel@tonic-gate 	mntinfo4_t *mi;
41507c478bd9Sstevel@tonic-gate 	rpc_inline_t *ptr;
41517c478bd9Sstevel@tonic-gate 
41527c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
41537c478bd9Sstevel@tonic-gate 
41547c478bd9Sstevel@tonic-gate 	/*
41557c478bd9Sstevel@tonic-gate 	 * Special case the private pseudo ops
41567c478bd9Sstevel@tonic-gate 	 */
41577c478bd9Sstevel@tonic-gate 	if (!(objp->argop & SUNW_PRIVATE_OP))
41587c46fb7fSek 		return (xdr_cnfs_argop4_wrap(xdrs, objp));
41597c478bd9Sstevel@tonic-gate 
41607c478bd9Sstevel@tonic-gate 	/*
41617c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
41627c478bd9Sstevel@tonic-gate 	 */
41637c478bd9Sstevel@tonic-gate 	switch (objp->argop) {
41647c478bd9Sstevel@tonic-gate 	case OP_CPUTFH:
41657c478bd9Sstevel@tonic-gate 		/*
41667c478bd9Sstevel@tonic-gate 		 * We are passed in the file handle as a nfs4_sharedfh_t *
41677c478bd9Sstevel@tonic-gate 		 * We need to acquire the correct locks so we can copy it out.
41687c478bd9Sstevel@tonic-gate 		 */
41697c478bd9Sstevel@tonic-gate 		sfh = (nfs4_sharedfh_t *)objp->nfs_argop4_u.opcputfh.sfh;
41707c478bd9Sstevel@tonic-gate 		mi = sfh->sfh_mi;
41717c478bd9Sstevel@tonic-gate 		(void) nfs_rw_enter_sig(&mi->mi_fh_lock, RW_READER, 0);
41727c478bd9Sstevel@tonic-gate 
41737c478bd9Sstevel@tonic-gate 		len = sfh->sfh_fh.nfs_fh4_len;
41747c478bd9Sstevel@tonic-gate 		ASSERT(len <= NFS4_FHSIZE);
41757c478bd9Sstevel@tonic-gate 
41767c478bd9Sstevel@tonic-gate 		/*
41777c478bd9Sstevel@tonic-gate 		 * First try and inline the copy
41787c478bd9Sstevel@tonic-gate 		 * Must first be a multiple of BYTES_PER_XDR_UNIT
41797c478bd9Sstevel@tonic-gate 		 */
41807c478bd9Sstevel@tonic-gate 		if (!(len % BYTES_PER_XDR_UNIT) &&
41817c478bd9Sstevel@tonic-gate 		    (ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + len)) !=
4182*0a701b1eSRobert Gordon 		    NULL) {
41837c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, OP_PUTFH);
41847c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, len);
41857c478bd9Sstevel@tonic-gate 			bcopy(sfh->sfh_fh.nfs_fh4_val, ptr, len);
41867c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
41877c478bd9Sstevel@tonic-gate 			return (TRUE);
41887c478bd9Sstevel@tonic-gate 		}
41897c478bd9Sstevel@tonic-gate 
41907c478bd9Sstevel@tonic-gate 		op = OP_PUTFH;
41917c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &op)) {
41927c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
41937c478bd9Sstevel@tonic-gate 			return (FALSE);
41947c478bd9Sstevel@tonic-gate 		}
41957c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len)) {
41967c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
41977c478bd9Sstevel@tonic-gate 			return (FALSE);
41987c478bd9Sstevel@tonic-gate 		}
41997c478bd9Sstevel@tonic-gate 		if (!(len % BYTES_PER_XDR_UNIT)) {
42007c478bd9Sstevel@tonic-gate 			if (XDR_PUTBYTES(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
42017c478bd9Sstevel@tonic-gate 				nfs_rw_exit(&mi->mi_fh_lock);
42027c478bd9Sstevel@tonic-gate 				return (TRUE);
42037c478bd9Sstevel@tonic-gate 			}
42047c478bd9Sstevel@tonic-gate 		} else if (xdr_opaque(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
42057c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
42067c478bd9Sstevel@tonic-gate 			return (TRUE);
42077c478bd9Sstevel@tonic-gate 		}
42087c478bd9Sstevel@tonic-gate 		nfs_rw_exit(&mi->mi_fh_lock);
42097c478bd9Sstevel@tonic-gate 		return (FALSE);
42107c478bd9Sstevel@tonic-gate 	case OP_CLOOKUP:
42117c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opclookup.cname);
42127c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
42137c478bd9Sstevel@tonic-gate 			return (FALSE);
42147c478bd9Sstevel@tonic-gate 		op = OP_LOOKUP;
42157c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
42167c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
42177c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
4218*0a701b1eSRobert Gordon 				    objp->nfs_argop4_u.opclookup.cname,
4219*0a701b1eSRobert Gordon 				    len));
42207c478bd9Sstevel@tonic-gate 			}
42217c478bd9Sstevel@tonic-gate 		}
42227c478bd9Sstevel@tonic-gate 		return (FALSE);
42237c478bd9Sstevel@tonic-gate 	case OP_COPEN:
42247c478bd9Sstevel@tonic-gate 		/* op processing inlined in xdr_OPEN4cargs */
42257c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4cargs(xdrs, &objp->nfs_argop4_u.opcopen));
42267c478bd9Sstevel@tonic-gate 	case OP_CREMOVE:
42277c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcremove.ctarget);
42287c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
42297c478bd9Sstevel@tonic-gate 			return (FALSE);
42307c478bd9Sstevel@tonic-gate 		op = OP_REMOVE;
42317c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
42327c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
42337c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
4234*0a701b1eSRobert Gordon 				    objp->nfs_argop4_u.opcremove.ctarget,
4235*0a701b1eSRobert Gordon 				    len));
42367c478bd9Sstevel@tonic-gate 			}
42377c478bd9Sstevel@tonic-gate 		}
42387c478bd9Sstevel@tonic-gate 		return (FALSE);
42397c478bd9Sstevel@tonic-gate 	case OP_CCREATE:
42407c478bd9Sstevel@tonic-gate 		op = OP_CREATE;
42417c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &op))
42427c478bd9Sstevel@tonic-gate 			return (FALSE);
42437c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4cargs(xdrs, &objp->nfs_argop4_u.opccreate));
42447c478bd9Sstevel@tonic-gate 	case OP_CLINK:
42457c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opclink.cnewname);
42467c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
42477c478bd9Sstevel@tonic-gate 			return (FALSE);
42487c478bd9Sstevel@tonic-gate 		op = OP_LINK;
42497c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
42507c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
42517c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
4252*0a701b1eSRobert Gordon 				    objp->nfs_argop4_u.opclink.cnewname,
4253*0a701b1eSRobert Gordon 				    len));
42547c478bd9Sstevel@tonic-gate 			}
42557c478bd9Sstevel@tonic-gate 		}
42567c478bd9Sstevel@tonic-gate 		return (FALSE);
42577c478bd9Sstevel@tonic-gate 	case OP_CRENAME:
42587c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcrename.coldname);
42597c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
42607c478bd9Sstevel@tonic-gate 			return (FALSE);
42617c478bd9Sstevel@tonic-gate 		op = OP_RENAME;
42627c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &op))
42637c478bd9Sstevel@tonic-gate 			return (FALSE);
42647c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len))
42657c478bd9Sstevel@tonic-gate 			return (FALSE);
42667c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs,
4267*0a701b1eSRobert Gordon 		    objp->nfs_argop4_u.opcrename.coldname, len))
42687c478bd9Sstevel@tonic-gate 			return (FALSE);
42697c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcrename.cnewname);
42707c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
42717c478bd9Sstevel@tonic-gate 			return (FALSE);
42727c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
42737c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
4274*0a701b1eSRobert Gordon 			    objp->nfs_argop4_u.opcrename.cnewname, len));
42757c478bd9Sstevel@tonic-gate 		}
42767c478bd9Sstevel@tonic-gate 		return (FALSE);
42777c478bd9Sstevel@tonic-gate 	case OP_CSECINFO:
42787c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcsecinfo.cname);
42797c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
42807c478bd9Sstevel@tonic-gate 			return (FALSE);
42817c478bd9Sstevel@tonic-gate 		op = OP_SECINFO;
42827c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
42837c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
42847c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
4285*0a701b1eSRobert Gordon 				    objp->nfs_argop4_u.opcsecinfo.cname,
4286*0a701b1eSRobert Gordon 				    len));
42877c478bd9Sstevel@tonic-gate 			}
42887c478bd9Sstevel@tonic-gate 		}
42897c478bd9Sstevel@tonic-gate 		return (FALSE);
42907c478bd9Sstevel@tonic-gate 	}
42917c478bd9Sstevel@tonic-gate 	return (FALSE);
42927c478bd9Sstevel@tonic-gate }
42937c478bd9Sstevel@tonic-gate 
42947c478bd9Sstevel@tonic-gate /*
42957c478bd9Sstevel@tonic-gate  * Note that the len and decode_len will only be different in the case
42967c478bd9Sstevel@tonic-gate  * of the client's use of this free function.  If the server is
42977c478bd9Sstevel@tonic-gate  * freeing results, then the len/decode_len will always match.
42987c478bd9Sstevel@tonic-gate  */
42997c478bd9Sstevel@tonic-gate static bool_t
43007c478bd9Sstevel@tonic-gate xdr_nfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
43017c478bd9Sstevel@tonic-gate {
43027c478bd9Sstevel@tonic-gate 	int i;
43037c478bd9Sstevel@tonic-gate 	nfs_resop4 *array = *arrayp;
43047c478bd9Sstevel@tonic-gate 
43057c478bd9Sstevel@tonic-gate 	/*
43067c478bd9Sstevel@tonic-gate 	 * Optimized XDR_FREE only results array
43077c478bd9Sstevel@tonic-gate 	 */
43087c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_FREE);
43097c478bd9Sstevel@tonic-gate 
43107c478bd9Sstevel@tonic-gate 	if (array == NULL)
43117c478bd9Sstevel@tonic-gate 		return (TRUE);
43127c478bd9Sstevel@tonic-gate 
43137c478bd9Sstevel@tonic-gate 	for (i = 0; i < decode_len; i++) {
43147c478bd9Sstevel@tonic-gate 		/*
43157c478bd9Sstevel@tonic-gate 		 * These should be ordered by frequency of use
43167c478bd9Sstevel@tonic-gate 		 */
43177c478bd9Sstevel@tonic-gate 		switch (array[i].resop) {
43187c478bd9Sstevel@tonic-gate 		case OP_PUTFH:
43197c478bd9Sstevel@tonic-gate 			continue;
43207c478bd9Sstevel@tonic-gate 		case OP_GETATTR:
43217c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetattr.status != NFS4_OK)
43227c478bd9Sstevel@tonic-gate 				continue;
43237c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetattr.ga_res.n4g_ext_res)
43247c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_resop4_u.opgetattr.
4325*0a701b1eSRobert Gordon 				    ga_res.n4g_ext_res,
4326*0a701b1eSRobert Gordon 				    sizeof (struct nfs4_ga_ext_res));
43277c478bd9Sstevel@tonic-gate 			continue;
43287c478bd9Sstevel@tonic-gate 		case OP_GETFH:
43297c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetfh.status != NFS4_OK)
43307c478bd9Sstevel@tonic-gate 				continue;
43317c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetfh.object.nfs_fh4_val !=
4332*0a701b1eSRobert Gordon 			    NULL) {
43337c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_resop4_u.opgetfh.object.
4334*0a701b1eSRobert Gordon 				    nfs_fh4_val,
4335*0a701b1eSRobert Gordon 				    array[i].nfs_resop4_u.opgetfh.object.
4336*0a701b1eSRobert Gordon 				    nfs_fh4_len);
43377c478bd9Sstevel@tonic-gate 			}
43387c478bd9Sstevel@tonic-gate 			continue;
43397c478bd9Sstevel@tonic-gate 		case OP_LOOKUP:
43407c478bd9Sstevel@tonic-gate 			continue;
43417c478bd9Sstevel@tonic-gate 		case OP_OPEN:
43427c478bd9Sstevel@tonic-gate 			(void) xdr_OPEN4res(xdrs, &array[i].nfs_resop4_u.
4343*0a701b1eSRobert Gordon 			    opopen);
43447c478bd9Sstevel@tonic-gate 			continue;
43457c478bd9Sstevel@tonic-gate 		case OP_CLOSE:
43467c478bd9Sstevel@tonic-gate 		case OP_ACCESS:
43477c478bd9Sstevel@tonic-gate 			continue;
43487c478bd9Sstevel@tonic-gate 		case OP_READ:
43497c478bd9Sstevel@tonic-gate 			(void) xdr_READ4res(xdrs,
4350*0a701b1eSRobert Gordon 			    &array[i].nfs_resop4_u.opread);
43517c478bd9Sstevel@tonic-gate 			continue;
43527c478bd9Sstevel@tonic-gate 		case OP_WRITE:
43537c478bd9Sstevel@tonic-gate 		case OP_DELEGRETURN:
43547c478bd9Sstevel@tonic-gate 		case OP_LOOKUPP:
43557c478bd9Sstevel@tonic-gate 		case OP_READDIR:
43567c478bd9Sstevel@tonic-gate 		case OP_REMOVE:
43577c478bd9Sstevel@tonic-gate 		case OP_COMMIT:
43587c478bd9Sstevel@tonic-gate 		case OP_CREATE:
43597c478bd9Sstevel@tonic-gate 		case OP_DELEGPURGE:
43607c478bd9Sstevel@tonic-gate 		case OP_LINK:
43617c478bd9Sstevel@tonic-gate 			continue;
43627c478bd9Sstevel@tonic-gate 		case OP_LOCK:
43637c478bd9Sstevel@tonic-gate 			(void) xdr_LOCK4res(xdrs, &array[i].nfs_resop4_u.
4364*0a701b1eSRobert Gordon 			    oplock);
43657c478bd9Sstevel@tonic-gate 			continue;
43667c478bd9Sstevel@tonic-gate 		case OP_LOCKT:
43677c478bd9Sstevel@tonic-gate 			(void) xdr_LOCKT4res(xdrs, &array[i].nfs_resop4_u.
4368*0a701b1eSRobert Gordon 			    oplockt);
43697c478bd9Sstevel@tonic-gate 			continue;
43707c478bd9Sstevel@tonic-gate 		case OP_LOCKU:
43717c478bd9Sstevel@tonic-gate 		case OP_NVERIFY:
43727c478bd9Sstevel@tonic-gate 		case OP_OPENATTR:
43737c478bd9Sstevel@tonic-gate 		case OP_OPEN_CONFIRM:
43747c478bd9Sstevel@tonic-gate 		case OP_OPEN_DOWNGRADE:
43757c478bd9Sstevel@tonic-gate 		case OP_PUTPUBFH:
43767c478bd9Sstevel@tonic-gate 		case OP_PUTROOTFH:
43777c478bd9Sstevel@tonic-gate 		case OP_RENAME:
43787c478bd9Sstevel@tonic-gate 		case OP_RENEW:
43797c478bd9Sstevel@tonic-gate 		case OP_RESTOREFH:
43807c478bd9Sstevel@tonic-gate 		case OP_SAVEFH:
43817c478bd9Sstevel@tonic-gate 			continue;
43827c478bd9Sstevel@tonic-gate 		case OP_READLINK:
43837c478bd9Sstevel@tonic-gate 			(void) xdr_READLINK4res(xdrs, &array[i].nfs_resop4_u.
4384*0a701b1eSRobert Gordon 			    opreadlink);
43857c478bd9Sstevel@tonic-gate 			continue;
43867c478bd9Sstevel@tonic-gate 		case OP_SECINFO:
43877c478bd9Sstevel@tonic-gate 			(void) xdr_array(xdrs,
4388*0a701b1eSRobert Gordon 			    (char **)&array[i].nfs_resop4_u.opsecinfo.
4389*0a701b1eSRobert Gordon 			    SECINFO4resok_val,
4390*0a701b1eSRobert Gordon 			    (uint_t *)&array[i].nfs_resop4_u.opsecinfo.
4391*0a701b1eSRobert Gordon 			    SECINFO4resok_len,
4392*0a701b1eSRobert Gordon 			    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
4393*0a701b1eSRobert Gordon 			    (xdrproc_t)xdr_secinfo4);
43947c478bd9Sstevel@tonic-gate 			continue;
43957c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID:
43967c478bd9Sstevel@tonic-gate 			(void) xdr_SETCLIENTID4res(xdrs,
4397*0a701b1eSRobert Gordon 			    &array[i].nfs_resop4_u.opsetclientid);
43987c478bd9Sstevel@tonic-gate 			continue;
43997c478bd9Sstevel@tonic-gate 		case OP_SETATTR:
44007c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID_CONFIRM:
44017c478bd9Sstevel@tonic-gate 		case OP_VERIFY:
44027c478bd9Sstevel@tonic-gate 		case OP_RELEASE_LOCKOWNER:
44037c478bd9Sstevel@tonic-gate 		case OP_ILLEGAL:
44047c478bd9Sstevel@tonic-gate 			continue;
44057c478bd9Sstevel@tonic-gate 		default:
44067c478bd9Sstevel@tonic-gate 			/*
44077c478bd9Sstevel@tonic-gate 			 * An invalid op is a coding error, it should never
44087c478bd9Sstevel@tonic-gate 			 * have been decoded.
44097c478bd9Sstevel@tonic-gate 			 * Don't error because the caller cannot finish
44107c478bd9Sstevel@tonic-gate 			 * freeing the residual memory of the array.
44117c478bd9Sstevel@tonic-gate 			 */
44127c478bd9Sstevel@tonic-gate 			continue;
44137c478bd9Sstevel@tonic-gate 		}
44147c478bd9Sstevel@tonic-gate 	}
44157c478bd9Sstevel@tonic-gate 
44167c478bd9Sstevel@tonic-gate 	kmem_free(*arrayp, len * sizeof (nfs_resop4));
44177c478bd9Sstevel@tonic-gate 	*arrayp = NULL;
44187c478bd9Sstevel@tonic-gate 	return (TRUE);
44197c478bd9Sstevel@tonic-gate }
44207c478bd9Sstevel@tonic-gate 
44217c46fb7fSek static bool_t
44227c46fb7fSek xdr_snfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
44237c46fb7fSek {
44247c46fb7fSek 	return (xdr_nfs_resop4_free(xdrs, arrayp, len, decode_len));
44257c46fb7fSek }
44267c46fb7fSek 
44277c478bd9Sstevel@tonic-gate static bool_t
44287c478bd9Sstevel@tonic-gate xdr_nfs_resop4(XDR *xdrs, nfs_resop4 *objp)
44297c478bd9Sstevel@tonic-gate {
44307c478bd9Sstevel@tonic-gate 	/*
44317c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
44327c478bd9Sstevel@tonic-gate 	 */
44337c478bd9Sstevel@tonic-gate 	switch (objp->resop) {
44347c478bd9Sstevel@tonic-gate 	case OP_PUTFH:
44357c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4436*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
44377c478bd9Sstevel@tonic-gate 	case OP_GETATTR:
44387c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
4439*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
44407c478bd9Sstevel@tonic-gate 			return (FALSE);
44417c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
44427c478bd9Sstevel@tonic-gate 			return (TRUE);
44437c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
4444*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opgetattr.obj_attributes));
44457c478bd9Sstevel@tonic-gate 	case OP_GETFH:
44467c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
4447*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
44487c478bd9Sstevel@tonic-gate 			return (FALSE);
44497c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
44507c478bd9Sstevel@tonic-gate 			return (TRUE);
44517c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
44527c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
44537c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
44547c478bd9Sstevel@tonic-gate 		    NFS4_FHSIZE));
44557c478bd9Sstevel@tonic-gate 	case OP_LOOKUP:
44567c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4457*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
44587c478bd9Sstevel@tonic-gate 	case OP_OPEN:
44597c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
44607c478bd9Sstevel@tonic-gate 	case OP_CLOSE:
44617c478bd9Sstevel@tonic-gate 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
44627c478bd9Sstevel@tonic-gate 	case OP_ACCESS:
44637c478bd9Sstevel@tonic-gate 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
44647c478bd9Sstevel@tonic-gate 	case OP_READ:
44657c478bd9Sstevel@tonic-gate 		return (xdr_READ4res(xdrs, &objp->nfs_resop4_u.opread));
44667c478bd9Sstevel@tonic-gate 	case OP_WRITE:
44677c478bd9Sstevel@tonic-gate 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
44687c478bd9Sstevel@tonic-gate 	case OP_DELEGRETURN:
44697c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4470*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
44717c478bd9Sstevel@tonic-gate 	case OP_LOOKUPP:
44727c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4473*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
44747c478bd9Sstevel@tonic-gate 	case OP_READDIR:
44757c478bd9Sstevel@tonic-gate 		return (xdr_READDIR4res(xdrs, &objp->nfs_resop4_u.opreaddir));
44767c478bd9Sstevel@tonic-gate 	case OP_REMOVE:
44777c478bd9Sstevel@tonic-gate 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
44787c478bd9Sstevel@tonic-gate 
44797c478bd9Sstevel@tonic-gate 	case OP_COMMIT:
44807c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
4481*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
44827c478bd9Sstevel@tonic-gate 			return (FALSE);
44837c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
44847c478bd9Sstevel@tonic-gate 			return (TRUE);
44857c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
4486*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
4487*0a701b1eSRobert Gordon 		    writeverf));
44887c478bd9Sstevel@tonic-gate 	case OP_CREATE:
44897c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
44907c478bd9Sstevel@tonic-gate 	case OP_DELEGPURGE:
44917c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4492*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
44937c478bd9Sstevel@tonic-gate 	case OP_LINK:
44947c478bd9Sstevel@tonic-gate 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
44957c478bd9Sstevel@tonic-gate 	case OP_LOCK:
44967c478bd9Sstevel@tonic-gate 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
44977c478bd9Sstevel@tonic-gate 	case OP_LOCKT:
44987c478bd9Sstevel@tonic-gate 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
44997c478bd9Sstevel@tonic-gate 	case OP_LOCKU:
45007c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
4501*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
45027c478bd9Sstevel@tonic-gate 			return (FALSE);
45037c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
45047c478bd9Sstevel@tonic-gate 			return (TRUE);
45057c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs,
45067c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
45077c478bd9Sstevel@tonic-gate 			return (FALSE);
45087c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs,
45097c478bd9Sstevel@tonic-gate 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
45107c478bd9Sstevel@tonic-gate 		    12));
45117c478bd9Sstevel@tonic-gate 	case OP_NVERIFY:
45127c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4513*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
45147c478bd9Sstevel@tonic-gate 	case OP_OPENATTR:
45157c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4516*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
45177c478bd9Sstevel@tonic-gate 	case OP_OPEN_CONFIRM:
45187c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_CONFIRM4res(xdrs,
4519*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opopen_confirm));
45207c478bd9Sstevel@tonic-gate 	case OP_OPEN_DOWNGRADE:
45217c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
4522*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opopen_downgrade));
45237c478bd9Sstevel@tonic-gate 	case OP_PUTPUBFH:
45247c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4525*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
45267c478bd9Sstevel@tonic-gate 	case OP_PUTROOTFH:
45277c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4528*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
45297c478bd9Sstevel@tonic-gate 	case OP_READLINK:
45307c478bd9Sstevel@tonic-gate 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
45317c478bd9Sstevel@tonic-gate 	case OP_RENAME:
45327c478bd9Sstevel@tonic-gate 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
45337c478bd9Sstevel@tonic-gate 	case OP_RENEW:
45347c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4535*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
45367c478bd9Sstevel@tonic-gate 	case OP_RESTOREFH:
45377c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4538*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
45397c478bd9Sstevel@tonic-gate 	case OP_SAVEFH:
45407c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4541*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
45427c478bd9Sstevel@tonic-gate 	case OP_SECINFO:
45437c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
4544*0a701b1eSRobert Gordon 		    status))
45457c478bd9Sstevel@tonic-gate 			return (FALSE);
45467c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
45477c478bd9Sstevel@tonic-gate 			return (TRUE);
45487c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
4549*0a701b1eSRobert Gordon 		    SECINFO4resok_val,
4550*0a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
4551*0a701b1eSRobert Gordon 		    SECINFO4resok_len,
4552*0a701b1eSRobert Gordon 		    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
4553*0a701b1eSRobert Gordon 		    (xdrproc_t)xdr_secinfo4));
45547c478bd9Sstevel@tonic-gate 	case OP_SETATTR:
45557c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
4556*0a701b1eSRobert Gordon 		    status))
45577c478bd9Sstevel@tonic-gate 			return (FALSE);
45587c478bd9Sstevel@tonic-gate 		return (xdr_bitmap4(xdrs,
4559*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opsetattr.attrsset));
45607c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID:
45617c478bd9Sstevel@tonic-gate 		return (xdr_SETCLIENTID4res(xdrs,
4562*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opsetclientid));
45637c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID_CONFIRM:
45647c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4565*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
4566*0a701b1eSRobert Gordon 		    status));
45677c478bd9Sstevel@tonic-gate 	case OP_VERIFY:
45687c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4569*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
45707c478bd9Sstevel@tonic-gate 	case OP_RELEASE_LOCKOWNER:
45717c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
45727c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
45737c478bd9Sstevel@tonic-gate 	case OP_ILLEGAL:
45747c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4575*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
45767c478bd9Sstevel@tonic-gate 	}
45777c478bd9Sstevel@tonic-gate 	return (FALSE);
45787c478bd9Sstevel@tonic-gate }
45797c478bd9Sstevel@tonic-gate 
45807c46fb7fSek static bool_t
45817c46fb7fSek xdr_snfs_resop4(XDR *xdrs, nfs_resop4 *objp)
45827c46fb7fSek {
45837c46fb7fSek 	if (!xdr_int(xdrs, (int *)&objp->resop))
45847c46fb7fSek 		return (FALSE);
45857c46fb7fSek 
45867c46fb7fSek 	switch (objp->resop) {
45877c46fb7fSek 	case OP_GETFH:
45887c46fb7fSek 		if (!XDR_PUTINT32(xdrs,
45897c46fb7fSek 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
45907c46fb7fSek 			return (FALSE);
45917c46fb7fSek 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
45927c46fb7fSek 			return (TRUE);
45937c46fb7fSek 		return (xdr_encode_nfs_fh4(xdrs,
4594eac3aab7Srobinson 		    &objp->nfs_resop4_u.opgetfh.object));
45957c46fb7fSek 	default:
45967c46fb7fSek 		return (xdr_nfs_resop4(xdrs, objp));
45977c46fb7fSek 	}
45987c46fb7fSek }
45997c46fb7fSek 
46007c478bd9Sstevel@tonic-gate static bool_t
46017c478bd9Sstevel@tonic-gate xdr_nfs_resop4_clnt(XDR *xdrs, nfs_resop4 *objp, nfs_argop4 *aobjp)
46027c478bd9Sstevel@tonic-gate {
46037c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->resop))
46047c478bd9Sstevel@tonic-gate 		return (FALSE);
46057c478bd9Sstevel@tonic-gate 	/*
46067c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
46077c478bd9Sstevel@tonic-gate 	 */
46087c478bd9Sstevel@tonic-gate 	switch (objp->resop) {
46097c478bd9Sstevel@tonic-gate 	case OP_PUTFH:
46107c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4611*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
46127c478bd9Sstevel@tonic-gate 	case OP_GETATTR:
46137c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
4614*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
46157c478bd9Sstevel@tonic-gate 			return (FALSE);
46167c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
46177c478bd9Sstevel@tonic-gate 			return (TRUE);
46187c478bd9Sstevel@tonic-gate 		return (xdr_ga_res(xdrs,
4619*0a701b1eSRobert Gordon 		    (GETATTR4res *)&objp->nfs_resop4_u.opgetattr,
4620*0a701b1eSRobert Gordon 		    &aobjp->nfs_argop4_u.opgetattr));
46217c478bd9Sstevel@tonic-gate 	case OP_GETFH:
46227c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
4623*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
46247c478bd9Sstevel@tonic-gate 			return (FALSE);
46257c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
46267c478bd9Sstevel@tonic-gate 			return (TRUE);
46277c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
46287c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
46297c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
46307c478bd9Sstevel@tonic-gate 		    NFS4_FHSIZE));
46317c478bd9Sstevel@tonic-gate 	case OP_LOOKUP:
46327c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4633*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
46347c478bd9Sstevel@tonic-gate 	case OP_NVERIFY:
46357c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4636*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
46377c478bd9Sstevel@tonic-gate 	case OP_OPEN:
46387c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
46397c478bd9Sstevel@tonic-gate 	case OP_CLOSE:
46407c478bd9Sstevel@tonic-gate 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
46417c478bd9Sstevel@tonic-gate 	case OP_ACCESS:
46427c478bd9Sstevel@tonic-gate 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
46437c478bd9Sstevel@tonic-gate 	case OP_READ:
46447c478bd9Sstevel@tonic-gate 		return (xdr_READ4res_clnt(xdrs, &objp->nfs_resop4_u.opread,
4645*0a701b1eSRobert Gordon 		    &aobjp->nfs_argop4_u.opread));
46467c478bd9Sstevel@tonic-gate 	case OP_WRITE:
46477c478bd9Sstevel@tonic-gate 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
46487c478bd9Sstevel@tonic-gate 	case OP_DELEGRETURN:
46497c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4650*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
46517c478bd9Sstevel@tonic-gate 	case OP_LOOKUPP:
46527c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4653*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
46547c478bd9Sstevel@tonic-gate 	case OP_READDIR:
46557c478bd9Sstevel@tonic-gate 		return (xdr_READDIR4res_clnt(xdrs,
4656*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opreaddirclnt,
4657*0a701b1eSRobert Gordon 		    &aobjp->nfs_argop4_u.opreaddir));
46587c478bd9Sstevel@tonic-gate 	case OP_REMOVE:
46597c478bd9Sstevel@tonic-gate 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
46607c478bd9Sstevel@tonic-gate 
46617c478bd9Sstevel@tonic-gate 	case OP_COMMIT:
46627c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
4663*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
46647c478bd9Sstevel@tonic-gate 			return (FALSE);
46657c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
46667c478bd9Sstevel@tonic-gate 			return (TRUE);
46677c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
4668*0a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
4669*0a701b1eSRobert Gordon 		    writeverf));
46707c478bd9Sstevel@tonic-gate 	case OP_CREATE:
46717c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
46727c478bd9Sstevel@tonic-gate 	case OP_DELEGPURGE:
46737c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4674*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
46757c478bd9Sstevel@tonic-gate 	case OP_LINK:
46767c478bd9Sstevel@tonic-gate 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
46777c478bd9Sstevel@tonic-gate 	case OP_LOCK:
46787c478bd9Sstevel@tonic-gate 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
46797c478bd9Sstevel@tonic-gate 	case OP_LOCKT:
46807c478bd9Sstevel@tonic-gate 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
46817c478bd9Sstevel@tonic-gate 	case OP_LOCKU:
46827c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
4683*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
46847c478bd9Sstevel@tonic-gate 			return (FALSE);
46857c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
46867c478bd9Sstevel@tonic-gate 			return (TRUE);
46877c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs,
46887c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
46897c478bd9Sstevel@tonic-gate 			return (FALSE);
46907c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs,
46917c478bd9Sstevel@tonic-gate 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
46927c478bd9Sstevel@tonic-gate 		    12));
46937c478bd9Sstevel@tonic-gate 	case OP_OPENATTR:
46947c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4695*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
46967c478bd9Sstevel@tonic-gate 	case OP_OPEN_CONFIRM:
46977c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_CONFIRM4res(xdrs,
4698*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opopen_confirm));
46997c478bd9Sstevel@tonic-gate 	case OP_OPEN_DOWNGRADE:
47007c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
4701*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opopen_downgrade));
47027c478bd9Sstevel@tonic-gate 	case OP_PUTPUBFH:
47037c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4704*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
47057c478bd9Sstevel@tonic-gate 	case OP_PUTROOTFH:
47067c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4707*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
47087c478bd9Sstevel@tonic-gate 	case OP_READLINK:
47097c478bd9Sstevel@tonic-gate 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
47107c478bd9Sstevel@tonic-gate 	case OP_RENAME:
47117c478bd9Sstevel@tonic-gate 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
47127c478bd9Sstevel@tonic-gate 	case OP_RENEW:
47137c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4714*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
47157c478bd9Sstevel@tonic-gate 	case OP_RESTOREFH:
47167c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4717*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
47187c478bd9Sstevel@tonic-gate 	case OP_SAVEFH:
47197c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4720*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
47217c478bd9Sstevel@tonic-gate 	case OP_SECINFO:
47227c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
4723*0a701b1eSRobert Gordon 		    status))
47247c478bd9Sstevel@tonic-gate 			return (FALSE);
47257c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
47267c478bd9Sstevel@tonic-gate 			return (TRUE);
47277c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
4728*0a701b1eSRobert Gordon 		    SECINFO4resok_val,
4729*0a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
4730*0a701b1eSRobert Gordon 		    SECINFO4resok_len,
4731*0a701b1eSRobert Gordon 		    ~0, sizeof (secinfo4), (xdrproc_t)xdr_secinfo4));
47327c478bd9Sstevel@tonic-gate 	case OP_SETATTR:
47337c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
4734*0a701b1eSRobert Gordon 		    status))
47357c478bd9Sstevel@tonic-gate 			return (FALSE);
47367c478bd9Sstevel@tonic-gate 		return (xdr_bitmap4(xdrs,
4737*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opsetattr.attrsset));
47387c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID:
47397c478bd9Sstevel@tonic-gate 		return (xdr_SETCLIENTID4res(xdrs,
4740*0a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opsetclientid));
47417c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID_CONFIRM:
47427c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4743*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
4744*0a701b1eSRobert Gordon 		    status));
47457c478bd9Sstevel@tonic-gate 	case OP_VERIFY:
47467c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4747*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
47487c478bd9Sstevel@tonic-gate 	case OP_RELEASE_LOCKOWNER:
47497c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47507c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
47517c478bd9Sstevel@tonic-gate 	case OP_ILLEGAL:
47527c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
4753*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
47547c478bd9Sstevel@tonic-gate 	}
47557c478bd9Sstevel@tonic-gate 	return (FALSE);
47567c478bd9Sstevel@tonic-gate }
47577c478bd9Sstevel@tonic-gate 
47587c478bd9Sstevel@tonic-gate bool_t
47597c478bd9Sstevel@tonic-gate xdr_COMPOUND4args_clnt(XDR *xdrs, COMPOUND4args_clnt *objp)
47607c478bd9Sstevel@tonic-gate {
47617c478bd9Sstevel@tonic-gate 	static int32_t twelve = 12;
47627c478bd9Sstevel@tonic-gate 	static int32_t minorversion = NFS4_MINORVERSION;
47637c478bd9Sstevel@tonic-gate 	uint32_t *ctagp;
47647c478bd9Sstevel@tonic-gate 	rpc_inline_t *ptr;
4765*0a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
4766*0a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
47677c478bd9Sstevel@tonic-gate 
47687c478bd9Sstevel@tonic-gate 	/*
47697c478bd9Sstevel@tonic-gate 	 * XDR_ENCODE only
47707c478bd9Sstevel@tonic-gate 	 */
47717c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
47727c478bd9Sstevel@tonic-gate 		return (TRUE);
47737c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
47747c478bd9Sstevel@tonic-gate 		return (FALSE);
47757c478bd9Sstevel@tonic-gate 
47767c478bd9Sstevel@tonic-gate 	ctagp = (uint32_t *)&nfs4_ctags[objp->ctag].ct_tag;
47777c478bd9Sstevel@tonic-gate 
47787c478bd9Sstevel@tonic-gate 	if ((ptr = XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT)) != NULL) {
47797c478bd9Sstevel@tonic-gate 		/*
47807c478bd9Sstevel@tonic-gate 		 * Efficiently encode fixed length tags, could be longlongs
47817c478bd9Sstevel@tonic-gate 		 * but 8 byte XDR alignment not assured
47827c478bd9Sstevel@tonic-gate 		 */
47837c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, 12);
47847c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, ctagp[0]);
47857c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, ctagp[1]);
47867c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, ctagp[2]);
47877c478bd9Sstevel@tonic-gate 
47887c478bd9Sstevel@tonic-gate 		/*
47897c478bd9Sstevel@tonic-gate 		 * Fixed minor version for now
47907c478bd9Sstevel@tonic-gate 		 */
47917c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, NFS4_MINORVERSION);
47927c478bd9Sstevel@tonic-gate 	} else {
47937c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &twelve))
47947c478bd9Sstevel@tonic-gate 			return (FALSE);
47957c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[0]))
47967c478bd9Sstevel@tonic-gate 			return (FALSE);
47977c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[1]))
47987c478bd9Sstevel@tonic-gate 			return (FALSE);
47997c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[2]))
48007c478bd9Sstevel@tonic-gate 			return (FALSE);
48017c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&minorversion))
48027c478bd9Sstevel@tonic-gate 			return (FALSE);
48037c478bd9Sstevel@tonic-gate 	}
4804*0a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) {
4805*0a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
4806*0a701b1eSRobert Gordon 		rci.rci_len = MAXPATHLEN * 2;
4807*0a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
4808*0a701b1eSRobert Gordon 	}
48097c478bd9Sstevel@tonic-gate 
48107c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->array,
4811*0a701b1eSRobert Gordon 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
4812*0a701b1eSRobert Gordon 	    sizeof (nfs_argop4), (xdrproc_t)xdr_cnfs_argop4));
48137c478bd9Sstevel@tonic-gate }
48147c478bd9Sstevel@tonic-gate 
48157c478bd9Sstevel@tonic-gate bool_t
48167c46fb7fSek xdr_COMPOUND4args_srv(XDR *xdrs, COMPOUND4args *objp)
48177c478bd9Sstevel@tonic-gate {
48187c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
4819*0a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
4820*0a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
48217c478bd9Sstevel@tonic-gate 		return (FALSE);
48227c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->minorversion))
48237c478bd9Sstevel@tonic-gate 		return (FALSE);
48247c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE)
48257c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->array,
4826*0a701b1eSRobert Gordon 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
4827*0a701b1eSRobert Gordon 		    sizeof (nfs_argop4), (xdrproc_t)xdr_snfs_argop4));
48287c478bd9Sstevel@tonic-gate 
48297c46fb7fSek 	return (xdr_snfs_argop4_free(xdrs, &objp->array, objp->array_len));
48307c478bd9Sstevel@tonic-gate }
48317c478bd9Sstevel@tonic-gate 
48327c478bd9Sstevel@tonic-gate bool_t
48337c478bd9Sstevel@tonic-gate xdr_COMPOUND4res_clnt(XDR *xdrs, COMPOUND4res_clnt *objp)
48347c478bd9Sstevel@tonic-gate {
48357c478bd9Sstevel@tonic-gate 	uint32_t len;
48367c478bd9Sstevel@tonic-gate 	int32_t *ptr;
48377c478bd9Sstevel@tonic-gate 	nfs_argop4 *argop;
48387c478bd9Sstevel@tonic-gate 	nfs_resop4 *resop;
48397c478bd9Sstevel@tonic-gate 
48407c478bd9Sstevel@tonic-gate 	/*
48417c478bd9Sstevel@tonic-gate 	 * No XDR_ENCODE
48427c478bd9Sstevel@tonic-gate 	 */
48437c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
48447c478bd9Sstevel@tonic-gate 		return (FALSE);
48457c478bd9Sstevel@tonic-gate 
48467c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
48477c478bd9Sstevel@tonic-gate 		if ((ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL) {
48487c478bd9Sstevel@tonic-gate 			objp->status = IXDR_GET_U_INT32(ptr);
48497c478bd9Sstevel@tonic-gate 			len = IXDR_GET_U_INT32(ptr);
48507c478bd9Sstevel@tonic-gate 		} else {
48517c478bd9Sstevel@tonic-gate 			if (!xdr_int(xdrs, (int32_t *)&objp->status))
48527c478bd9Sstevel@tonic-gate 				return (FALSE);
48537c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (uint32_t *)&len))
48547c478bd9Sstevel@tonic-gate 				return (FALSE);
48557c478bd9Sstevel@tonic-gate 		}
48567c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
48577c478bd9Sstevel@tonic-gate 			return (FALSE);
48587c478bd9Sstevel@tonic-gate 		/*
48597c478bd9Sstevel@tonic-gate 		 * Ignore the tag
48607c478bd9Sstevel@tonic-gate 		 */
48617c478bd9Sstevel@tonic-gate 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &len))
48627c478bd9Sstevel@tonic-gate 			return (FALSE);
48637c478bd9Sstevel@tonic-gate 
48647c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->array_len))
48657c478bd9Sstevel@tonic-gate 			return (FALSE);
48667c478bd9Sstevel@tonic-gate 
48677c478bd9Sstevel@tonic-gate 		if (objp->array_len > objp->argsp->array_len)
48687c478bd9Sstevel@tonic-gate 			return (FALSE);
48697c478bd9Sstevel@tonic-gate 
48707c478bd9Sstevel@tonic-gate 		if (objp->status == NFS_OK &&
48717c478bd9Sstevel@tonic-gate 		    objp->array_len != objp->argsp->array_len)
48727c478bd9Sstevel@tonic-gate 			return (FALSE);
48737c478bd9Sstevel@tonic-gate 
48747c478bd9Sstevel@tonic-gate 		/* Alloc the results array */
48757c478bd9Sstevel@tonic-gate 		argop = objp->argsp->array;
48767c478bd9Sstevel@tonic-gate 		len = objp->array_len * sizeof (nfs_resop4);
48777c478bd9Sstevel@tonic-gate 		objp->decode_len = 0;
48787c478bd9Sstevel@tonic-gate 		objp->array = resop = kmem_zalloc(len, KM_SLEEP);
48797c478bd9Sstevel@tonic-gate 
48807c478bd9Sstevel@tonic-gate 		for (len = 0; len < objp->array_len;
4881*0a701b1eSRobert Gordon 		    len++, resop++, argop++, objp->decode_len++) {
48827c478bd9Sstevel@tonic-gate 			if (!xdr_nfs_resop4_clnt(xdrs, resop, argop)) {
48837c478bd9Sstevel@tonic-gate 				/*
48847c478bd9Sstevel@tonic-gate 				 * Make sure to free anything that may
48857c478bd9Sstevel@tonic-gate 				 * have been allocated along the way.
48867c478bd9Sstevel@tonic-gate 				 */
48877c478bd9Sstevel@tonic-gate 				xdrs->x_op = XDR_FREE;
48887c478bd9Sstevel@tonic-gate 				(void) xdr_nfs_resop4_free(xdrs, &objp->array,
4889*0a701b1eSRobert Gordon 				    objp->array_len,
4890*0a701b1eSRobert Gordon 				    objp->decode_len);
48917c478bd9Sstevel@tonic-gate 				return (FALSE);
48927c478bd9Sstevel@tonic-gate 			}
48937c478bd9Sstevel@tonic-gate 		}
48947c478bd9Sstevel@tonic-gate 		return (TRUE);
48957c478bd9Sstevel@tonic-gate 	}
48967c478bd9Sstevel@tonic-gate 	return (xdr_nfs_resop4_free(xdrs, &objp->array,
4897*0a701b1eSRobert Gordon 	    objp->array_len, objp->decode_len));
48987c478bd9Sstevel@tonic-gate }
48997c478bd9Sstevel@tonic-gate 
49007c478bd9Sstevel@tonic-gate bool_t
49017c46fb7fSek xdr_COMPOUND4res_srv(XDR *xdrs, COMPOUND4res *objp)
49027c478bd9Sstevel@tonic-gate {
49037c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
49047c478bd9Sstevel@tonic-gate 		return (FALSE);
49057c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
4906*0a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
4907*0a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
49087c478bd9Sstevel@tonic-gate 		return (FALSE);
49097c478bd9Sstevel@tonic-gate 
49107c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE)
49117c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->array,
4912*0a701b1eSRobert Gordon 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
4913*0a701b1eSRobert Gordon 		    sizeof (nfs_resop4), (xdrproc_t)xdr_snfs_resop4));
49147c478bd9Sstevel@tonic-gate 
49157c46fb7fSek 	return (xdr_snfs_resop4_free(xdrs, &objp->array,
4916*0a701b1eSRobert Gordon 	    objp->array_len, objp->array_len));
49177c478bd9Sstevel@tonic-gate }
49187c478bd9Sstevel@tonic-gate 
4919eac3aab7Srobinson /*
4920eac3aab7Srobinson  * NFS server side callback, initiating the callback request so it
4921eac3aab7Srobinson  * is the RPC client. Must convert from server's internal filehandle
4922eac3aab7Srobinson  * format to wire format.
4923eac3aab7Srobinson  */
49247c478bd9Sstevel@tonic-gate static bool_t
4925eac3aab7Srobinson xdr_snfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
49267c478bd9Sstevel@tonic-gate {
4927eac3aab7Srobinson 	CB_GETATTR4args *gargs;
4928eac3aab7Srobinson 	CB_RECALL4args *rargs;
4929eac3aab7Srobinson 
4930eac3aab7Srobinson 	ASSERT(xdrs->x_op == XDR_ENCODE);
4931eac3aab7Srobinson 
4932eac3aab7Srobinson 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->argop))
4933eac3aab7Srobinson 		return (FALSE);
4934eac3aab7Srobinson 
4935eac3aab7Srobinson 	switch (objp->argop) {
4936eac3aab7Srobinson 	case OP_CB_GETATTR:
4937eac3aab7Srobinson 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
4938eac3aab7Srobinson 
4939eac3aab7Srobinson 		if (!xdr_encode_nfs_fh4(xdrs, &gargs->fh))
4940eac3aab7Srobinson 			return (FALSE);
4941eac3aab7Srobinson 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
4942eac3aab7Srobinson 	case OP_CB_RECALL:
4943eac3aab7Srobinson 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
4944eac3aab7Srobinson 
4945eac3aab7Srobinson 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->stateid.seqid))
4946eac3aab7Srobinson 			return (FALSE);
4947eac3aab7Srobinson 		if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
4948eac3aab7Srobinson 			return (FALSE);
4949eac3aab7Srobinson 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->truncate))
4950eac3aab7Srobinson 			return (FALSE);
4951eac3aab7Srobinson 		return (xdr_encode_nfs_fh4(xdrs, &rargs->fh));
4952eac3aab7Srobinson 	case OP_CB_ILLEGAL:
4953eac3aab7Srobinson 		return (TRUE);
4954eac3aab7Srobinson 	}
4955eac3aab7Srobinson 	return (FALSE);
4956eac3aab7Srobinson }
4957eac3aab7Srobinson 
4958eac3aab7Srobinson /*
4959eac3aab7Srobinson  * NFS client side callback, receiving the callback request so it
4960eac3aab7Srobinson  * is the RPC server. Must treat the file handles as opaque.
4961eac3aab7Srobinson  */
4962eac3aab7Srobinson static bool_t
4963eac3aab7Srobinson xdr_cnfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
4964eac3aab7Srobinson {
4965eac3aab7Srobinson 	CB_GETATTR4args *gargs;
4966eac3aab7Srobinson 	CB_RECALL4args *rargs;
4967eac3aab7Srobinson 
4968eac3aab7Srobinson 	ASSERT(xdrs->x_op != XDR_ENCODE);
4969eac3aab7Srobinson 
49707c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->argop))
49717c478bd9Sstevel@tonic-gate 		return (FALSE);
49727c478bd9Sstevel@tonic-gate 	switch (objp->argop) {
49737c478bd9Sstevel@tonic-gate 	case OP_CB_GETATTR:
4974eac3aab7Srobinson 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
4975eac3aab7Srobinson 
4976eac3aab7Srobinson 		if (!xdr_bytes(xdrs, (char **)&gargs->fh.nfs_fh4_val,
4977eac3aab7Srobinson 		    (uint_t *)&gargs->fh.nfs_fh4_len, NFS4_FHSIZE))
49787c478bd9Sstevel@tonic-gate 			return (FALSE);
4979eac3aab7Srobinson 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
49807c478bd9Sstevel@tonic-gate 	case OP_CB_RECALL:
4981eac3aab7Srobinson 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
4982eac3aab7Srobinson 
4983eac3aab7Srobinson 		if (!xdr_u_int(xdrs, &rargs->stateid.seqid))
49847c478bd9Sstevel@tonic-gate 			return (FALSE);
4985eac3aab7Srobinson 		if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
49867c478bd9Sstevel@tonic-gate 			return (FALSE);
4987eac3aab7Srobinson 		if (!xdr_bool(xdrs, &rargs->truncate))
49887c478bd9Sstevel@tonic-gate 			return (FALSE);
4989eac3aab7Srobinson 		return (xdr_bytes(xdrs, (char **)&rargs->fh.nfs_fh4_val,
4990eac3aab7Srobinson 		    (uint_t *)&rargs->fh.nfs_fh4_len, NFS4_FHSIZE));
49917c478bd9Sstevel@tonic-gate 	case OP_CB_ILLEGAL:
49927c478bd9Sstevel@tonic-gate 		return (TRUE);
49937c478bd9Sstevel@tonic-gate 	}
49947c478bd9Sstevel@tonic-gate 	return (FALSE);
49957c478bd9Sstevel@tonic-gate }
49967c478bd9Sstevel@tonic-gate 
49977c478bd9Sstevel@tonic-gate static bool_t
49987c478bd9Sstevel@tonic-gate xdr_nfs_cb_resop4(XDR *xdrs, nfs_cb_resop4 *objp)
49997c478bd9Sstevel@tonic-gate {
50007c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->resop))
50017c478bd9Sstevel@tonic-gate 		return (FALSE);
50027c478bd9Sstevel@tonic-gate 	switch (objp->resop) {
50037c478bd9Sstevel@tonic-gate 	case OP_CB_GETATTR:
50047c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
5005*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbgetattr.
5006*0a701b1eSRobert Gordon 		    status))
50077c478bd9Sstevel@tonic-gate 			return (FALSE);
50087c478bd9Sstevel@tonic-gate 		if (objp->nfs_cb_resop4_u.opcbgetattr.status != NFS4_OK)
50097c478bd9Sstevel@tonic-gate 			return (TRUE);
50107c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
5011*0a701b1eSRobert Gordon 		    &objp->nfs_cb_resop4_u.opcbgetattr.
5012*0a701b1eSRobert Gordon 		    obj_attributes));
50137c478bd9Sstevel@tonic-gate 	case OP_CB_RECALL:
50147c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
5015*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbrecall.status));
50167c478bd9Sstevel@tonic-gate 	case OP_CB_ILLEGAL:
50177c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
5018*0a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbillegal.status));
50197c478bd9Sstevel@tonic-gate 	}
50207c478bd9Sstevel@tonic-gate 	return (FALSE);
50217c478bd9Sstevel@tonic-gate }
50227c478bd9Sstevel@tonic-gate 
5023eac3aab7Srobinson /*
5024eac3aab7Srobinson  * The NFS client side callback, RPC server
5025eac3aab7Srobinson  */
5026eac3aab7Srobinson bool_t
5027eac3aab7Srobinson xdr_CB_COMPOUND4args_clnt(XDR *xdrs, CB_COMPOUND4args *objp)
5028eac3aab7Srobinson {
5029eac3aab7Srobinson 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
5030*0a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
5031*0a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
5032eac3aab7Srobinson 		return (FALSE);
5033eac3aab7Srobinson 	if (!xdr_u_int(xdrs, &objp->minorversion))
5034eac3aab7Srobinson 		return (FALSE);
5035eac3aab7Srobinson 	if (!xdr_u_int(xdrs, &objp->callback_ident))
5036eac3aab7Srobinson 		return (FALSE);
5037eac3aab7Srobinson 	return (xdr_array(xdrs, (char **)&objp->array,
5038*0a701b1eSRobert Gordon 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5039*0a701b1eSRobert Gordon 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_cnfs_cb_argop4));
5040eac3aab7Srobinson }
5041eac3aab7Srobinson 
5042eac3aab7Srobinson /*
5043eac3aab7Srobinson  * The NFS server side callback, RPC client
5044eac3aab7Srobinson  */
50457c478bd9Sstevel@tonic-gate bool_t
5046eac3aab7Srobinson xdr_CB_COMPOUND4args_srv(XDR *xdrs, CB_COMPOUND4args *objp)
50477c478bd9Sstevel@tonic-gate {
50487c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
5049*0a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
5050*0a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
50517c478bd9Sstevel@tonic-gate 		return (FALSE);
50527c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->minorversion))
50537c478bd9Sstevel@tonic-gate 		return (FALSE);
50547c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->callback_ident))
50557c478bd9Sstevel@tonic-gate 		return (FALSE);
50567c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->array,
5057*0a701b1eSRobert Gordon 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5058*0a701b1eSRobert Gordon 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_snfs_cb_argop4));
50597c478bd9Sstevel@tonic-gate }
50607c478bd9Sstevel@tonic-gate 
50617c478bd9Sstevel@tonic-gate bool_t
50627c478bd9Sstevel@tonic-gate xdr_CB_COMPOUND4res(XDR *xdrs, CB_COMPOUND4res *objp)
50637c478bd9Sstevel@tonic-gate {
50647c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
50657c478bd9Sstevel@tonic-gate 		return (FALSE);
50667c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
5067*0a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
5068*0a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
50697c478bd9Sstevel@tonic-gate 		return (FALSE);
50707c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->array,
5071*0a701b1eSRobert Gordon 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5072*0a701b1eSRobert Gordon 	    sizeof (nfs_cb_resop4), (xdrproc_t)xdr_nfs_cb_resop4));
50737c478bd9Sstevel@tonic-gate }
5074