xref: /illumos-gate/usr/src/uts/common/fs/nfs/nfs4_xdr.c (revision e36d7b11)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
527242a7cSthurlow  * Common Development and Distribution License (the "License").
627242a7cSthurlow  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22c242f9a0Schunli zhang - Sun Microsystems - Irvine United States  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
230a701b1eSRobert Gordon  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
25297b4d80SVitaliy Gusev /*
26297b4d80SVitaliy Gusev  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
27*e36d7b11SSebastien Roy  * Copyright (c) 2013 by Delphix. All rights reserved.
28297b4d80SVitaliy Gusev  */
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  * A handcoded version based on the original rpcgen code.
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  * Note: All future NFS4 protocol changes should be added by hand
347c478bd9Sstevel@tonic-gate  * to this file.
357c478bd9Sstevel@tonic-gate  *
367c478bd9Sstevel@tonic-gate  * CAUTION: All protocol changes must also be propagated to:
377c478bd9Sstevel@tonic-gate  *     usr/src/cmd/cmd-inet/usr.sbin/snoop/nfs4_xdr.c
387c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #include <sys/types.h>
417c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
427c478bd9Sstevel@tonic-gate #include <sys/dnlc.h>
437c478bd9Sstevel@tonic-gate #include <nfs/nfs.h>
447c478bd9Sstevel@tonic-gate #include <nfs/nfs4_kprot.h>
457c478bd9Sstevel@tonic-gate #include <nfs/rnode4.h>
467c478bd9Sstevel@tonic-gate #include <nfs/nfs4.h>
477c478bd9Sstevel@tonic-gate #include <nfs/nfs4_clnt.h>
487c478bd9Sstevel@tonic-gate #include <sys/sdt.h>
492f172c55SRobert Thurlow #include <sys/mkdev.h>
507c478bd9Sstevel@tonic-gate #include <rpc/rpc_rdma.h>
512f172c55SRobert Thurlow #include <rpc/xdr.h>
522f172c55SRobert Thurlow 
532f172c55SRobert Thurlow #define	xdr_dev_t xdr_u_int
542f172c55SRobert Thurlow 
552f172c55SRobert Thurlow extern bool_t xdr_netbuf(XDR *, struct netbuf *);
562f172c55SRobert Thurlow extern bool_t xdr_vector(XDR *, char *, const uint_t, const uint_t,
572f172c55SRobert Thurlow 	const xdrproc_t);
582f172c55SRobert Thurlow bool_t xdr_knetconfig(XDR *, struct knetconfig *);
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate bool_t
617c478bd9Sstevel@tonic-gate xdr_bitmap4(XDR *xdrs, bitmap4 *objp)
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate 	int32_t len, size;
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
667c478bd9Sstevel@tonic-gate 		return (TRUE);
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 	/*
697c478bd9Sstevel@tonic-gate 	 * Simplified bitmap4 processing, always encode from uint64_t
707c478bd9Sstevel@tonic-gate 	 * to 2 uint32_t's, always decode first 2 uint32_t's into a
717c478bd9Sstevel@tonic-gate 	 * uint64_t and ignore all of the rest.
727c478bd9Sstevel@tonic-gate 	 */
737c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
747c478bd9Sstevel@tonic-gate 		len = 2;
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len))
777c478bd9Sstevel@tonic-gate 			return (FALSE);
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
807c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
810a701b1eSRobert Gordon 		    BYTES_PER_XDR_UNIT)) == TRUE) {
827c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)objp));
837c478bd9Sstevel@tonic-gate 		}
847c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
857c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)objp) == TRUE) {
867c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
870a701b1eSRobert Gordon 			    BYTES_PER_XDR_UNIT)));
887c478bd9Sstevel@tonic-gate 		}
897c478bd9Sstevel@tonic-gate #endif
907c478bd9Sstevel@tonic-gate 		return (FALSE);
917c478bd9Sstevel@tonic-gate 	}
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, &len))
947c478bd9Sstevel@tonic-gate 		return (FALSE);
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate 	/*
977c478bd9Sstevel@tonic-gate 	 * Common fast DECODE cases
987c478bd9Sstevel@tonic-gate 	 */
997c478bd9Sstevel@tonic-gate 	if (len == 2) {
1007c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
1017c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
1020a701b1eSRobert Gordon 		    BYTES_PER_XDR_UNIT)) == TRUE) {
1037c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)objp));
1047c478bd9Sstevel@tonic-gate 		}
1057c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
1067c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)objp) == TRUE) {
1077c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
1080a701b1eSRobert Gordon 			    BYTES_PER_XDR_UNIT)));
1097c478bd9Sstevel@tonic-gate 		}
1107c478bd9Sstevel@tonic-gate #endif
1117c478bd9Sstevel@tonic-gate 		return (FALSE);
1127c478bd9Sstevel@tonic-gate 	}
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate 	*objp = 0;
1157c478bd9Sstevel@tonic-gate 	if (len == 0)
1167c478bd9Sstevel@tonic-gate 		return (TRUE);
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	/*
1197c478bd9Sstevel@tonic-gate 	 * The not so common DECODE cases, len == 1 || len > 2
1207c478bd9Sstevel@tonic-gate 	 */
1217c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
1227c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
1237c478bd9Sstevel@tonic-gate 		return (FALSE);
1247c478bd9Sstevel@tonic-gate 	if (--len == 0)
1257c478bd9Sstevel@tonic-gate 		return (TRUE);
1267c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
1277c478bd9Sstevel@tonic-gate 		return (FALSE);
1287c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
1297c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
1307c478bd9Sstevel@tonic-gate 		return (FALSE);
1317c478bd9Sstevel@tonic-gate 	if (--len == 0)
1327c478bd9Sstevel@tonic-gate 		return (TRUE);
1337c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
1347c478bd9Sstevel@tonic-gate 		return (FALSE);
1357c478bd9Sstevel@tonic-gate #else
1367c478bd9Sstevel@tonic-gate 	return (FALSE);
1377c478bd9Sstevel@tonic-gate #endif
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 	if (--len == 0)
1407c478bd9Sstevel@tonic-gate 		return (TRUE);
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	size = len * BYTES_PER_XDR_UNIT;
1437c478bd9Sstevel@tonic-gate 	return (XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size));
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate /* Called by xdr_array, nfsid_map_xdr */
1477c478bd9Sstevel@tonic-gate bool_t
1487c478bd9Sstevel@tonic-gate xdr_utf8string(XDR *xdrs, utf8string *objp)
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE)
1517c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->utf8string_val,
1520a701b1eSRobert Gordon 		    (uint_t *)&objp->utf8string_len, NFS4_MAX_UTF8STRING));
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	if (objp->utf8string_val != NULL) {
1557c478bd9Sstevel@tonic-gate 		kmem_free(objp->utf8string_val, objp->utf8string_len);
1567c478bd9Sstevel@tonic-gate 		objp->utf8string_val = NULL;
1577c478bd9Sstevel@tonic-gate 	}
1587c478bd9Sstevel@tonic-gate 	return (TRUE);
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate 
1612f172c55SRobert Thurlow /*
1622f172c55SRobert Thurlow  * used by NFSv4 referrals to get info needed for NFSv4 referral mount.
1632f172c55SRobert Thurlow  */
1642f172c55SRobert Thurlow bool_t
1652f172c55SRobert Thurlow xdr_nfs_fsl_info(XDR *xdrs, struct nfs_fsl_info *objp)
1662f172c55SRobert Thurlow {
1672f172c55SRobert Thurlow 
1682f172c55SRobert Thurlow 	if (!xdr_u_int(xdrs, &objp->netbuf_len))
1692f172c55SRobert Thurlow 		return (FALSE);
1702f172c55SRobert Thurlow 	if (!xdr_u_int(xdrs, &objp->netnm_len))
1712f172c55SRobert Thurlow 		return (FALSE);
1722f172c55SRobert Thurlow 	if (!xdr_u_int(xdrs, &objp->knconf_len))
1732f172c55SRobert Thurlow 		return (FALSE);
1742f172c55SRobert Thurlow 
1752f172c55SRobert Thurlow #if defined(_LP64)
1762f172c55SRobert Thurlow 	/*
1772f172c55SRobert Thurlow 	 * The object can come from a 32-bit binary; nfsmapid.
1782f172c55SRobert Thurlow 	 * To be safe we double the size of the knetconfig to
1792f172c55SRobert Thurlow 	 * allow some buffering for decoding.
1802f172c55SRobert Thurlow 	 */
1812f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE)
1822f172c55SRobert Thurlow 		objp->knconf_len += sizeof (struct knetconfig);
1832f172c55SRobert Thurlow #endif
1842f172c55SRobert Thurlow 
1852f172c55SRobert Thurlow 	if (!xdr_string(xdrs, &objp->netname, ~0))
1862f172c55SRobert Thurlow 		return (FALSE);
1872f172c55SRobert Thurlow 	if (!xdr_pointer(xdrs, (char **)&objp->addr, objp->netbuf_len,
1882f172c55SRobert Thurlow 	    (xdrproc_t)xdr_netbuf))
1892f172c55SRobert Thurlow 		return (FALSE);
1902f172c55SRobert Thurlow 	if (!xdr_pointer(xdrs, (char **)&objp->knconf,
1912f172c55SRobert Thurlow 	    objp->knconf_len, (xdrproc_t)xdr_knetconfig))
1922f172c55SRobert Thurlow 		return (FALSE);
1932f172c55SRobert Thurlow 	return (TRUE);
1942f172c55SRobert Thurlow }
1952f172c55SRobert Thurlow 
1962f172c55SRobert Thurlow bool_t
1972f172c55SRobert Thurlow xdr_knetconfig(XDR *xdrs, struct knetconfig *objp)
1982f172c55SRobert Thurlow {
1992f172c55SRobert Thurlow 	rpc_inline_t *buf;
2002f172c55SRobert Thurlow 	u_longlong_t dev64;
2012f172c55SRobert Thurlow #if !defined(_LP64)
2022f172c55SRobert Thurlow 	uint32_t major, minor;
2032f172c55SRobert Thurlow #endif
2042f172c55SRobert Thurlow 	int i;
2052f172c55SRobert Thurlow 
2062f172c55SRobert Thurlow 	if (!xdr_u_int(xdrs, &objp->knc_semantics))
2072f172c55SRobert Thurlow 		return (FALSE);
2082f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
2092f172c55SRobert Thurlow 		objp->knc_protofmly = (((char *)objp) +
2102f172c55SRobert Thurlow 		    sizeof (struct knetconfig));
2112f172c55SRobert Thurlow 		objp->knc_proto = objp->knc_protofmly + KNC_STRSIZE;
2122f172c55SRobert Thurlow 	}
2132f172c55SRobert Thurlow 	if (!xdr_opaque(xdrs, objp->knc_protofmly, KNC_STRSIZE))
2142f172c55SRobert Thurlow 		return (FALSE);
2152f172c55SRobert Thurlow 	if (!xdr_opaque(xdrs, objp->knc_proto, KNC_STRSIZE))
2162f172c55SRobert Thurlow 		return (FALSE);
2172f172c55SRobert Thurlow 
2182f172c55SRobert Thurlow 	/*
2192f172c55SRobert Thurlow 	 * For interoperability between 32-bit daemon and 64-bit kernel,
2202f172c55SRobert Thurlow 	 * we always treat dev_t as 64-bit number and do the expanding
2212f172c55SRobert Thurlow 	 * or compression of dev_t as needed.
2222f172c55SRobert Thurlow 	 * We have to hand craft the conversion since there is no available
2232f172c55SRobert Thurlow 	 * function in ddi.c. Besides ddi.c is available only in the kernel
2242f172c55SRobert Thurlow 	 * and we want to keep both user and kernel of xdr_knetconfig() the
2252f172c55SRobert Thurlow 	 * same for consistency.
2262f172c55SRobert Thurlow 	 */
2272f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_ENCODE) {
2282f172c55SRobert Thurlow #if defined(_LP64)
2292f172c55SRobert Thurlow 		dev64 = objp->knc_rdev;
2302f172c55SRobert Thurlow #else
2312f172c55SRobert Thurlow 		major = (objp->knc_rdev >> NBITSMINOR32) & MAXMAJ32;
2322f172c55SRobert Thurlow 		minor = objp->knc_rdev & MAXMIN32;
2332f172c55SRobert Thurlow 		dev64 = (((unsigned long long)major) << NBITSMINOR64) | minor;
2342f172c55SRobert Thurlow #endif
2352f172c55SRobert Thurlow 		if (!xdr_u_longlong_t(xdrs, &dev64))
2362f172c55SRobert Thurlow 			return (FALSE);
2372f172c55SRobert Thurlow 	}
2382f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
2392f172c55SRobert Thurlow #if defined(_LP64)
2402f172c55SRobert Thurlow 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->knc_rdev))
2412f172c55SRobert Thurlow 			return (FALSE);
2422f172c55SRobert Thurlow #else
2432f172c55SRobert Thurlow 		if (!xdr_u_longlong_t(xdrs, &dev64))
2442f172c55SRobert Thurlow 			return (FALSE);
2452f172c55SRobert Thurlow 
2462f172c55SRobert Thurlow 		major = (dev64 >> NBITSMINOR64) & L_MAXMAJ32;
2472f172c55SRobert Thurlow 		minor = dev64 & L_MAXMIN32;
2482f172c55SRobert Thurlow 		objp->knc_rdev = (major << L_BITSMINOR32) | minor;
2492f172c55SRobert Thurlow #endif
2502f172c55SRobert Thurlow 	}
2512f172c55SRobert Thurlow 
2522f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_ENCODE) {
2532f172c55SRobert Thurlow 		buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT);
2542f172c55SRobert Thurlow 		if (buf == NULL) {
2552f172c55SRobert Thurlow 			if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
2562f172c55SRobert Thurlow 			    sizeof (uint_t), (xdrproc_t)xdr_u_int))
2572f172c55SRobert Thurlow 				return (FALSE);
2582f172c55SRobert Thurlow 		} else {
2592f172c55SRobert Thurlow 			uint_t *genp;
2602f172c55SRobert Thurlow 
2612f172c55SRobert Thurlow 			for (i = 0, genp = objp->knc_unused;
2622f172c55SRobert Thurlow 			    i < 8; i++) {
2632f172c55SRobert Thurlow #if defined(_LP64) || defined(_KERNEL)
2642f172c55SRobert Thurlow 				IXDR_PUT_U_INT32(buf, *genp++);
2652f172c55SRobert Thurlow #else
2662f172c55SRobert Thurlow 				IXDR_PUT_U_LONG(buf, *genp++);
2672f172c55SRobert Thurlow #endif
2682f172c55SRobert Thurlow 			}
2692f172c55SRobert Thurlow 		}
2702f172c55SRobert Thurlow 		return (TRUE);
2712f172c55SRobert Thurlow 	} else if (xdrs->x_op == XDR_DECODE) {
2722f172c55SRobert Thurlow 		buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT);
2732f172c55SRobert Thurlow 		if (buf == NULL) {
2742f172c55SRobert Thurlow 			if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
2752f172c55SRobert Thurlow 			    sizeof (uint_t), (xdrproc_t)xdr_u_int))
2762f172c55SRobert Thurlow 				return (FALSE);
2772f172c55SRobert Thurlow 		} else {
2782f172c55SRobert Thurlow 			uint_t *genp;
2792f172c55SRobert Thurlow 
2802f172c55SRobert Thurlow 			for (i = 0, genp = objp->knc_unused;
2812f172c55SRobert Thurlow 			    i < 8; i++) {
2822f172c55SRobert Thurlow #if defined(_LP64) || defined(_KERNEL)
2832f172c55SRobert Thurlow 					*genp++ = IXDR_GET_U_INT32(buf);
2842f172c55SRobert Thurlow #else
2852f172c55SRobert Thurlow 					*genp++ = IXDR_GET_U_LONG(buf);
2862f172c55SRobert Thurlow #endif
2872f172c55SRobert Thurlow 			}
2882f172c55SRobert Thurlow 		}
2892f172c55SRobert Thurlow 		return (TRUE);
2902f172c55SRobert Thurlow 	}
2912f172c55SRobert Thurlow 
2922f172c55SRobert Thurlow 	if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
2932f172c55SRobert Thurlow 	    sizeof (uint_t), (xdrproc_t)xdr_u_int))
2942f172c55SRobert Thurlow 		return (FALSE);
2952f172c55SRobert Thurlow 	return (TRUE);
2962f172c55SRobert Thurlow }
2972f172c55SRobert Thurlow 
2987c478bd9Sstevel@tonic-gate /*
299eac3aab7Srobinson  * XDR_INLINE decode a filehandle.
3007c46fb7fSek  */
3017c46fb7fSek bool_t
302eac3aab7Srobinson xdr_inline_decode_nfs_fh4(uint32_t *ptr, nfs_fh4_fmt_t *fhp, uint32_t fhsize)
3037c46fb7fSek {
304eac3aab7Srobinson 	uchar_t *bp = (uchar_t *)ptr;
3054f85d229Srobinson 	uchar_t *cp;
306eac3aab7Srobinson 	uint32_t dsize;
307eac3aab7Srobinson 	uintptr_t resid;
3084f85d229Srobinson 
3097c46fb7fSek 	/*
310eac3aab7Srobinson 	 * Check to see if what the client sent us is bigger or smaller
311eac3aab7Srobinson 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
312eac3aab7Srobinson 	 * unfortunately badly named as it is no longer the max and is
313eac3aab7Srobinson 	 * really the min of what is sent over the wire.
3147c46fb7fSek 	 */
315eac3aab7Srobinson 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
316eac3aab7Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA +
317eac3aab7Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
318eac3aab7Srobinson 		return (FALSE);
319eac3aab7Srobinson 	}
3204f85d229Srobinson 
3217c46fb7fSek 	/*
322eac3aab7Srobinson 	 * All internal parts of a filehandle are in native byte order.
323eac3aab7Srobinson 	 *
324eac3aab7Srobinson 	 * Decode what should be fh4_fsid, it is aligned.
3257c46fb7fSek 	 */
326eac3aab7Srobinson 	fhp->fh4_fsid.val[0] = *(uint32_t *)bp;
327eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
328eac3aab7Srobinson 	fhp->fh4_fsid.val[1] = *(uint32_t *)bp;
329eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
3307c46fb7fSek 
3317c46fb7fSek 	/*
332eac3aab7Srobinson 	 * Decode what should be fh4_len.  fh4_len is two bytes, so we're
333eac3aab7Srobinson 	 * unaligned now.
3347c46fb7fSek 	 */
335eac3aab7Srobinson 	cp = (uchar_t *)&fhp->fh4_len;
336eac3aab7Srobinson 	*cp++ = *bp++;
337eac3aab7Srobinson 	*cp++ = *bp++;
338eac3aab7Srobinson 	fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
3397c46fb7fSek 
3407c46fb7fSek 	/*
341da6c28aaSamw 	 * For backwards compatibility, the fid length may be less than
342eac3aab7Srobinson 	 * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
3437c46fb7fSek 	 */
344eac3aab7Srobinson 	dsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
3457c46fb7fSek 
3467c46fb7fSek 	/*
347eac3aab7Srobinson 	 * Make sure the client isn't sending us a bogus length for fh4_data.
3487c46fb7fSek 	 */
349eac3aab7Srobinson 	if (fhsize < dsize)
350eac3aab7Srobinson 		return (FALSE);
351eac3aab7Srobinson 	bcopy(bp, fhp->fh4_data, dsize);
352eac3aab7Srobinson 	bp += dsize;
353eac3aab7Srobinson 	fhsize -= dsize;
3547c46fb7fSek 
355eac3aab7Srobinson 	if (fhsize < sizeof (ushort_t))
356eac3aab7Srobinson 		return (FALSE);
357eac3aab7Srobinson 	cp = (uchar_t *)&fhp->fh4_xlen;
358eac3aab7Srobinson 	*cp++ = *bp++;
359eac3aab7Srobinson 	*cp++ = *bp++;
360eac3aab7Srobinson 	fhsize -= sizeof (ushort_t);
361eac3aab7Srobinson 
362eac3aab7Srobinson 	dsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
3637c46fb7fSek 
3647c46fb7fSek 	/*
365eac3aab7Srobinson 	 * Make sure the client isn't sending us a bogus length for fh4_xdata.
3667c46fb7fSek 	 */
367eac3aab7Srobinson 	if (fhsize < dsize)
368eac3aab7Srobinson 		return (FALSE);
369eac3aab7Srobinson 	bcopy(bp, fhp->fh4_xdata, dsize);
370eac3aab7Srobinson 	fhsize -= dsize;
371eac3aab7Srobinson 	bp += dsize;
3727c46fb7fSek 
3737c46fb7fSek 	/*
374eac3aab7Srobinson 	 * We realign things on purpose, so skip any padding
3757c46fb7fSek 	 */
376eac3aab7Srobinson 	resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
377eac3aab7Srobinson 	if (resid != 0) {
378eac3aab7Srobinson 		if (fhsize < (BYTES_PER_XDR_UNIT - resid))
379eac3aab7Srobinson 			return (FALSE);
380eac3aab7Srobinson 		bp += BYTES_PER_XDR_UNIT - resid;
381eac3aab7Srobinson 		fhsize -= BYTES_PER_XDR_UNIT - resid;
382eac3aab7Srobinson 	}
3837c46fb7fSek 
384eac3aab7Srobinson 	if (fhsize < BYTES_PER_XDR_UNIT)
385eac3aab7Srobinson 		return (FALSE);
386eac3aab7Srobinson 	fhp->fh4_flag = *(uint32_t *)bp;
387eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
388eac3aab7Srobinson 	fhsize -= BYTES_PER_XDR_UNIT;
3897c46fb7fSek 
3907c46fb7fSek #ifdef VOLATILE_FH_TEST
391eac3aab7Srobinson 	if (fhsize < BYTES_PER_XDR_UNIT)
392eac3aab7Srobinson 		return (FALSE);
393eac3aab7Srobinson 	fhp->fh4_volatile_id = *(uint32_t *)bp;
394eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
395eac3aab7Srobinson 	fhsize -= BYTES_PER_XDR_UNIT;
3967c46fb7fSek #endif
397eac3aab7Srobinson 	/*
398eac3aab7Srobinson 	 * Make sure client didn't send extra bytes
399eac3aab7Srobinson 	 */
400eac3aab7Srobinson 	if (fhsize != 0)
401eac3aab7Srobinson 		return (FALSE);
4027c46fb7fSek 	return (TRUE);
4037c46fb7fSek }
4047c46fb7fSek 
4057c46fb7fSek static bool_t
4067c46fb7fSek xdr_decode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
4077c46fb7fSek {
4087c46fb7fSek 	uint32_t fhsize;		/* filehandle size */
4094f85d229Srobinson 	uint32_t bufsize;
4104f85d229Srobinson 	rpc_inline_t *ptr;
41127242a7cSthurlow 	uchar_t *bp;
4127c46fb7fSek 
4137c46fb7fSek 	ASSERT(xdrs->x_op == XDR_DECODE);
4147c46fb7fSek 
4157c46fb7fSek 	/*
4167c46fb7fSek 	 * Retrieve the filehandle length.
4177c46fb7fSek 	 */
4187c46fb7fSek 	if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
4197c46fb7fSek 		return (FALSE);
4207c46fb7fSek 
4214f85d229Srobinson 	objp->nfs_fh4_val = NULL;
4224f85d229Srobinson 	objp->nfs_fh4_len = 0;
4234f85d229Srobinson 
4247c46fb7fSek 	/*
4254f85d229Srobinson 	 * Check to see if what the client sent us is bigger or smaller
4264f85d229Srobinson 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
4274f85d229Srobinson 	 * unfortunately badly named as it is no longer the max and is
4284f85d229Srobinson 	 * really the min of what is sent over the wire.
4297c46fb7fSek 	 */
4304f85d229Srobinson 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
4314f85d229Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA +
4324f85d229Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
4334f85d229Srobinson 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
4344f85d229Srobinson 			return (FALSE);
4354f85d229Srobinson 		return (TRUE);
4364f85d229Srobinson 	}
4377c46fb7fSek 
4384f85d229Srobinson 	/*
4394f85d229Srobinson 	 * bring in fhsize plus any padding
4404f85d229Srobinson 	 */
4414f85d229Srobinson 	bufsize = RNDUP(fhsize);
4424f85d229Srobinson 	ptr = XDR_INLINE(xdrs, bufsize);
443eac3aab7Srobinson 	bp = (uchar_t *)ptr;
4444f85d229Srobinson 	if (ptr == NULL) {
44527242a7cSthurlow 		bp = kmem_alloc(bufsize, KM_SLEEP);
44627242a7cSthurlow 		if (!xdr_opaque(xdrs, (char *)bp, bufsize)) {
44727242a7cSthurlow 			kmem_free(bp, bufsize);
4484f85d229Srobinson 			return (FALSE);
44927242a7cSthurlow 		}
4504f85d229Srobinson 	}
4517c46fb7fSek 
4527c46fb7fSek 	objp->nfs_fh4_val = kmem_zalloc(sizeof (nfs_fh4_fmt_t), KM_SLEEP);
4537c46fb7fSek 	objp->nfs_fh4_len = sizeof (nfs_fh4_fmt_t);
454eac3aab7Srobinson 
455eac3aab7Srobinson 	if (xdr_inline_decode_nfs_fh4((uint32_t *)bp,
456eac3aab7Srobinson 	    (nfs_fh4_fmt_t *)objp->nfs_fh4_val, fhsize) == FALSE) {
457eac3aab7Srobinson 		/*
458eac3aab7Srobinson 		 * If in the process of decoding we find the file handle
459eac3aab7Srobinson 		 * is not correctly formed, we need to continue decoding
460eac3aab7Srobinson 		 * and trigger an NFS layer error. Set the nfs_fh4_len to
461eac3aab7Srobinson 		 * zero so it gets caught as a bad length.
462eac3aab7Srobinson 		 */
463eac3aab7Srobinson 		kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
464eac3aab7Srobinson 		objp->nfs_fh4_val = NULL;
465eac3aab7Srobinson 		objp->nfs_fh4_len = 0;
466eac3aab7Srobinson 	}
467eac3aab7Srobinson 
468eac3aab7Srobinson 	if (ptr == NULL)
46927242a7cSthurlow 		kmem_free(bp, bufsize);
470eac3aab7Srobinson 	return (TRUE);
471eac3aab7Srobinson }
472eac3aab7Srobinson 
473eac3aab7Srobinson /*
474eac3aab7Srobinson  * XDR_INLINE encode a filehandle.
475eac3aab7Srobinson  */
476eac3aab7Srobinson bool_t
477eac3aab7Srobinson xdr_inline_encode_nfs_fh4(uint32_t **ptrp, uint32_t *ptr_redzone,
478eac3aab7Srobinson 	nfs_fh4_fmt_t *fhp)
479eac3aab7Srobinson {
480eac3aab7Srobinson 	uint32_t *ptr = *ptrp;
481eac3aab7Srobinson 	uchar_t *cp;
482eac3aab7Srobinson 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
483eac3aab7Srobinson 	uint32_t padword;
484eac3aab7Srobinson 
485eac3aab7Srobinson 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
486eac3aab7Srobinson 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
4877c46fb7fSek 
4887c46fb7fSek 	/*
489eac3aab7Srobinson 	 * First get the initial and variable sized part of the filehandle.
4907c46fb7fSek 	 */
491eac3aab7Srobinson 	otw_len = sizeof (fhp->fh4_fsid) +
492eac3aab7Srobinson 	    sizeof (fhp->fh4_len) + fsize +
493eac3aab7Srobinson 	    sizeof (fhp->fh4_xlen) + xsize;
4947c46fb7fSek 
4957c46fb7fSek 	/*
496eac3aab7Srobinson 	 * Round out to a full word.
4977c46fb7fSek 	 */
498eac3aab7Srobinson 	otw_len = RNDUP(otw_len);
499eac3aab7Srobinson 	padword = (otw_len / BYTES_PER_XDR_UNIT);	/* includes fhlen */
5007c46fb7fSek 
5017c46fb7fSek 	/*
502eac3aab7Srobinson 	 * Add in the fixed sized pieces.
5037c46fb7fSek 	 */
504eac3aab7Srobinson 	otw_len += sizeof (fhp->fh4_flag);
505eac3aab7Srobinson #ifdef VOLATILE_FH_TEST
506eac3aab7Srobinson 	otw_len += sizeof (fhp->fh4_volatile_id);
507eac3aab7Srobinson #endif
5087c46fb7fSek 
5094f85d229Srobinson 	/*
510eac3aab7Srobinson 	 * Make sure we don't exceed our buffer.
5114f85d229Srobinson 	 */
512eac3aab7Srobinson 	if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone)
513eac3aab7Srobinson 		return (FALSE);
5147c46fb7fSek 
5157c46fb7fSek 	/*
51627242a7cSthurlow 	 * Zero out the padding.
5177c46fb7fSek 	 */
518eac3aab7Srobinson 	ptr[padword] = 0;
5197c46fb7fSek 
52027242a7cSthurlow 	IXDR_PUT_U_INT32(ptr, otw_len);
52127242a7cSthurlow 
5224f85d229Srobinson 	/*
523eac3aab7Srobinson 	 * The rest of the filehandle is in native byteorder
5244f85d229Srobinson 	 */
525eac3aab7Srobinson 	/* fh4_fsid */
526eac3aab7Srobinson 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[0];
527eac3aab7Srobinson 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[1];
5287c46fb7fSek 
5297c46fb7fSek 	/*
530eac3aab7Srobinson 	 * Since the next pieces are unaligned, we need to
531eac3aab7Srobinson 	 * do bytewise copies.
5327c46fb7fSek 	 */
533eac3aab7Srobinson 	cp = (uchar_t *)ptr;
5347c46fb7fSek 
535eac3aab7Srobinson 	/* fh4_len + fh4_data */
536eac3aab7Srobinson 	bcopy(&fhp->fh4_len, cp, sizeof (fhp->fh4_len) + fsize);
537eac3aab7Srobinson 	cp += sizeof (fhp->fh4_len) + fsize;
538eac3aab7Srobinson 
539eac3aab7Srobinson 	/* fh4_xlen + fh4_xdata */
540eac3aab7Srobinson 	bcopy(&fhp->fh4_xlen, cp, sizeof (fhp->fh4_xlen) + xsize);
541eac3aab7Srobinson 	cp += sizeof (fhp->fh4_xlen) + xsize;
542eac3aab7Srobinson 
543eac3aab7Srobinson 	/* do necessary rounding/padding */
544eac3aab7Srobinson 	cp = (uchar_t *)RNDUP((uintptr_t)cp);
545eac3aab7Srobinson 	ptr = (uint32_t *)cp;
5467c46fb7fSek 
5474f85d229Srobinson 	/*
548eac3aab7Srobinson 	 * With the above padding, we're word aligned again.
5494f85d229Srobinson 	 */
550eac3aab7Srobinson 	ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0);
551eac3aab7Srobinson 
552eac3aab7Srobinson 	/* fh4_flag */
553eac3aab7Srobinson 	*ptr++ = (uint32_t)fhp->fh4_flag;
554eac3aab7Srobinson 
555eac3aab7Srobinson #ifdef VOLATILE_FH_TEST
556eac3aab7Srobinson 	/* fh4_volatile_id */
557eac3aab7Srobinson 	*ptr++ = (uint32_t)fhp->fh4_volatile_id;
558eac3aab7Srobinson #endif
559eac3aab7Srobinson 	*ptrp = ptr;
560eac3aab7Srobinson 
5617c46fb7fSek 	return (TRUE);
5627c46fb7fSek }
5637c46fb7fSek 
5647c46fb7fSek static bool_t
5657c46fb7fSek xdr_encode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
5667c46fb7fSek {
5674f85d229Srobinson 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
5684f85d229Srobinson 	bool_t ret;
5694f85d229Srobinson 	rpc_inline_t *ptr;
5704f85d229Srobinson 	rpc_inline_t *buf = NULL;
5714f85d229Srobinson 	uint32_t *ptr_redzone;
5724f85d229Srobinson 	nfs_fh4_fmt_t *fhp;
5737c46fb7fSek 
5747c46fb7fSek 	ASSERT(xdrs->x_op == XDR_ENCODE);
5757c46fb7fSek 
5764f85d229Srobinson 	fhp = (nfs_fh4_fmt_t *)objp->nfs_fh4_val;
5774f85d229Srobinson 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
5784f85d229Srobinson 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
5797c46fb7fSek 
5804f85d229Srobinson 	/*
5814f85d229Srobinson 	 * First get the over the wire size, it is the 4 bytes
5824f85d229Srobinson 	 * for the length, plus the combined size of the
5834f85d229Srobinson 	 * file handle components.
5844f85d229Srobinson 	 */
5854f85d229Srobinson 	otw_len = BYTES_PER_XDR_UNIT + sizeof (fhp->fh4_fsid) +
5864f85d229Srobinson 	    sizeof (fhp->fh4_len) + fsize +
5874f85d229Srobinson 	    sizeof (fhp->fh4_xlen) + xsize +
5884f85d229Srobinson 	    sizeof (fhp->fh4_flag);
5897c46fb7fSek #ifdef VOLATILE_FH_TEST
5904f85d229Srobinson 	otw_len += sizeof (fhp->fh4_volatile_id);
5917c46fb7fSek #endif
5927c46fb7fSek 	/*
5934f85d229Srobinson 	 * Round out to a full word.
5947c46fb7fSek 	 */
5954f85d229Srobinson 	otw_len = RNDUP(otw_len);
5967c46fb7fSek 
5977c46fb7fSek 	/*
5984f85d229Srobinson 	 * Next try to inline the XDR stream, if that fails (rare)
5994f85d229Srobinson 	 * allocate a buffer to encode the file handle and then
6004f85d229Srobinson 	 * copy it using xdr_opaque and free the buffer.
6017c46fb7fSek 	 */
6024f85d229Srobinson 	ptr = XDR_INLINE(xdrs, otw_len);
6034f85d229Srobinson 	if (ptr == NULL)
6044f85d229Srobinson 		ptr = buf = kmem_alloc(otw_len, KM_SLEEP);
6057c46fb7fSek 
6064f85d229Srobinson 	ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT));
6074f85d229Srobinson 	ret = xdr_inline_encode_nfs_fh4((uint32_t **)&ptr, ptr_redzone, fhp);
6087c46fb7fSek 
6094f85d229Srobinson 	if (buf != NULL) {
6104f85d229Srobinson 		if (ret == TRUE)
6114f85d229Srobinson 			ret = xdr_opaque(xdrs, (char *)buf, otw_len);
6124f85d229Srobinson 		kmem_free(buf, otw_len);
6134f85d229Srobinson 	}
6144f85d229Srobinson 	return (ret);
6157c46fb7fSek }
6167c46fb7fSek 
6177c46fb7fSek /*
6187c46fb7fSek  * XDR a NFSv4 filehandle.
619eac3aab7Srobinson  * Encoding interprets the contents (server).
620eac3aab7Srobinson  * Decoding the contents are opaque (client).
6217c478bd9Sstevel@tonic-gate  */
6227c478bd9Sstevel@tonic-gate bool_t
6237c478bd9Sstevel@tonic-gate xdr_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
6247c478bd9Sstevel@tonic-gate {
625eac3aab7Srobinson 	switch (xdrs->x_op) {
626eac3aab7Srobinson 	case XDR_ENCODE:
6277c46fb7fSek 		return (xdr_encode_nfs_fh4(xdrs, objp));
628eac3aab7Srobinson 	case XDR_DECODE:
629eac3aab7Srobinson 		return (xdr_bytes(xdrs, (char **)&objp->nfs_fh4_val,
630eac3aab7Srobinson 		    (uint_t *)&objp->nfs_fh4_len, NFS4_FHSIZE));
631eac3aab7Srobinson 	case XDR_FREE:
632eac3aab7Srobinson 		if (objp->nfs_fh4_val != NULL) {
633eac3aab7Srobinson 			kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
634eac3aab7Srobinson 			objp->nfs_fh4_val = NULL;
635eac3aab7Srobinson 		}
636eac3aab7Srobinson 		return (TRUE);
6377c478bd9Sstevel@tonic-gate 	}
638eac3aab7Srobinson 	return (FALSE);
6397c478bd9Sstevel@tonic-gate }
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate /* Called by xdr_array */
6427c478bd9Sstevel@tonic-gate static bool_t
6437c478bd9Sstevel@tonic-gate xdr_fs_location4(XDR *xdrs, fs_location4 *objp)
6447c478bd9Sstevel@tonic-gate {
6452f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
6462f172c55SRobert Thurlow 		objp->server_val = NULL;
6472f172c55SRobert Thurlow 		objp->rootpath.pathname4_val = NULL;
6482f172c55SRobert Thurlow 	}
6497c478bd9Sstevel@tonic-gate 	if (!xdr_array(xdrs, (char **)&objp->server_val,
6502f172c55SRobert Thurlow 	    (uint_t *)&objp->server_len, NFS4_MAX_UTF8STRING,
6510a701b1eSRobert Gordon 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
6527c478bd9Sstevel@tonic-gate 		return (FALSE);
6537c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->rootpath.pathname4_val,
6540a701b1eSRobert Gordon 	    (uint_t *)&objp->rootpath.pathname4_len,
6550a701b1eSRobert Gordon 	    NFS4_MAX_PATHNAME4,
6560a701b1eSRobert Gordon 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string));
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate /* Called by xdr_array */
6607c478bd9Sstevel@tonic-gate static bool_t
6617c478bd9Sstevel@tonic-gate xdr_nfsace4(XDR *xdrs, nfsace4 *objp)
6627c478bd9Sstevel@tonic-gate {
6637c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
6647c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->type))
6657c478bd9Sstevel@tonic-gate 			return (FALSE);
6667c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->flag))
6677c478bd9Sstevel@tonic-gate 			return (FALSE);
6687c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->access_mask))
6697c478bd9Sstevel@tonic-gate 			return (FALSE);
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
6727c478bd9Sstevel@tonic-gate 			objp->who.utf8string_val = NULL;
6737c478bd9Sstevel@tonic-gate 			objp->who.utf8string_len = 0;
6747c478bd9Sstevel@tonic-gate 		}
6757c478bd9Sstevel@tonic-gate 
6767c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->who.utf8string_val,
6770a701b1eSRobert Gordon 		    (uint_t *)&objp->who.utf8string_len,
6780a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
6797c478bd9Sstevel@tonic-gate 	}
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	/*
6827c478bd9Sstevel@tonic-gate 	 * Optimized free case
6837c478bd9Sstevel@tonic-gate 	 */
6847c478bd9Sstevel@tonic-gate 	if (objp->who.utf8string_val != NULL) {
6857c478bd9Sstevel@tonic-gate 		kmem_free(objp->who.utf8string_val, objp->who.utf8string_len);
6867c478bd9Sstevel@tonic-gate 		objp->who.utf8string_val = NULL;
6877c478bd9Sstevel@tonic-gate 	}
6887c478bd9Sstevel@tonic-gate 	return (TRUE);
6897c478bd9Sstevel@tonic-gate }
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate /*
6927c478bd9Sstevel@tonic-gate  * These functions are called out of nfs4_attr.c
6937c478bd9Sstevel@tonic-gate  */
6947c478bd9Sstevel@tonic-gate bool_t
6957c478bd9Sstevel@tonic-gate xdr_fattr4_fsid(XDR *xdrs, fattr4_fsid *objp)
6967c478bd9Sstevel@tonic-gate {
6977c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
6987c478bd9Sstevel@tonic-gate 		return (TRUE);
6997c478bd9Sstevel@tonic-gate 
7007c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->major))
7017c478bd9Sstevel@tonic-gate 		return (FALSE);
7027c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->minor));
7037c478bd9Sstevel@tonic-gate }
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate bool_t
7077c478bd9Sstevel@tonic-gate xdr_fattr4_acl(XDR *xdrs, fattr4_acl *objp)
7087c478bd9Sstevel@tonic-gate {
7097c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->fattr4_acl_val,
7100a701b1eSRobert Gordon 	    (uint_t *)&objp->fattr4_acl_len, NFS4_ACL_LIMIT,
7110a701b1eSRobert Gordon 	    sizeof (nfsace4), (xdrproc_t)xdr_nfsace4));
7127c478bd9Sstevel@tonic-gate }
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate bool_t
7157c478bd9Sstevel@tonic-gate xdr_fattr4_fs_locations(XDR *xdrs, fattr4_fs_locations *objp)
7167c478bd9Sstevel@tonic-gate {
7172f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
7182f172c55SRobert Thurlow 		objp->fs_root.pathname4_len = 0;
7192f172c55SRobert Thurlow 		objp->fs_root.pathname4_val = NULL;
7202f172c55SRobert Thurlow 		objp->locations_val = NULL;
7212f172c55SRobert Thurlow 	}
7227c478bd9Sstevel@tonic-gate 	if (!xdr_array(xdrs, (char **)&objp->fs_root.pathname4_val,
7230a701b1eSRobert Gordon 	    (uint_t *)&objp->fs_root.pathname4_len,
7240a701b1eSRobert Gordon 	    NFS4_MAX_PATHNAME4,
7250a701b1eSRobert Gordon 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
7267c478bd9Sstevel@tonic-gate 		return (FALSE);
7277c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->locations_val,
7280a701b1eSRobert Gordon 	    (uint_t *)&objp->locations_len, NFS4_FS_LOCATIONS_LIMIT,
7290a701b1eSRobert Gordon 	    sizeof (fs_location4), (xdrproc_t)xdr_fs_location4));
7307c478bd9Sstevel@tonic-gate }
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate bool_t
7337c478bd9Sstevel@tonic-gate xdr_fattr4_rawdev(XDR *xdrs, fattr4_rawdev *objp)
7347c478bd9Sstevel@tonic-gate {
7357c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
7367c478bd9Sstevel@tonic-gate 		return (TRUE);
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->specdata1))
7397c478bd9Sstevel@tonic-gate 		return (FALSE);
7407c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->specdata2));
7417c478bd9Sstevel@tonic-gate }
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate bool_t
7447c478bd9Sstevel@tonic-gate xdr_nfstime4(XDR *xdrs, nfstime4 *objp)
7457c478bd9Sstevel@tonic-gate {
7467c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
7477c478bd9Sstevel@tonic-gate 		return (TRUE);
7487c478bd9Sstevel@tonic-gate 
7497c478bd9Sstevel@tonic-gate 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->seconds))
7507c478bd9Sstevel@tonic-gate 		return (FALSE);
7517c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->nseconds));
7527c478bd9Sstevel@tonic-gate }
7537c478bd9Sstevel@tonic-gate 
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate /*
7567c478bd9Sstevel@tonic-gate  * structured used for calls into xdr_ga_fattr_res() as a means
7577c478bd9Sstevel@tonic-gate  * to do an immediate/short-term cache of owner/group strings
7587c478bd9Sstevel@tonic-gate  * for callers like the readdir processing.  In the case of readdir,
7597c478bd9Sstevel@tonic-gate  * it is likely that the directory objects will be owned by the same
7607c478bd9Sstevel@tonic-gate  * owner/group and if so there is no need to call into the uid/gid
7617c478bd9Sstevel@tonic-gate  * mapping code.  While the uid/gid interfaces have their own cache
7627c478bd9Sstevel@tonic-gate  * having one here will reduct pathlength further.
7637c478bd9Sstevel@tonic-gate  */
7647c478bd9Sstevel@tonic-gate #define	MAX_OG_NAME 100
7657c478bd9Sstevel@tonic-gate typedef struct ug_cache
7667c478bd9Sstevel@tonic-gate {
7677c478bd9Sstevel@tonic-gate 	uid_t	uid;
7687c478bd9Sstevel@tonic-gate 	gid_t	gid;
7697c478bd9Sstevel@tonic-gate 	utf8string u_curr, u_last;
7707c478bd9Sstevel@tonic-gate 	utf8string g_curr, g_last;
7717c478bd9Sstevel@tonic-gate 	char	u_buf1[MAX_OG_NAME];
7727c478bd9Sstevel@tonic-gate 	char	u_buf2[MAX_OG_NAME];
7737c478bd9Sstevel@tonic-gate 	char	g_buf1[MAX_OG_NAME];
7747c478bd9Sstevel@tonic-gate 	char	g_buf2[MAX_OG_NAME];
7757c478bd9Sstevel@tonic-gate } ug_cache_t;
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate #define	U_SWAP_CURR_LAST(ug) \
7787c478bd9Sstevel@tonic-gate 	(ug)->u_last.utf8string_len = (ug)->u_curr.utf8string_len;	\
7797c478bd9Sstevel@tonic-gate 	if ((ug)->u_last.utf8string_val == (ug)->u_buf1) {		\
7807c478bd9Sstevel@tonic-gate 		(ug)->u_last.utf8string_val = (ug)->u_buf2;		\
7817c478bd9Sstevel@tonic-gate 		(ug)->u_curr.utf8string_val = (ug)->u_buf1;		\
7827c478bd9Sstevel@tonic-gate 	} else {							\
7837c478bd9Sstevel@tonic-gate 		(ug)->u_last.utf8string_val = (ug)->u_buf1;		\
7847c478bd9Sstevel@tonic-gate 		(ug)->u_curr.utf8string_val = (ug)->u_buf2;		\
7857c478bd9Sstevel@tonic-gate 	}
7867c478bd9Sstevel@tonic-gate 
7877c478bd9Sstevel@tonic-gate #define	G_SWAP_CURR_LAST(ug) \
7887c478bd9Sstevel@tonic-gate 	(ug)->g_last.utf8string_len = (ug)->g_curr.utf8string_len;	\
7897c478bd9Sstevel@tonic-gate 	if ((ug)->g_last.utf8string_val == (ug)->g_buf1) {		\
7907c478bd9Sstevel@tonic-gate 		(ug)->g_last.utf8string_val = (ug)->g_buf2;		\
7917c478bd9Sstevel@tonic-gate 		(ug)->g_curr.utf8string_val = (ug)->g_buf1;		\
7927c478bd9Sstevel@tonic-gate 	} else {							\
7937c478bd9Sstevel@tonic-gate 		(ug)->g_last.utf8string_val = (ug)->g_buf1;		\
7947c478bd9Sstevel@tonic-gate 		(ug)->g_curr.utf8string_val = (ug)->g_buf2;		\
7957c478bd9Sstevel@tonic-gate 	}
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate static ug_cache_t *
7987c478bd9Sstevel@tonic-gate alloc_ugcache()
7997c478bd9Sstevel@tonic-gate {
8007c478bd9Sstevel@tonic-gate 	ug_cache_t *pug = kmem_alloc(sizeof (ug_cache_t), KM_SLEEP);
8017c478bd9Sstevel@tonic-gate 
8027c478bd9Sstevel@tonic-gate 	pug->uid = pug->gid = 0;
8037c478bd9Sstevel@tonic-gate 	pug->u_curr.utf8string_len = 0;
8047c478bd9Sstevel@tonic-gate 	pug->u_last.utf8string_len = 0;
8057c478bd9Sstevel@tonic-gate 	pug->g_curr.utf8string_len = 0;
8067c478bd9Sstevel@tonic-gate 	pug->g_last.utf8string_len = 0;
8077c478bd9Sstevel@tonic-gate 	pug->u_curr.utf8string_val = pug->u_buf1;
8087c478bd9Sstevel@tonic-gate 	pug->u_last.utf8string_val = pug->u_buf2;
8097c478bd9Sstevel@tonic-gate 	pug->g_curr.utf8string_val = pug->g_buf1;
8107c478bd9Sstevel@tonic-gate 	pug->g_last.utf8string_val = pug->g_buf2;
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate 	return (pug);
8137c478bd9Sstevel@tonic-gate }
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate static void
8167c478bd9Sstevel@tonic-gate xdr_ga_prefill_vattr(struct nfs4_ga_res *garp, struct mntinfo4 *mi)
8177c478bd9Sstevel@tonic-gate {
8187c478bd9Sstevel@tonic-gate 	static vattr_t s_vattr = {
8197c478bd9Sstevel@tonic-gate 		AT_ALL,		/* va_mask */
8207c478bd9Sstevel@tonic-gate 		VNON,		/* va_type */
8217c478bd9Sstevel@tonic-gate 		0777,		/* va_mode */
8227c478bd9Sstevel@tonic-gate 		UID_NOBODY,	/* va_uid */
8237c478bd9Sstevel@tonic-gate 		GID_NOBODY,	/* va_gid */
8247c478bd9Sstevel@tonic-gate 		0,		/* va_fsid */
8257c478bd9Sstevel@tonic-gate 		0,		/* va_nodeid */
8267c478bd9Sstevel@tonic-gate 		1,		/* va_nlink */
8277c478bd9Sstevel@tonic-gate 		0,		/* va_size */
8287c478bd9Sstevel@tonic-gate 		{0, 0},		/* va_atime */
8297c478bd9Sstevel@tonic-gate 		{0, 0},		/* va_mtime */
8307c478bd9Sstevel@tonic-gate 		{0, 0},		/* va_ctime */
8317c478bd9Sstevel@tonic-gate 		0,		/* va_rdev */
8327c478bd9Sstevel@tonic-gate 		MAXBSIZE,	/* va_blksize */
8337c478bd9Sstevel@tonic-gate 		0,		/* va_nblocks */
8347c478bd9Sstevel@tonic-gate 		0		/* va_seq */
8357c478bd9Sstevel@tonic-gate 	};
8367c478bd9Sstevel@tonic-gate 
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate 	garp->n4g_va = s_vattr;
8397c478bd9Sstevel@tonic-gate 	garp->n4g_va.va_fsid = mi->mi_vfsp->vfs_dev;
8407c478bd9Sstevel@tonic-gate 	hrt2ts(gethrtime(), &garp->n4g_va.va_atime);
8417c478bd9Sstevel@tonic-gate 	garp->n4g_va.va_mtime = garp->n4g_va.va_ctime = garp->n4g_va.va_atime;
8427c478bd9Sstevel@tonic-gate }
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate static void
8457c478bd9Sstevel@tonic-gate xdr_ga_prefill_statvfs(struct nfs4_ga_ext_res *gesp, struct mntinfo4 *mi)
8467c478bd9Sstevel@tonic-gate {
8477c478bd9Sstevel@tonic-gate 	static statvfs64_t s_sb = {
8487c478bd9Sstevel@tonic-gate 		MAXBSIZE,	/* f_bsize */
8497c478bd9Sstevel@tonic-gate 		DEV_BSIZE,	/* f_frsize */
8507c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_blocks */
8517c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_bfree */
8527c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_bavail */
8537c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_files */
8547c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_ffree */
8557c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_favail */
8567c478bd9Sstevel@tonic-gate 		0,		/* f_fsid */
8577c478bd9Sstevel@tonic-gate 		"\0",		/* f_basetype */
8587c478bd9Sstevel@tonic-gate 		0,		/* f_flag */
8597c478bd9Sstevel@tonic-gate 		MAXNAMELEN,	/* f_namemax */
8607c478bd9Sstevel@tonic-gate 		"\0",		/* f_fstr */
8617c478bd9Sstevel@tonic-gate 	};
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate 	gesp->n4g_sb = s_sb;
8647c478bd9Sstevel@tonic-gate 	gesp->n4g_sb.f_fsid = mi->mi_vfsp->vfs_fsid.val[0];
8657c478bd9Sstevel@tonic-gate }
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate static bool_t
8687c478bd9Sstevel@tonic-gate xdr_ga_fattr_res(XDR *xdrs, struct nfs4_ga_res *garp, bitmap4 resbmap,
8697c478bd9Sstevel@tonic-gate 		bitmap4 argbmap, struct mntinfo4 *mi, ug_cache_t *pug)
8707c478bd9Sstevel@tonic-gate {
8717c478bd9Sstevel@tonic-gate 	int truefalse;
8727c478bd9Sstevel@tonic-gate 	struct nfs4_ga_ext_res ges, *gesp;
8737c478bd9Sstevel@tonic-gate 	vattr_t *vap = &garp->n4g_va;
8747c478bd9Sstevel@tonic-gate 	vsecattr_t *vsap = &garp->n4g_vsa;
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 	if (garp->n4g_ext_res)
8797c478bd9Sstevel@tonic-gate 		gesp = garp->n4g_ext_res;
8807c478bd9Sstevel@tonic-gate 	else
8817c478bd9Sstevel@tonic-gate 		gesp = &ges;
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate 	vap->va_mask = 0;
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate 	/* Check to see if the vattr should be pre-filled */
8867c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_VATTR_MASK)
8877c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_vattr(garp, mi);
8887c478bd9Sstevel@tonic-gate 
8897c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_STATFS_ATTR_MASK)
8907c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_statvfs(gesp, mi);
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate 	if (resbmap &
8937c478bd9Sstevel@tonic-gate 	    (FATTR4_SUPPORTED_ATTRS_MASK |
8947c478bd9Sstevel@tonic-gate 	    FATTR4_TYPE_MASK |
8957c478bd9Sstevel@tonic-gate 	    FATTR4_FH_EXPIRE_TYPE_MASK |
8967c478bd9Sstevel@tonic-gate 	    FATTR4_CHANGE_MASK |
8977c478bd9Sstevel@tonic-gate 	    FATTR4_SIZE_MASK |
8987c478bd9Sstevel@tonic-gate 	    FATTR4_LINK_SUPPORT_MASK |
8997c478bd9Sstevel@tonic-gate 	    FATTR4_SYMLINK_SUPPORT_MASK |
9007c478bd9Sstevel@tonic-gate 	    FATTR4_NAMED_ATTR_MASK)) {
9017c478bd9Sstevel@tonic-gate 
9027c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
9037c478bd9Sstevel@tonic-gate 			if (!xdr_bitmap4(xdrs, &gesp->n4g_suppattrs))
9047c478bd9Sstevel@tonic-gate 				return (FALSE);
9057c478bd9Sstevel@tonic-gate 		}
9067c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TYPE_MASK) {
9077c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_type))
9087c478bd9Sstevel@tonic-gate 				return (FALSE);
9097c478bd9Sstevel@tonic-gate 
9102c2d21e9SRichard Lowe 			if ((nfs_ftype4)vap->va_type < NF4REG ||
9112c2d21e9SRichard Lowe 			    (nfs_ftype4)vap->va_type > NF4NAMEDATTR)
9127c478bd9Sstevel@tonic-gate 				vap->va_type = VBAD;
9137c478bd9Sstevel@tonic-gate 			else
9147c478bd9Sstevel@tonic-gate 				vap->va_type = nf4_to_vt[vap->va_type];
9157c478bd9Sstevel@tonic-gate 			if (vap->va_type == VBLK)
9167c478bd9Sstevel@tonic-gate 				vap->va_blksize = DEV_BSIZE;
9177c478bd9Sstevel@tonic-gate 
9187c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_TYPE;
9197c478bd9Sstevel@tonic-gate 		}
9207c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
9217c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_fet))
9227c478bd9Sstevel@tonic-gate 				return (FALSE);
9237c478bd9Sstevel@tonic-gate 		}
9247c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHANGE_MASK) {
9257c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
9260a701b1eSRobert Gordon 			    (u_longlong_t *)&garp->n4g_change))
9277c478bd9Sstevel@tonic-gate 				return (FALSE);
9287c478bd9Sstevel@tonic-gate 			garp->n4g_change_valid = 1;
9297c478bd9Sstevel@tonic-gate 		}
9307c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SIZE_MASK) {
9317c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
9320a701b1eSRobert Gordon 			    (u_longlong_t *)&vap->va_size))
9337c478bd9Sstevel@tonic-gate 				return (FALSE);
9347c478bd9Sstevel@tonic-gate 			if (!NFS4_SIZE_OK(vap->va_size)) {
9357c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = EFBIG;
9367c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
9377c478bd9Sstevel@tonic-gate 			} else {
9387c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_SIZE;
9397c478bd9Sstevel@tonic-gate 			}
9407c478bd9Sstevel@tonic-gate 		}
9417c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
9427c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9437c478bd9Sstevel@tonic-gate 				return (FALSE);
9447c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_link_support =
9450a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
9467c478bd9Sstevel@tonic-gate 		}
9477c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
9487c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9497c478bd9Sstevel@tonic-gate 				return (FALSE);
9507c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_symlink_support =
9510a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
9527c478bd9Sstevel@tonic-gate 		}
9537c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
9547c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9557c478bd9Sstevel@tonic-gate 				return (FALSE);
9567c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
9577c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists =
9580a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
9597c478bd9Sstevel@tonic-gate 		}
9607c478bd9Sstevel@tonic-gate 	}
9617c478bd9Sstevel@tonic-gate 	if (resbmap &
9627c478bd9Sstevel@tonic-gate 	    (FATTR4_FSID_MASK |
9637c478bd9Sstevel@tonic-gate 	    FATTR4_UNIQUE_HANDLES_MASK |
9647c478bd9Sstevel@tonic-gate 	    FATTR4_LEASE_TIME_MASK |
9657c478bd9Sstevel@tonic-gate 	    FATTR4_RDATTR_ERROR_MASK)) {
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FSID_MASK) {
9680a701b1eSRobert Gordon 			if ((!xdr_u_longlong_t(xdrs,
9690a701b1eSRobert Gordon 			    (u_longlong_t *)&garp->n4g_fsid.major)) ||
9700a701b1eSRobert Gordon 			    (!xdr_u_longlong_t(xdrs,
9710a701b1eSRobert Gordon 			    (u_longlong_t *)&garp->n4g_fsid.minor)))
9727c478bd9Sstevel@tonic-gate 				return (FALSE);
9730a701b1eSRobert Gordon 			garp->n4g_fsid_valid = 1;
9747c478bd9Sstevel@tonic-gate 		}
9757c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
9767c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9777c478bd9Sstevel@tonic-gate 				return (FALSE);
9787c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_unique_handles =
9790a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
9807c478bd9Sstevel@tonic-gate 		}
9817c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
9827c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_leasetime))
9837c478bd9Sstevel@tonic-gate 				return (FALSE);
9847c478bd9Sstevel@tonic-gate 		}
9857c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
9867c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs,
9870a701b1eSRobert Gordon 			    (int *)&gesp->n4g_rdattr_error))
9887c478bd9Sstevel@tonic-gate 				return (FALSE);
9897c478bd9Sstevel@tonic-gate 		}
9907c478bd9Sstevel@tonic-gate 	}
9917c478bd9Sstevel@tonic-gate 	if (resbmap &
9927c478bd9Sstevel@tonic-gate 	    (FATTR4_ACL_MASK |
9937c478bd9Sstevel@tonic-gate 	    FATTR4_ACLSUPPORT_MASK |
9947c478bd9Sstevel@tonic-gate 	    FATTR4_ARCHIVE_MASK |
9957c478bd9Sstevel@tonic-gate 	    FATTR4_CANSETTIME_MASK)) {
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACL_MASK) {
9987c478bd9Sstevel@tonic-gate 			fattr4_acl	acl;
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate 			acl.fattr4_acl_val = NULL;
10017c478bd9Sstevel@tonic-gate 			acl.fattr4_acl_len = 0;
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 			if (!xdr_fattr4_acl(xdrs, &acl))
10047c478bd9Sstevel@tonic-gate 				return (FALSE);
10057c478bd9Sstevel@tonic-gate 
10067c478bd9Sstevel@tonic-gate 			vsap->vsa_aclcnt = acl.fattr4_acl_len;
10077c478bd9Sstevel@tonic-gate 			vsap->vsa_aclentp = acl.fattr4_acl_val;
10087c478bd9Sstevel@tonic-gate 			vsap->vsa_mask = VSA_ACE | VSA_ACECNT;
1009da6c28aaSamw 			vsap->vsa_aclentsz = vsap->vsa_aclcnt * sizeof (ace_t);
10107c478bd9Sstevel@tonic-gate 
10117c478bd9Sstevel@tonic-gate 		}
10127c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
10137c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_aclsupport))
10147c478bd9Sstevel@tonic-gate 				return (FALSE);
10157c478bd9Sstevel@tonic-gate 		}
10167c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ARCHIVE_MASK) {
10177c478bd9Sstevel@tonic-gate 			ASSERT(0);
10187c478bd9Sstevel@tonic-gate 		}
10197c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CANSETTIME_MASK) {
10207c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
10217c478bd9Sstevel@tonic-gate 				return (FALSE);
10227c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_cansettime =
10230a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
10247c478bd9Sstevel@tonic-gate 		}
10257c478bd9Sstevel@tonic-gate 	}
10267c478bd9Sstevel@tonic-gate 	if (resbmap &
10277c478bd9Sstevel@tonic-gate 	    (FATTR4_CASE_INSENSITIVE_MASK |
10287c478bd9Sstevel@tonic-gate 	    FATTR4_CASE_PRESERVING_MASK |
10297c478bd9Sstevel@tonic-gate 	    FATTR4_CHOWN_RESTRICTED_MASK |
10307c478bd9Sstevel@tonic-gate 	    FATTR4_FILEHANDLE_MASK |
10317c478bd9Sstevel@tonic-gate 	    FATTR4_FILEID_MASK |
10327c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_AVAIL_MASK |
10337c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_FREE_MASK |
10347c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_TOTAL_MASK)) {
10357c478bd9Sstevel@tonic-gate 
10367c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
10377c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
10387c478bd9Sstevel@tonic-gate 				return (FALSE);
10397c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_insensitive =
10400a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
10417c478bd9Sstevel@tonic-gate 		}
10427c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
10437c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
10447c478bd9Sstevel@tonic-gate 				return (FALSE);
10457c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_preserving =
10460a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
10477c478bd9Sstevel@tonic-gate 		}
10487c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
10497c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
10507c478bd9Sstevel@tonic-gate 				return (FALSE);
10517c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_chown_restricted =
10520a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
10537c478bd9Sstevel@tonic-gate 		}
10547c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
10557c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
10567c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.val =
10570a701b1eSRobert Gordon 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
10587c478bd9Sstevel@tonic-gate 			if (!xdr_bytes(xdrs,
10597c478bd9Sstevel@tonic-gate 			    (char **)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_val,
10607c478bd9Sstevel@tonic-gate 			    (uint_t *)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_len,
10617c478bd9Sstevel@tonic-gate 			    NFS4_FHSIZE))
10627c478bd9Sstevel@tonic-gate 				return (FALSE);
10637c478bd9Sstevel@tonic-gate 		}
10647c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEID_MASK) {
10657c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
10660a701b1eSRobert Gordon 			    (u_longlong_t *)&vap->va_nodeid))
10677c478bd9Sstevel@tonic-gate 				return (FALSE);
10687c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NODEID;
10697c478bd9Sstevel@tonic-gate 		}
10707c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
10717c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
10720a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_favail))
10737c478bd9Sstevel@tonic-gate 				return (FALSE);
10747c478bd9Sstevel@tonic-gate 		}
10757c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_FREE_MASK) {
10767c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
10770a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_ffree))
10787c478bd9Sstevel@tonic-gate 				return (FALSE);
10797c478bd9Sstevel@tonic-gate 		}
10807c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
10817c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
10820a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_files))
10837c478bd9Sstevel@tonic-gate 				return (FALSE);
10847c478bd9Sstevel@tonic-gate 		}
10857c478bd9Sstevel@tonic-gate 	}
10867c478bd9Sstevel@tonic-gate 	if (resbmap &
10877c478bd9Sstevel@tonic-gate 	    (FATTR4_FS_LOCATIONS_MASK |
10887c478bd9Sstevel@tonic-gate 	    FATTR4_HIDDEN_MASK |
10897c478bd9Sstevel@tonic-gate 	    FATTR4_HOMOGENEOUS_MASK)) {
10907c478bd9Sstevel@tonic-gate 
10917c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
10922f172c55SRobert Thurlow 			if (!xdr_fattr4_fs_locations(xdrs,
10932f172c55SRobert Thurlow 			    &gesp->n4g_fslocations))
10942f172c55SRobert Thurlow 				return (FALSE);
10957c478bd9Sstevel@tonic-gate 		}
10967c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HIDDEN_MASK) {
10977c478bd9Sstevel@tonic-gate 			ASSERT(0);
10987c478bd9Sstevel@tonic-gate 		}
10997c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
11007c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
11017c478bd9Sstevel@tonic-gate 				return (FALSE);
11027c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_homogeneous =
11030a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
11047c478bd9Sstevel@tonic-gate 		}
11057c478bd9Sstevel@tonic-gate 	}
11067c478bd9Sstevel@tonic-gate 	if (resbmap &
11077c478bd9Sstevel@tonic-gate 	    (FATTR4_MAXFILESIZE_MASK |
11087c478bd9Sstevel@tonic-gate 	    FATTR4_MAXLINK_MASK |
11097c478bd9Sstevel@tonic-gate 	    FATTR4_MAXNAME_MASK |
11107c478bd9Sstevel@tonic-gate 	    FATTR4_MAXREAD_MASK |
11117c478bd9Sstevel@tonic-gate 	    FATTR4_MAXWRITE_MASK)) {
11127c478bd9Sstevel@tonic-gate 
11137c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
11147c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
11150a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_maxfilesize))
11167c478bd9Sstevel@tonic-gate 				return (FALSE);
11177c478bd9Sstevel@tonic-gate 		}
11187c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXLINK_MASK) {
11197c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs,
11200a701b1eSRobert Gordon 			    (int *)&gesp->n4g_pc4.pc4_link_max))
11217c478bd9Sstevel@tonic-gate 				return (FALSE);
11227c478bd9Sstevel@tonic-gate 		}
11237c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXNAME_MASK) {
11247c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs,
11250a701b1eSRobert Gordon 			    (int *)&gesp->n4g_pc4.pc4_name_max))
11267c478bd9Sstevel@tonic-gate 				return (FALSE);
11277c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
11287c478bd9Sstevel@tonic-gate 		}
11297c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXREAD_MASK) {
11307c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
11310a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_maxread))
11327c478bd9Sstevel@tonic-gate 				return (FALSE);
11337c478bd9Sstevel@tonic-gate 		}
11347c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXWRITE_MASK) {
11357c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
11360a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_maxwrite))
11377c478bd9Sstevel@tonic-gate 				return (FALSE);
11387c478bd9Sstevel@tonic-gate 		}
11397c478bd9Sstevel@tonic-gate 	}
11407c478bd9Sstevel@tonic-gate 	if (resbmap &
11417c478bd9Sstevel@tonic-gate 	    (FATTR4_MIMETYPE_MASK |
11427c478bd9Sstevel@tonic-gate 	    FATTR4_MODE_MASK |
11437c478bd9Sstevel@tonic-gate 	    FATTR4_NO_TRUNC_MASK |
11447c478bd9Sstevel@tonic-gate 	    FATTR4_NUMLINKS_MASK)) {
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MIMETYPE_MASK) {
11477c478bd9Sstevel@tonic-gate 			ASSERT(0);
11487c478bd9Sstevel@tonic-gate 		}
11497c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MODE_MASK) {
11507c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_mode))
11517c478bd9Sstevel@tonic-gate 				return (FALSE);
11527c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MODE;
11537c478bd9Sstevel@tonic-gate 		}
11547c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
11557c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
11567c478bd9Sstevel@tonic-gate 				return (FALSE);
11577c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_no_trunc =
11580a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
11597c478bd9Sstevel@tonic-gate 		}
11607c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NUMLINKS_MASK) {
11617c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_nlink))
11627c478bd9Sstevel@tonic-gate 				return (FALSE);
11637c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NLINK;
11647c478bd9Sstevel@tonic-gate 		}
11657c478bd9Sstevel@tonic-gate 	}
11667c478bd9Sstevel@tonic-gate 	if (resbmap &
11677c478bd9Sstevel@tonic-gate 	    (FATTR4_OWNER_MASK |
11687c478bd9Sstevel@tonic-gate 	    FATTR4_OWNER_GROUP_MASK |
11697c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
11707c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_MASK) {
11737c478bd9Sstevel@tonic-gate 			uint_t *owner_length, ol;
11747c478bd9Sstevel@tonic-gate 			char *owner_val = NULL;
11757c478bd9Sstevel@tonic-gate 			char *owner_alloc = NULL;
11767c478bd9Sstevel@tonic-gate 			utf8string ov;
11777c478bd9Sstevel@tonic-gate 			int error;
11787c478bd9Sstevel@tonic-gate 
11797c478bd9Sstevel@tonic-gate 			/* get the OWNER_LENGTH */
11807c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ol))
11817c478bd9Sstevel@tonic-gate 				return (FALSE);
11827c478bd9Sstevel@tonic-gate 
11837c478bd9Sstevel@tonic-gate 			/* Manage the owner length location */
11847c478bd9Sstevel@tonic-gate 			if (pug && ol <= MAX_OG_NAME) {
11857c478bd9Sstevel@tonic-gate 				owner_length = &pug->u_curr.utf8string_len;
11867c478bd9Sstevel@tonic-gate 				*owner_length = ol;
11877c478bd9Sstevel@tonic-gate 			} else {
11887c478bd9Sstevel@tonic-gate 				owner_length = &ol;
11897c478bd9Sstevel@tonic-gate 			}
11907c478bd9Sstevel@tonic-gate 
11917c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
11927c478bd9Sstevel@tonic-gate 			if (*owner_length > MAX_OG_NAME || pug == NULL)
11937c478bd9Sstevel@tonic-gate 				owner_val = owner_alloc =
11940a701b1eSRobert Gordon 				    kmem_alloc(*owner_length, KM_SLEEP);
11957c478bd9Sstevel@tonic-gate 			else
11967c478bd9Sstevel@tonic-gate 				owner_val = pug->u_curr.utf8string_val;
11977c478bd9Sstevel@tonic-gate 
11987c478bd9Sstevel@tonic-gate 			/* get the OWNER string */
11997c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, owner_val, *owner_length)) {
12007c478bd9Sstevel@tonic-gate 				if (owner_alloc)
12017c478bd9Sstevel@tonic-gate 					kmem_free(owner_alloc, *owner_length);
12027c478bd9Sstevel@tonic-gate 				return (FALSE);
12037c478bd9Sstevel@tonic-gate 			}
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
12067c478bd9Sstevel@tonic-gate 			if (pug &&
12077c478bd9Sstevel@tonic-gate 			    *owner_length == pug->u_last.utf8string_len &&
12087c478bd9Sstevel@tonic-gate 			    bcmp(owner_val, pug->u_last.utf8string_val,
12090a701b1eSRobert Gordon 			    *owner_length) == 0) {
12107c478bd9Sstevel@tonic-gate 				vap->va_uid = pug->uid;
12117c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_UID;
12127c478bd9Sstevel@tonic-gate 			} else {
12137c478bd9Sstevel@tonic-gate 				uid_t uid;
12147c478bd9Sstevel@tonic-gate 
12157c478bd9Sstevel@tonic-gate 				ov.utf8string_len = *owner_length;
12167c478bd9Sstevel@tonic-gate 				ov.utf8string_val = owner_val;
12177c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
12187c478bd9Sstevel@tonic-gate 				/*
12197c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
12207c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
12217c478bd9Sstevel@tonic-gate 				 * be cached.
12227c478bd9Sstevel@tonic-gate 				 */
12237c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
12247c478bd9Sstevel@tonic-gate 					error = 0;
12257c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
12260a701b1eSRobert Gordon 					    NFS4_GETATTR_NOCACHE_OK;
12277c478bd9Sstevel@tonic-gate 				}
12287c478bd9Sstevel@tonic-gate 
12297c478bd9Sstevel@tonic-gate 				if (error) {
12307c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
12317c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
12320a701b1eSRobert Gordon 					    NFS4_GETATTR_ATUID_ERR;
12337c478bd9Sstevel@tonic-gate 				} else {
12347c478bd9Sstevel@tonic-gate 					vap->va_uid = uid;
12357c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_UID;
12367c478bd9Sstevel@tonic-gate 					if (pug && ol <= MAX_OG_NAME) {
12377c478bd9Sstevel@tonic-gate 						pug->uid = uid;
12387c478bd9Sstevel@tonic-gate 						U_SWAP_CURR_LAST(pug);
12397c478bd9Sstevel@tonic-gate 					}
12407c478bd9Sstevel@tonic-gate 				}
12417c478bd9Sstevel@tonic-gate 				if (owner_alloc)
12427c478bd9Sstevel@tonic-gate 					kmem_free(owner_alloc, *owner_length);
12437c478bd9Sstevel@tonic-gate 			}
12447c478bd9Sstevel@tonic-gate 		}
12457c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
12467c478bd9Sstevel@tonic-gate 			uint_t *group_length, gl;
12477c478bd9Sstevel@tonic-gate 			char *group_val = NULL;
12487c478bd9Sstevel@tonic-gate 			char *group_alloc = NULL;
12497c478bd9Sstevel@tonic-gate 			utf8string gv;
12507c478bd9Sstevel@tonic-gate 			int error;
12517c478bd9Sstevel@tonic-gate 
12527c478bd9Sstevel@tonic-gate 			/* get the OWNER_GROUP_LENGTH */
12537c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &gl))
12547c478bd9Sstevel@tonic-gate 				return (FALSE);
12557c478bd9Sstevel@tonic-gate 
12567c478bd9Sstevel@tonic-gate 			/* Manage the group length location */
12577c478bd9Sstevel@tonic-gate 			if (pug && gl <= MAX_OG_NAME) {
12587c478bd9Sstevel@tonic-gate 				group_length = &pug->g_curr.utf8string_len;
12597c478bd9Sstevel@tonic-gate 				*group_length = gl;
12607c478bd9Sstevel@tonic-gate 			} else {
12617c478bd9Sstevel@tonic-gate 				group_length = &gl;
12627c478bd9Sstevel@tonic-gate 			}
12637c478bd9Sstevel@tonic-gate 
12647c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
12657c478bd9Sstevel@tonic-gate 			if (*group_length > MAX_OG_NAME || pug == NULL)
12667c478bd9Sstevel@tonic-gate 				group_val = group_alloc =
12670a701b1eSRobert Gordon 				    kmem_alloc(*group_length, KM_SLEEP);
12687c478bd9Sstevel@tonic-gate 			else
12697c478bd9Sstevel@tonic-gate 				group_val = pug->g_curr.utf8string_val;
12707c478bd9Sstevel@tonic-gate 
12717c478bd9Sstevel@tonic-gate 			/* get the OWNER_GROUP string */
12727c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, group_val, *group_length)) {
12737c478bd9Sstevel@tonic-gate 				if (group_alloc)
12747c478bd9Sstevel@tonic-gate 					kmem_free(group_alloc, *group_length);
12757c478bd9Sstevel@tonic-gate 				return (FALSE);
12767c478bd9Sstevel@tonic-gate 			}
12777c478bd9Sstevel@tonic-gate 
12787c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
12797c478bd9Sstevel@tonic-gate 			if (pug &&
12807c478bd9Sstevel@tonic-gate 			    *group_length == pug->g_last.utf8string_len &&
12817c478bd9Sstevel@tonic-gate 			    bcmp(group_val, pug->g_last.utf8string_val,
12820a701b1eSRobert Gordon 			    *group_length) == 0) {
12837c478bd9Sstevel@tonic-gate 				vap->va_gid = pug->gid;
12847c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_GID;
12857c478bd9Sstevel@tonic-gate 			} else {
12867c478bd9Sstevel@tonic-gate 				uid_t gid;
12877c478bd9Sstevel@tonic-gate 
12887c478bd9Sstevel@tonic-gate 				gv.utf8string_len = *group_length;
12897c478bd9Sstevel@tonic-gate 				gv.utf8string_val = group_val;
12907c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
12917c478bd9Sstevel@tonic-gate 				/*
12927c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
12937c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
12947c478bd9Sstevel@tonic-gate 				 * be cached.
12957c478bd9Sstevel@tonic-gate 				 */
12967c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
12977c478bd9Sstevel@tonic-gate 					error = 0;
12987c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
12990a701b1eSRobert Gordon 					    NFS4_GETATTR_NOCACHE_OK;
13007c478bd9Sstevel@tonic-gate 				}
13017c478bd9Sstevel@tonic-gate 
13027c478bd9Sstevel@tonic-gate 				if (error) {
13037c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
13047c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
13050a701b1eSRobert Gordon 					    NFS4_GETATTR_ATGID_ERR;
13067c478bd9Sstevel@tonic-gate 				} else {
13077c478bd9Sstevel@tonic-gate 					vap->va_gid = gid;
13087c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_GID;
13097c478bd9Sstevel@tonic-gate 					if (pug && gl <= MAX_OG_NAME) {
13107c478bd9Sstevel@tonic-gate 						pug->gid = gid;
13117c478bd9Sstevel@tonic-gate 						G_SWAP_CURR_LAST(pug);
13127c478bd9Sstevel@tonic-gate 					}
13137c478bd9Sstevel@tonic-gate 				}
13147c478bd9Sstevel@tonic-gate 				if (group_alloc) {
13157c478bd9Sstevel@tonic-gate 					kmem_free(group_alloc, *group_length);
13167c478bd9Sstevel@tonic-gate 				}
13177c478bd9Sstevel@tonic-gate 			}
13187c478bd9Sstevel@tonic-gate 		}
13197c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
13207c478bd9Sstevel@tonic-gate 			ASSERT(0);
13217c478bd9Sstevel@tonic-gate 		}
13227c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
13237c478bd9Sstevel@tonic-gate 			ASSERT(0);
13247c478bd9Sstevel@tonic-gate 		}
13257c478bd9Sstevel@tonic-gate 	}
13267c478bd9Sstevel@tonic-gate 	if (resbmap &
13277c478bd9Sstevel@tonic-gate 	    (FATTR4_QUOTA_USED_MASK |
13287c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_AVAIL_MASK |
13297c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_FREE_MASK |
13307c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_TOTAL_MASK |
13317c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_USED_MASK |
13327c478bd9Sstevel@tonic-gate 	    FATTR4_SYSTEM_MASK)) {
13337c478bd9Sstevel@tonic-gate 
13347c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
13357c478bd9Sstevel@tonic-gate 			ASSERT(0);
13367c478bd9Sstevel@tonic-gate 		}
13377c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RAWDEV_MASK) {
13387c478bd9Sstevel@tonic-gate 			fattr4_rawdev rawdev;
13397c478bd9Sstevel@tonic-gate 			if (!xdr_fattr4_rawdev(xdrs, &rawdev))
13407c478bd9Sstevel@tonic-gate 				return (FALSE);
13417c478bd9Sstevel@tonic-gate 
13427c478bd9Sstevel@tonic-gate 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
13437c478bd9Sstevel@tonic-gate 				vap->va_rdev = makedevice(rawdev.specdata1,
13440a701b1eSRobert Gordon 				    rawdev.specdata2);
13457c478bd9Sstevel@tonic-gate 			} else {
13467c478bd9Sstevel@tonic-gate 				vap->va_rdev = 0;
13477c478bd9Sstevel@tonic-gate 			}
13487c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_RDEV;
13497c478bd9Sstevel@tonic-gate 		}
13507c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
13517c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
13520a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_bavail))
13537c478bd9Sstevel@tonic-gate 				return (FALSE);
13547c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
13557c478bd9Sstevel@tonic-gate 		}
13567c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
13577c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
13580a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_bfree))
13597c478bd9Sstevel@tonic-gate 				return (FALSE);
13607c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
13617c478bd9Sstevel@tonic-gate 		}
13627c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
13637c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
13640a701b1eSRobert Gordon 			    (u_longlong_t *)&gesp->n4g_sb.f_blocks))
13657c478bd9Sstevel@tonic-gate 				return (FALSE);
13667c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
13677c478bd9Sstevel@tonic-gate 		}
13687c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_USED_MASK) {
13697c478bd9Sstevel@tonic-gate 			uint64_t space_used;
13707c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
13710a701b1eSRobert Gordon 			    (u_longlong_t *)&space_used))
13727c478bd9Sstevel@tonic-gate 				return (FALSE);
13737c478bd9Sstevel@tonic-gate 
13747c478bd9Sstevel@tonic-gate 			/* Compute space depending on device type */
13757c478bd9Sstevel@tonic-gate 			ASSERT((vap->va_mask & AT_TYPE));
13767c478bd9Sstevel@tonic-gate 			if (vap->va_type == VREG || vap->va_type == VDIR ||
13777c478bd9Sstevel@tonic-gate 			    vap->va_type == VLNK) {
13787c478bd9Sstevel@tonic-gate 				vap->va_nblocks = (u_longlong_t)
13790a701b1eSRobert Gordon 				    ((space_used + (offset4)DEV_BSIZE -
13800a701b1eSRobert Gordon 				    (offset4)1) / (offset4)DEV_BSIZE);
13817c478bd9Sstevel@tonic-gate 			} else {
13827c478bd9Sstevel@tonic-gate 				vap->va_nblocks = 0;
13837c478bd9Sstevel@tonic-gate 			}
13847c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NBLOCKS;
13857c478bd9Sstevel@tonic-gate 		}
13867c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYSTEM_MASK) {
13877c478bd9Sstevel@tonic-gate 			ASSERT(0);
13887c478bd9Sstevel@tonic-gate 		}
13897c478bd9Sstevel@tonic-gate 	}
13907c478bd9Sstevel@tonic-gate 	if (resbmap &
13917c478bd9Sstevel@tonic-gate 	    (FATTR4_TIME_ACCESS_MASK |
13927c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_ACCESS_SET_MASK |
13937c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_BACKUP_MASK |
13947c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_CREATE_MASK |
13957c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_DELTA_MASK |
13967c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_METADATA_MASK |
13977c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_MASK |
13987c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_SET_MASK |
13997c478bd9Sstevel@tonic-gate 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
14007c478bd9Sstevel@tonic-gate 
14017c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
14027c478bd9Sstevel@tonic-gate 			nfstime4 atime;
14037c478bd9Sstevel@tonic-gate 			int error;
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate 			if (!xdr_longlong_t(xdrs,
14060a701b1eSRobert Gordon 			    (longlong_t *)&atime.seconds))
14077c478bd9Sstevel@tonic-gate 				return (FALSE);
14087c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&atime.nseconds))
14097c478bd9Sstevel@tonic-gate 				return (FALSE);
14107c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&atime, &vap->va_atime);
14117c478bd9Sstevel@tonic-gate 			if (error) {
14127c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
14137c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
14147c478bd9Sstevel@tonic-gate 			}
14157c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_ATIME;
14167c478bd9Sstevel@tonic-gate 		}
14177c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
14187c478bd9Sstevel@tonic-gate 			ASSERT(0);
14197c478bd9Sstevel@tonic-gate 		}
14207c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
14217c478bd9Sstevel@tonic-gate 			ASSERT(0);
14227c478bd9Sstevel@tonic-gate 		}
14237c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
14247c478bd9Sstevel@tonic-gate 			ASSERT(0);
14257c478bd9Sstevel@tonic-gate 		}
14267c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
14277c478bd9Sstevel@tonic-gate 			if ((!xdr_u_longlong_t(xdrs,
14287c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_delta.seconds)) ||
14297c478bd9Sstevel@tonic-gate 			    (!xdr_u_int(xdrs, &gesp->n4g_delta.nseconds)))
14307c478bd9Sstevel@tonic-gate 				return (FALSE);
14317c478bd9Sstevel@tonic-gate 		}
14327c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
14337c478bd9Sstevel@tonic-gate 			nfstime4 mdt;
14347c478bd9Sstevel@tonic-gate 			int error;
14357c478bd9Sstevel@tonic-gate 
14367c478bd9Sstevel@tonic-gate 			if (!xdr_longlong_t(xdrs, (longlong_t *)&mdt.seconds))
14377c478bd9Sstevel@tonic-gate 				return (FALSE);
14387c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&mdt.nseconds))
14397c478bd9Sstevel@tonic-gate 				return (FALSE);
14407c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
14417c478bd9Sstevel@tonic-gate 			if (error) {
14427c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
14437c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
14447c478bd9Sstevel@tonic-gate 			}
14457c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_CTIME;
14467c478bd9Sstevel@tonic-gate 		}
14477c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
14487c478bd9Sstevel@tonic-gate 			nfstime4 mtime;
14497c478bd9Sstevel@tonic-gate 			int error;
14507c478bd9Sstevel@tonic-gate 
14517c478bd9Sstevel@tonic-gate 			if (!xdr_longlong_t(xdrs,
14520a701b1eSRobert Gordon 			    (longlong_t *)&mtime.seconds))
14537c478bd9Sstevel@tonic-gate 				return (FALSE);
14547c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&mtime.nseconds))
14557c478bd9Sstevel@tonic-gate 				return (FALSE);
14567c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
14577c478bd9Sstevel@tonic-gate 			if (error) {
14587c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
14597c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
14607c478bd9Sstevel@tonic-gate 			}
14617c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MTIME;
14627c478bd9Sstevel@tonic-gate 		}
14637c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
14647c478bd9Sstevel@tonic-gate 			ASSERT(0);
14657c478bd9Sstevel@tonic-gate 		}
14667c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
14677c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
14680a701b1eSRobert Gordon 			    (u_longlong_t *)&garp->n4g_mon_fid))
14697c478bd9Sstevel@tonic-gate 				return (FALSE);
14707c478bd9Sstevel@tonic-gate 			garp->n4g_mon_fid_valid = 1;
14717c478bd9Sstevel@tonic-gate 		}
14727c478bd9Sstevel@tonic-gate 	}
14737c478bd9Sstevel@tonic-gate 
14747c478bd9Sstevel@tonic-gate 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
14757c478bd9Sstevel@tonic-gate 		/* copy only if not provided */
14767c478bd9Sstevel@tonic-gate 		if (garp->n4g_ext_res == NULL) {
14777c478bd9Sstevel@tonic-gate 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
14787c478bd9Sstevel@tonic-gate 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
14797c478bd9Sstevel@tonic-gate 		}
14807c478bd9Sstevel@tonic-gate 	}
14817c478bd9Sstevel@tonic-gate 
14827c478bd9Sstevel@tonic-gate 	return (TRUE);
14837c478bd9Sstevel@tonic-gate }
14847c478bd9Sstevel@tonic-gate 
14857c478bd9Sstevel@tonic-gate /*
14867c478bd9Sstevel@tonic-gate  * Inlined version of get_bitmap4 processing
14877c478bd9Sstevel@tonic-gate  */
14887c478bd9Sstevel@tonic-gate bitmap4
14897c478bd9Sstevel@tonic-gate xdr_get_bitmap4_inline(uint32_t **iptr)
14907c478bd9Sstevel@tonic-gate {
14917c478bd9Sstevel@tonic-gate 	uint32_t resbmaplen;
14927c478bd9Sstevel@tonic-gate 	bitmap4 bm;
14937c478bd9Sstevel@tonic-gate 	uint32_t *ptr = *iptr;
14947c478bd9Sstevel@tonic-gate 
14957c478bd9Sstevel@tonic-gate 	/* bitmap LENGTH */
14967c478bd9Sstevel@tonic-gate 	resbmaplen = IXDR_GET_U_INT32(ptr);
14977c478bd9Sstevel@tonic-gate 
14987c478bd9Sstevel@tonic-gate 	/* Inline the bitmap and attrlen for common case of two word map */
14997c478bd9Sstevel@tonic-gate 	if (resbmaplen == 2) {
15007c478bd9Sstevel@tonic-gate 		IXDR_GET_HYPER(ptr, bm);
15017c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15027c478bd9Sstevel@tonic-gate 		return (bm);
15037c478bd9Sstevel@tonic-gate 	}
15047c478bd9Sstevel@tonic-gate 
15057c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
15067c478bd9Sstevel@tonic-gate 	bm = IXDR_GET_U_INT32(ptr);
15077c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
15087c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15097c478bd9Sstevel@tonic-gate 		return (bm);
15107c478bd9Sstevel@tonic-gate 	}
15117c478bd9Sstevel@tonic-gate 	*((uint32_t *)&bm) |= IXDR_GET_U_INT32(ptr);
15127c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
15137c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15147c478bd9Sstevel@tonic-gate 		return (bm);
15157c478bd9Sstevel@tonic-gate 	}
15167c478bd9Sstevel@tonic-gate 	ptr += resbmaplen;
15177c478bd9Sstevel@tonic-gate 	*iptr = ptr;
15187c478bd9Sstevel@tonic-gate 	return (bm);
15197c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
15207c478bd9Sstevel@tonic-gate 	*((uint32_t *)&bm) = IXDR_GET_U_INT32(ptr);
15217c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
15227c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15237c478bd9Sstevel@tonic-gate 		return (bm);
15247c478bd9Sstevel@tonic-gate 	}
15257c478bd9Sstevel@tonic-gate 	bm |= IXDR_GET_U_INT32(ptr);
15267c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
15277c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15287c478bd9Sstevel@tonic-gate 		return (bm);
15297c478bd9Sstevel@tonic-gate 	}
15307c478bd9Sstevel@tonic-gate 	ptr += resbmaplen;
15317c478bd9Sstevel@tonic-gate 	*iptr = ptr;
15327c478bd9Sstevel@tonic-gate 	return (bm);
15337c478bd9Sstevel@tonic-gate #else
15347c478bd9Sstevel@tonic-gate 	ASSERT(0);
15357c478bd9Sstevel@tonic-gate 	ptr += resbmaplen;
15367c478bd9Sstevel@tonic-gate 	*iptr = ptr;
15377c478bd9Sstevel@tonic-gate 	return (0);
15387c478bd9Sstevel@tonic-gate #endif
15397c478bd9Sstevel@tonic-gate }
15407c478bd9Sstevel@tonic-gate 
15417c478bd9Sstevel@tonic-gate static bool_t
15427c478bd9Sstevel@tonic-gate xdr_ga_fattr_res_inline(uint32_t *ptr, struct nfs4_ga_res *garp,
15437c478bd9Sstevel@tonic-gate 			bitmap4 resbmap, bitmap4 argbmap, struct mntinfo4 *mi,
15447c478bd9Sstevel@tonic-gate 			ug_cache_t *pug)
15457c478bd9Sstevel@tonic-gate {
15467c478bd9Sstevel@tonic-gate 	int truefalse;
15477c478bd9Sstevel@tonic-gate 	struct nfs4_ga_ext_res ges, *gesp;
15487c478bd9Sstevel@tonic-gate 	vattr_t *vap = &garp->n4g_va;
15497c478bd9Sstevel@tonic-gate 
15507c478bd9Sstevel@tonic-gate 	if (garp->n4g_ext_res)
15517c478bd9Sstevel@tonic-gate 		gesp = garp->n4g_ext_res;
15527c478bd9Sstevel@tonic-gate 	else
15537c478bd9Sstevel@tonic-gate 		gesp = &ges;
15547c478bd9Sstevel@tonic-gate 
15557c478bd9Sstevel@tonic-gate 	vap->va_mask = 0;
15567c478bd9Sstevel@tonic-gate 
15577c478bd9Sstevel@tonic-gate 	/* Check to see if the vattr should be pre-filled */
15587c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_VATTR_MASK)
15597c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_vattr(garp, mi);
15607c478bd9Sstevel@tonic-gate 
15617c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_STATFS_ATTR_MASK)
15627c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_statvfs(gesp, mi);
15637c478bd9Sstevel@tonic-gate 
15647c478bd9Sstevel@tonic-gate 	if (resbmap &
15657c478bd9Sstevel@tonic-gate 	    (FATTR4_SUPPORTED_ATTRS_MASK |
15667c478bd9Sstevel@tonic-gate 	    FATTR4_TYPE_MASK |
15677c478bd9Sstevel@tonic-gate 	    FATTR4_FH_EXPIRE_TYPE_MASK |
15687c478bd9Sstevel@tonic-gate 	    FATTR4_CHANGE_MASK |
15697c478bd9Sstevel@tonic-gate 	    FATTR4_SIZE_MASK |
15707c478bd9Sstevel@tonic-gate 	    FATTR4_LINK_SUPPORT_MASK |
15717c478bd9Sstevel@tonic-gate 	    FATTR4_SYMLINK_SUPPORT_MASK |
15727c478bd9Sstevel@tonic-gate 	    FATTR4_NAMED_ATTR_MASK)) {
15737c478bd9Sstevel@tonic-gate 
15747c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
15757c478bd9Sstevel@tonic-gate 			gesp->n4g_suppattrs = xdr_get_bitmap4_inline(&ptr);
15767c478bd9Sstevel@tonic-gate 		}
15777c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TYPE_MASK) {
15787c478bd9Sstevel@tonic-gate 			vap->va_type = IXDR_GET_U_INT32(ptr);
15797c478bd9Sstevel@tonic-gate 
15802c2d21e9SRichard Lowe 			if ((nfs_ftype4)vap->va_type < NF4REG ||
15812c2d21e9SRichard Lowe 			    (nfs_ftype4)vap->va_type > NF4NAMEDATTR)
15827c478bd9Sstevel@tonic-gate 				vap->va_type = VBAD;
15837c478bd9Sstevel@tonic-gate 			else
15847c478bd9Sstevel@tonic-gate 				vap->va_type = nf4_to_vt[vap->va_type];
15857c478bd9Sstevel@tonic-gate 			if (vap->va_type == VBLK)
15867c478bd9Sstevel@tonic-gate 				vap->va_blksize = DEV_BSIZE;
15877c478bd9Sstevel@tonic-gate 
15887c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_TYPE;
15897c478bd9Sstevel@tonic-gate 		}
15907c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
15917c478bd9Sstevel@tonic-gate 			gesp->n4g_fet = IXDR_GET_U_INT32(ptr);
15927c478bd9Sstevel@tonic-gate 		}
15937c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHANGE_MASK) {
15947c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_change);
15957c478bd9Sstevel@tonic-gate 			garp->n4g_change_valid = 1;
15967c478bd9Sstevel@tonic-gate 		}
15977c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SIZE_MASK) {
15987c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, vap->va_size);
15997c478bd9Sstevel@tonic-gate 
16007c478bd9Sstevel@tonic-gate 			if (!NFS4_SIZE_OK(vap->va_size)) {
16017c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = EFBIG;
16027c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
16037c478bd9Sstevel@tonic-gate 			} else {
16047c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_SIZE;
16057c478bd9Sstevel@tonic-gate 			}
16067c478bd9Sstevel@tonic-gate 		}
16077c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
16087c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16097c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_link_support =
16100a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
16117c478bd9Sstevel@tonic-gate 		}
16127c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
16137c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16147c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_symlink_support =
16150a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
16167c478bd9Sstevel@tonic-gate 		}
16177c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
16187c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16197c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
16207c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists =
16210a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
16227c478bd9Sstevel@tonic-gate 		}
16237c478bd9Sstevel@tonic-gate 	}
16247c478bd9Sstevel@tonic-gate 	if (resbmap &
16257c478bd9Sstevel@tonic-gate 	    (FATTR4_FSID_MASK |
16267c478bd9Sstevel@tonic-gate 	    FATTR4_UNIQUE_HANDLES_MASK |
16277c478bd9Sstevel@tonic-gate 	    FATTR4_LEASE_TIME_MASK |
16287c478bd9Sstevel@tonic-gate 	    FATTR4_RDATTR_ERROR_MASK)) {
16297c478bd9Sstevel@tonic-gate 
16307c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FSID_MASK) {
16317c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.major);
16327c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.minor);
16337c478bd9Sstevel@tonic-gate 			garp->n4g_fsid_valid = 1;
16347c478bd9Sstevel@tonic-gate 		}
16357c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
16367c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16377c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_unique_handles =
16380a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
16397c478bd9Sstevel@tonic-gate 		}
16407c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
16417c478bd9Sstevel@tonic-gate 			gesp->n4g_leasetime = IXDR_GET_U_INT32(ptr);
16427c478bd9Sstevel@tonic-gate 		}
16437c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
16447c478bd9Sstevel@tonic-gate 			gesp->n4g_rdattr_error = IXDR_GET_U_INT32(ptr);
16457c478bd9Sstevel@tonic-gate 		}
16467c478bd9Sstevel@tonic-gate 	}
16477c478bd9Sstevel@tonic-gate 	if (resbmap &
16487c478bd9Sstevel@tonic-gate 	    (FATTR4_ACL_MASK |
16497c478bd9Sstevel@tonic-gate 	    FATTR4_ACLSUPPORT_MASK |
16507c478bd9Sstevel@tonic-gate 	    FATTR4_ARCHIVE_MASK |
16517c478bd9Sstevel@tonic-gate 	    FATTR4_CANSETTIME_MASK)) {
16527c478bd9Sstevel@tonic-gate 
16537c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACL_MASK) {
16547c478bd9Sstevel@tonic-gate 			ASSERT(0);
16557c478bd9Sstevel@tonic-gate 		}
16567c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
16577c478bd9Sstevel@tonic-gate 			gesp->n4g_aclsupport = IXDR_GET_U_INT32(ptr);
16587c478bd9Sstevel@tonic-gate 		}
16597c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ARCHIVE_MASK) {
16607c478bd9Sstevel@tonic-gate 			ASSERT(0);
16617c478bd9Sstevel@tonic-gate 		}
16627c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CANSETTIME_MASK) {
16637c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16647c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_cansettime =
16650a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
16667c478bd9Sstevel@tonic-gate 		}
16677c478bd9Sstevel@tonic-gate 	}
16687c478bd9Sstevel@tonic-gate 	if (resbmap &
16697c478bd9Sstevel@tonic-gate 	    (FATTR4_CASE_INSENSITIVE_MASK |
16707c478bd9Sstevel@tonic-gate 	    FATTR4_CASE_PRESERVING_MASK |
16717c478bd9Sstevel@tonic-gate 	    FATTR4_CHOWN_RESTRICTED_MASK |
16727c478bd9Sstevel@tonic-gate 	    FATTR4_FILEHANDLE_MASK |
16737c478bd9Sstevel@tonic-gate 	    FATTR4_FILEID_MASK |
16747c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_AVAIL_MASK |
16757c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_FREE_MASK |
16767c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_TOTAL_MASK)) {
16777c478bd9Sstevel@tonic-gate 
16787c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
16797c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16807c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_insensitive =
16810a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
16827c478bd9Sstevel@tonic-gate 		}
16837c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
16847c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16857c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_preserving =
16860a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
16877c478bd9Sstevel@tonic-gate 		}
16887c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
16897c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16907c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_chown_restricted =
16910a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
16927c478bd9Sstevel@tonic-gate 		}
16937c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
16947c478bd9Sstevel@tonic-gate 			int len = IXDR_GET_U_INT32(ptr);
16957c478bd9Sstevel@tonic-gate 
16967c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
16977c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.val =
16980a701b1eSRobert Gordon 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
16997c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.n4g_fh.nfs_fh4_len = len;
17007c478bd9Sstevel@tonic-gate 
17017c478bd9Sstevel@tonic-gate 			bcopy(ptr, gesp->n4g_fh_u.n4g_fh.nfs_fh4_val, len);
17027c478bd9Sstevel@tonic-gate 
17037c478bd9Sstevel@tonic-gate 			ptr += RNDUP(len) / BYTES_PER_XDR_UNIT;
17047c478bd9Sstevel@tonic-gate 		}
17057c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEID_MASK) {
17067c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
17077c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NODEID;
17087c478bd9Sstevel@tonic-gate 		}
17097c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
17107c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_favail);
17117c478bd9Sstevel@tonic-gate 		}
17127c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_FREE_MASK) {
17137c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_ffree);
17147c478bd9Sstevel@tonic-gate 		}
17157c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
17167c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_files);
17177c478bd9Sstevel@tonic-gate 		}
17187c478bd9Sstevel@tonic-gate 	}
17197c478bd9Sstevel@tonic-gate 	if (resbmap &
17207c478bd9Sstevel@tonic-gate 	    (FATTR4_FS_LOCATIONS_MASK |
17217c478bd9Sstevel@tonic-gate 	    FATTR4_HIDDEN_MASK |
17227c478bd9Sstevel@tonic-gate 	    FATTR4_HOMOGENEOUS_MASK)) {
17237c478bd9Sstevel@tonic-gate 
17247c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
17257c478bd9Sstevel@tonic-gate 			ASSERT(0);
17267c478bd9Sstevel@tonic-gate 		}
17277c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HIDDEN_MASK) {
17287c478bd9Sstevel@tonic-gate 			ASSERT(0);
17297c478bd9Sstevel@tonic-gate 		}
17307c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
17317c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
17327c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_homogeneous =
17330a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
17347c478bd9Sstevel@tonic-gate 		}
17357c478bd9Sstevel@tonic-gate 	}
17367c478bd9Sstevel@tonic-gate 	if (resbmap &
17377c478bd9Sstevel@tonic-gate 	    (FATTR4_MAXFILESIZE_MASK |
17387c478bd9Sstevel@tonic-gate 	    FATTR4_MAXLINK_MASK |
17397c478bd9Sstevel@tonic-gate 	    FATTR4_MAXNAME_MASK |
17407c478bd9Sstevel@tonic-gate 	    FATTR4_MAXREAD_MASK |
17417c478bd9Sstevel@tonic-gate 	    FATTR4_MAXWRITE_MASK)) {
17427c478bd9Sstevel@tonic-gate 
17437c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
17447c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxfilesize);
17457c478bd9Sstevel@tonic-gate 		}
17467c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXLINK_MASK) {
17477c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_link_max = IXDR_GET_U_INT32(ptr);
17487c478bd9Sstevel@tonic-gate 		}
17497c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXNAME_MASK) {
17507c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_name_max = IXDR_GET_U_INT32(ptr);
17517c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
17527c478bd9Sstevel@tonic-gate 		}
17537c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXREAD_MASK) {
17547c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxread);
17557c478bd9Sstevel@tonic-gate 		}
17567c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXWRITE_MASK) {
17577c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxwrite);
17587c478bd9Sstevel@tonic-gate 		}
17597c478bd9Sstevel@tonic-gate 	}
17607c478bd9Sstevel@tonic-gate 	if (resbmap &
17617c478bd9Sstevel@tonic-gate 	    (FATTR4_MIMETYPE_MASK |
17627c478bd9Sstevel@tonic-gate 	    FATTR4_MODE_MASK |
17637c478bd9Sstevel@tonic-gate 	    FATTR4_NO_TRUNC_MASK |
17647c478bd9Sstevel@tonic-gate 	    FATTR4_NUMLINKS_MASK)) {
17657c478bd9Sstevel@tonic-gate 
17667c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MIMETYPE_MASK) {
17677c478bd9Sstevel@tonic-gate 			ASSERT(0);
17687c478bd9Sstevel@tonic-gate 		}
17697c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MODE_MASK) {
17707c478bd9Sstevel@tonic-gate 			vap->va_mode = IXDR_GET_U_INT32(ptr);
17717c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MODE;
17727c478bd9Sstevel@tonic-gate 		}
17737c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
17747c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
17757c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_no_trunc =
17760a701b1eSRobert Gordon 			    (truefalse ? TRUE : FALSE);
17777c478bd9Sstevel@tonic-gate 		}
17787c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NUMLINKS_MASK) {
17797c478bd9Sstevel@tonic-gate 			vap->va_nlink = IXDR_GET_U_INT32(ptr);
17807c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NLINK;
17817c478bd9Sstevel@tonic-gate 		}
17827c478bd9Sstevel@tonic-gate 	}
17837c478bd9Sstevel@tonic-gate 	if (resbmap &
17847c478bd9Sstevel@tonic-gate 	    (FATTR4_OWNER_MASK |
17857c478bd9Sstevel@tonic-gate 	    FATTR4_OWNER_GROUP_MASK |
17867c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
17877c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
17887c478bd9Sstevel@tonic-gate 
17897c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_MASK) {
17907c478bd9Sstevel@tonic-gate 			uint_t *owner_length, ol;
17917c478bd9Sstevel@tonic-gate 			char *owner_val = NULL;
17927c478bd9Sstevel@tonic-gate 			utf8string ov;
17937c478bd9Sstevel@tonic-gate 			int error;
17947c478bd9Sstevel@tonic-gate 
17957c478bd9Sstevel@tonic-gate 			/* get the OWNER_LENGTH */
17967c478bd9Sstevel@tonic-gate 			ol = IXDR_GET_U_INT32(ptr);
17977c478bd9Sstevel@tonic-gate 
17987c478bd9Sstevel@tonic-gate 			/* Manage the owner length location */
17997c478bd9Sstevel@tonic-gate 			if (pug && ol <= MAX_OG_NAME) {
18007c478bd9Sstevel@tonic-gate 				owner_length = &pug->u_curr.utf8string_len;
18017c478bd9Sstevel@tonic-gate 				*owner_length = ol;
18027c478bd9Sstevel@tonic-gate 			} else {
18037c478bd9Sstevel@tonic-gate 				owner_length = &ol;
18047c478bd9Sstevel@tonic-gate 			}
18057c478bd9Sstevel@tonic-gate 
18067c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
18077c478bd9Sstevel@tonic-gate 			if (*owner_length > MAX_OG_NAME || pug == NULL)
18087c478bd9Sstevel@tonic-gate 				owner_val = (char *)ptr;
18097c478bd9Sstevel@tonic-gate 			else
18107c478bd9Sstevel@tonic-gate 				owner_val = (char *)ptr;
18117c478bd9Sstevel@tonic-gate 
18127c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
18137c478bd9Sstevel@tonic-gate 			if (pug &&
18147c478bd9Sstevel@tonic-gate 			    *owner_length == pug->u_last.utf8string_len &&
18157c478bd9Sstevel@tonic-gate 			    bcmp(owner_val, pug->u_last.utf8string_val,
18160a701b1eSRobert Gordon 			    *owner_length) == 0) {
18177c478bd9Sstevel@tonic-gate 				vap->va_uid = pug->uid;
18187c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_UID;
18197c478bd9Sstevel@tonic-gate 			} else {
18207c478bd9Sstevel@tonic-gate 				uid_t uid;
18217c478bd9Sstevel@tonic-gate 
18227c478bd9Sstevel@tonic-gate 				ov.utf8string_len = *owner_length;
18237c478bd9Sstevel@tonic-gate 				ov.utf8string_val = owner_val;
18247c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
18257c478bd9Sstevel@tonic-gate 				/*
18267c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
18277c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
18287c478bd9Sstevel@tonic-gate 				 * be cached.
18297c478bd9Sstevel@tonic-gate 				 */
18307c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
18317c478bd9Sstevel@tonic-gate 					error = 0;
18327c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
18330a701b1eSRobert Gordon 					    NFS4_GETATTR_NOCACHE_OK;
18347c478bd9Sstevel@tonic-gate 				}
18357c478bd9Sstevel@tonic-gate 
18367c478bd9Sstevel@tonic-gate 				if (error) {
18377c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
18387c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
18390a701b1eSRobert Gordon 					    NFS4_GETATTR_ATUID_ERR;
18407c478bd9Sstevel@tonic-gate 				} else {
18417c478bd9Sstevel@tonic-gate 					vap->va_uid = uid;
18427c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_UID;
18437c478bd9Sstevel@tonic-gate 					/* save the results for next time */
18447c478bd9Sstevel@tonic-gate 					if (pug && ol <= MAX_OG_NAME) {
18457c478bd9Sstevel@tonic-gate 						pug->uid = uid;
18467c478bd9Sstevel@tonic-gate 						pug->u_curr.utf8string_len =
18470a701b1eSRobert Gordon 						    ov.utf8string_len;
18487c478bd9Sstevel@tonic-gate 						bcopy(owner_val,
18490a701b1eSRobert Gordon 						    pug->u_curr.utf8string_val,
18500a701b1eSRobert Gordon 						    ol);
18517c478bd9Sstevel@tonic-gate 						U_SWAP_CURR_LAST(pug);
18527c478bd9Sstevel@tonic-gate 					}
18537c478bd9Sstevel@tonic-gate 				}
18547c478bd9Sstevel@tonic-gate 			}
18557c478bd9Sstevel@tonic-gate 			ptr += RNDUP(ol) / BYTES_PER_XDR_UNIT;
18567c478bd9Sstevel@tonic-gate 		}
18577c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
18587c478bd9Sstevel@tonic-gate 			uint_t *group_length, gl;
18597c478bd9Sstevel@tonic-gate 			char *group_val = NULL;
18607c478bd9Sstevel@tonic-gate 			utf8string gv;
18617c478bd9Sstevel@tonic-gate 			int error;
18627c478bd9Sstevel@tonic-gate 
18637c478bd9Sstevel@tonic-gate 			/* get the OWNER_GROUP_LENGTH */
18647c478bd9Sstevel@tonic-gate 			gl = IXDR_GET_U_INT32(ptr);
18657c478bd9Sstevel@tonic-gate 
18667c478bd9Sstevel@tonic-gate 			/* Manage the group length location */
18677c478bd9Sstevel@tonic-gate 			if (pug && gl <= MAX_OG_NAME) {
18687c478bd9Sstevel@tonic-gate 				group_length = &pug->g_curr.utf8string_len;
18697c478bd9Sstevel@tonic-gate 				*group_length = gl;
18707c478bd9Sstevel@tonic-gate 			} else {
18717c478bd9Sstevel@tonic-gate 				group_length = &gl;
18727c478bd9Sstevel@tonic-gate 			}
18737c478bd9Sstevel@tonic-gate 
18747c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
18757c478bd9Sstevel@tonic-gate 			if (*group_length > MAX_OG_NAME || pug == NULL)
18767c478bd9Sstevel@tonic-gate 				group_val = (char *)ptr;
18777c478bd9Sstevel@tonic-gate 			else
18787c478bd9Sstevel@tonic-gate 				group_val = (char *)ptr;
18797c478bd9Sstevel@tonic-gate 
18807c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
18817c478bd9Sstevel@tonic-gate 			if (pug &&
18827c478bd9Sstevel@tonic-gate 			    *group_length == pug->g_last.utf8string_len &&
18837c478bd9Sstevel@tonic-gate 			    bcmp(group_val, pug->g_last.utf8string_val,
18840a701b1eSRobert Gordon 			    *group_length) == 0) {
18857c478bd9Sstevel@tonic-gate 				vap->va_gid = pug->gid;
18867c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_GID;
18877c478bd9Sstevel@tonic-gate 			} else {
18887c478bd9Sstevel@tonic-gate 				uid_t gid;
18897c478bd9Sstevel@tonic-gate 
18907c478bd9Sstevel@tonic-gate 				gv.utf8string_len = *group_length;
18917c478bd9Sstevel@tonic-gate 				gv.utf8string_val = group_val;
18927c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
18937c478bd9Sstevel@tonic-gate 				/*
18947c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
18957c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
18967c478bd9Sstevel@tonic-gate 				 * be cached.
18977c478bd9Sstevel@tonic-gate 				 */
18987c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
18997c478bd9Sstevel@tonic-gate 					error = 0;
19007c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
19010a701b1eSRobert Gordon 					    NFS4_GETATTR_NOCACHE_OK;
19027c478bd9Sstevel@tonic-gate 				}
19037c478bd9Sstevel@tonic-gate 
19047c478bd9Sstevel@tonic-gate 				if (error) {
19057c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
19067c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
19070a701b1eSRobert Gordon 					    NFS4_GETATTR_ATGID_ERR;
19087c478bd9Sstevel@tonic-gate 				} else {
19097c478bd9Sstevel@tonic-gate 					vap->va_gid = gid;
19107c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_GID;
19117c478bd9Sstevel@tonic-gate 					if (pug && gl <= MAX_OG_NAME) {
19127c478bd9Sstevel@tonic-gate 						pug->gid = gid;
19137c478bd9Sstevel@tonic-gate 						pug->g_curr.utf8string_len =
19140a701b1eSRobert Gordon 						    gv.utf8string_len;
19157c478bd9Sstevel@tonic-gate 						bcopy(group_val,
19167c478bd9Sstevel@tonic-gate 						    pug->g_curr.utf8string_val,
19177c478bd9Sstevel@tonic-gate 						    gl);
19187c478bd9Sstevel@tonic-gate 						G_SWAP_CURR_LAST(pug);
19197c478bd9Sstevel@tonic-gate 					}
19207c478bd9Sstevel@tonic-gate 				}
19217c478bd9Sstevel@tonic-gate 			}
19227c478bd9Sstevel@tonic-gate 			ptr += RNDUP(gl) / BYTES_PER_XDR_UNIT;
19237c478bd9Sstevel@tonic-gate 		}
19247c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
19257c478bd9Sstevel@tonic-gate 			ASSERT(0);
19267c478bd9Sstevel@tonic-gate 		}
19277c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
19287c478bd9Sstevel@tonic-gate 			ASSERT(0);
19297c478bd9Sstevel@tonic-gate 		}
19307c478bd9Sstevel@tonic-gate 	}
19317c478bd9Sstevel@tonic-gate 	if (resbmap &
19327c478bd9Sstevel@tonic-gate 	    (FATTR4_QUOTA_USED_MASK |
19337c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_AVAIL_MASK |
19347c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_FREE_MASK |
19357c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_TOTAL_MASK |
19367c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_USED_MASK |
19377c478bd9Sstevel@tonic-gate 	    FATTR4_SYSTEM_MASK)) {
19387c478bd9Sstevel@tonic-gate 
19397c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
19407c478bd9Sstevel@tonic-gate 			ASSERT(0);
19417c478bd9Sstevel@tonic-gate 		}
19427c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RAWDEV_MASK) {
19437c478bd9Sstevel@tonic-gate 			fattr4_rawdev rawdev;
19447c478bd9Sstevel@tonic-gate 
19457c478bd9Sstevel@tonic-gate 			rawdev.specdata1 = IXDR_GET_U_INT32(ptr);
19467c478bd9Sstevel@tonic-gate 			rawdev.specdata2 = IXDR_GET_U_INT32(ptr);
19477c478bd9Sstevel@tonic-gate 
19487c478bd9Sstevel@tonic-gate 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
19497c478bd9Sstevel@tonic-gate 				vap->va_rdev = makedevice(rawdev.specdata1,
19500a701b1eSRobert Gordon 				    rawdev.specdata2);
19517c478bd9Sstevel@tonic-gate 			} else {
19527c478bd9Sstevel@tonic-gate 				vap->va_rdev = 0;
19537c478bd9Sstevel@tonic-gate 			}
19547c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_RDEV;
19557c478bd9Sstevel@tonic-gate 		}
19567c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
19577c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bavail);
19587c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
19597c478bd9Sstevel@tonic-gate 		}
19607c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
19617c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bfree);
19627c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
19637c478bd9Sstevel@tonic-gate 		}
19647c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
19657c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_blocks);
19667c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
19677c478bd9Sstevel@tonic-gate 		}
19687c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_USED_MASK) {
19697c478bd9Sstevel@tonic-gate 			uint64_t space_used;
19707c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, space_used);
19717c478bd9Sstevel@tonic-gate 
19727c478bd9Sstevel@tonic-gate 			/* Compute space depending on device type */
19737c478bd9Sstevel@tonic-gate 			ASSERT((vap->va_mask & AT_TYPE));
19747c478bd9Sstevel@tonic-gate 			if (vap->va_type == VREG || vap->va_type == VDIR ||
19757c478bd9Sstevel@tonic-gate 			    vap->va_type == VLNK) {
19767c478bd9Sstevel@tonic-gate 				vap->va_nblocks = (u_longlong_t)
19770a701b1eSRobert Gordon 				    ((space_used + (offset4)DEV_BSIZE -
19780a701b1eSRobert Gordon 				    (offset4)1) / (offset4)DEV_BSIZE);
19797c478bd9Sstevel@tonic-gate 			} else {
19807c478bd9Sstevel@tonic-gate 				vap->va_nblocks = 0;
19817c478bd9Sstevel@tonic-gate 			}
19827c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NBLOCKS;
19837c478bd9Sstevel@tonic-gate 		}
19847c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYSTEM_MASK) {
19857c478bd9Sstevel@tonic-gate 			ASSERT(0);
19867c478bd9Sstevel@tonic-gate 		}
19877c478bd9Sstevel@tonic-gate 	}
19887c478bd9Sstevel@tonic-gate 	if (resbmap &
19897c478bd9Sstevel@tonic-gate 	    (FATTR4_TIME_ACCESS_MASK |
19907c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_ACCESS_SET_MASK |
19917c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_BACKUP_MASK |
19927c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_CREATE_MASK |
19937c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_DELTA_MASK |
19947c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_METADATA_MASK |
19957c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_MASK |
19967c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_SET_MASK |
19977c478bd9Sstevel@tonic-gate 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
19987c478bd9Sstevel@tonic-gate 
19997c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
20007c478bd9Sstevel@tonic-gate 			nfstime4 atime;
20017c478bd9Sstevel@tonic-gate 			int error;
20027c478bd9Sstevel@tonic-gate 
20037c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, atime.seconds);
20047c478bd9Sstevel@tonic-gate 			atime.nseconds = IXDR_GET_U_INT32(ptr);
20057c478bd9Sstevel@tonic-gate 
20067c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&atime, &vap->va_atime);
20077c478bd9Sstevel@tonic-gate 			if (error) {
20087c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
20097c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
20107c478bd9Sstevel@tonic-gate 			}
20117c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_ATIME;
20127c478bd9Sstevel@tonic-gate 		}
20137c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
20147c478bd9Sstevel@tonic-gate 			ASSERT(0);
20157c478bd9Sstevel@tonic-gate 		}
20167c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
20177c478bd9Sstevel@tonic-gate 			ASSERT(0);
20187c478bd9Sstevel@tonic-gate 		}
20197c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
20207c478bd9Sstevel@tonic-gate 			ASSERT(0);
20217c478bd9Sstevel@tonic-gate 		}
20227c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
20237c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_delta.seconds);
20247c478bd9Sstevel@tonic-gate 			gesp->n4g_delta.nseconds = IXDR_GET_U_INT32(ptr);
20257c478bd9Sstevel@tonic-gate 		}
20267c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
20277c478bd9Sstevel@tonic-gate 			nfstime4 mdt;
20287c478bd9Sstevel@tonic-gate 			int error;
20297c478bd9Sstevel@tonic-gate 
20307c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, mdt.seconds);
20317c478bd9Sstevel@tonic-gate 			mdt.nseconds = IXDR_GET_U_INT32(ptr);
20327c478bd9Sstevel@tonic-gate 
20337c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
20347c478bd9Sstevel@tonic-gate 			if (error) {
20357c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
20367c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
20377c478bd9Sstevel@tonic-gate 			}
20387c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_CTIME;
20397c478bd9Sstevel@tonic-gate 		}
20407c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
20417c478bd9Sstevel@tonic-gate 			nfstime4 mtime;
20427c478bd9Sstevel@tonic-gate 			int error;
20437c478bd9Sstevel@tonic-gate 
20447c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, mtime.seconds);
20457c478bd9Sstevel@tonic-gate 			mtime.nseconds = IXDR_GET_U_INT32(ptr);
20467c478bd9Sstevel@tonic-gate 
20477c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
20487c478bd9Sstevel@tonic-gate 			if (error) {
20497c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
20507c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
20517c478bd9Sstevel@tonic-gate 			}
20527c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MTIME;
20537c478bd9Sstevel@tonic-gate 		}
20547c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
20557c478bd9Sstevel@tonic-gate 			ASSERT(0);
20567c478bd9Sstevel@tonic-gate 		}
20577c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
20587c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_mon_fid);
20597c478bd9Sstevel@tonic-gate 			garp->n4g_mon_fid_valid = 1;
20607c478bd9Sstevel@tonic-gate 		}
20617c478bd9Sstevel@tonic-gate 	}
20627c478bd9Sstevel@tonic-gate 
20637c478bd9Sstevel@tonic-gate 	/*
20647c478bd9Sstevel@tonic-gate 	 * FATTR4_ACL_MASK is not yet supported by this function, but
20657c478bd9Sstevel@tonic-gate 	 * we check against it anyway, in case it ever is.
20667c478bd9Sstevel@tonic-gate 	 */
20677c478bd9Sstevel@tonic-gate 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
20687c478bd9Sstevel@tonic-gate 		/* copy only if not provided */
20697c478bd9Sstevel@tonic-gate 		if (garp->n4g_ext_res == NULL) {
20707c478bd9Sstevel@tonic-gate 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
20717c478bd9Sstevel@tonic-gate 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
20727c478bd9Sstevel@tonic-gate 		}
20737c478bd9Sstevel@tonic-gate 	}
20747c478bd9Sstevel@tonic-gate 
20757c478bd9Sstevel@tonic-gate 	return (TRUE);
20767c478bd9Sstevel@tonic-gate }
20777c478bd9Sstevel@tonic-gate 
20787c478bd9Sstevel@tonic-gate 
20797c478bd9Sstevel@tonic-gate /*
20807c478bd9Sstevel@tonic-gate  * "." and ".." buffers for filling in on read and readdir
20817c478bd9Sstevel@tonic-gate  * calls. Intialize the first time and fill in on every
20827c478bd9Sstevel@tonic-gate  * call to to readdir.
20837c478bd9Sstevel@tonic-gate  */
20847c478bd9Sstevel@tonic-gate char	*nfs4_dot_entries;
20857c478bd9Sstevel@tonic-gate char	*nfs4_dot_dot_entry;
20867c478bd9Sstevel@tonic-gate 
20877c478bd9Sstevel@tonic-gate /*
20887c478bd9Sstevel@tonic-gate  * Create the "." or ".." and pad the buffer once so they are
20897c478bd9Sstevel@tonic-gate  * copied out as required into the user supplied buffer everytime.
20907c478bd9Sstevel@tonic-gate  * DIRENT64_RECLEN(sizeof (".") - 1) = DIRENT64_RECLEN(1)
20917c478bd9Sstevel@tonic-gate  * DIRENT64_RECLEN(sizeof ("..") - 1) = DIRENT64_RECLEN(2)
20927c478bd9Sstevel@tonic-gate  */
20937c478bd9Sstevel@tonic-gate void
20947c478bd9Sstevel@tonic-gate nfs4_init_dot_entries()
20957c478bd9Sstevel@tonic-gate {
20967c478bd9Sstevel@tonic-gate 	struct dirent64 *odp;
20977c478bd9Sstevel@tonic-gate 
20987c478bd9Sstevel@tonic-gate 	/*
20997c478bd9Sstevel@tonic-gate 	 * zalloc it so it zeros the buffer out. Need
21007c478bd9Sstevel@tonic-gate 	 * to just do it once.
21017c478bd9Sstevel@tonic-gate 	 */
21027c478bd9Sstevel@tonic-gate 	nfs4_dot_entries = kmem_zalloc(DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2),
21037c478bd9Sstevel@tonic-gate 	    KM_SLEEP);
21047c478bd9Sstevel@tonic-gate 
21057c478bd9Sstevel@tonic-gate 	odp = (struct dirent64 *)nfs4_dot_entries;
21067c478bd9Sstevel@tonic-gate 	odp->d_off = 1; /* magic cookie for "." entry */
21077c478bd9Sstevel@tonic-gate 	odp->d_reclen = DIRENT64_RECLEN(1);
21087c478bd9Sstevel@tonic-gate 	odp->d_name[0] = '.';
21097c478bd9Sstevel@tonic-gate 	odp->d_name[1] = '\0';
21107c478bd9Sstevel@tonic-gate 
21117c478bd9Sstevel@tonic-gate 	nfs4_dot_dot_entry = nfs4_dot_entries + DIRENT64_RECLEN(1);
21127c478bd9Sstevel@tonic-gate 	odp = (struct dirent64 *)nfs4_dot_dot_entry;
21137c478bd9Sstevel@tonic-gate 
21147c478bd9Sstevel@tonic-gate 	odp->d_off = 2;
21157c478bd9Sstevel@tonic-gate 	odp->d_reclen = DIRENT64_RECLEN(2);
21167c478bd9Sstevel@tonic-gate 	odp->d_name[0] = '.';
21177c478bd9Sstevel@tonic-gate 	odp->d_name[1] = '.';
21187c478bd9Sstevel@tonic-gate 	odp->d_name[2] = '\0';
21197c478bd9Sstevel@tonic-gate }
21207c478bd9Sstevel@tonic-gate 
21217c478bd9Sstevel@tonic-gate void
21227c478bd9Sstevel@tonic-gate nfs4_destroy_dot_entries()
21237c478bd9Sstevel@tonic-gate {
21247c478bd9Sstevel@tonic-gate 	if (nfs4_dot_entries)
21257c478bd9Sstevel@tonic-gate 		kmem_free(nfs4_dot_entries, DIRENT64_RECLEN(1) +
21267c478bd9Sstevel@tonic-gate 		    DIRENT64_RECLEN(2));
21277c478bd9Sstevel@tonic-gate 
21287c478bd9Sstevel@tonic-gate 	nfs4_dot_entries = nfs4_dot_dot_entry = NULL;
21297c478bd9Sstevel@tonic-gate }
21307c478bd9Sstevel@tonic-gate 
21317c478bd9Sstevel@tonic-gate bool_t
21327c478bd9Sstevel@tonic-gate xdr_READDIR4res_clnt(XDR *xdrs, READDIR4res_clnt *objp, READDIR4args *aobjp)
21337c478bd9Sstevel@tonic-gate {
21347c478bd9Sstevel@tonic-gate 	bool_t more_data;
21357c478bd9Sstevel@tonic-gate 	rddir4_cache *rdc = aobjp->rdc;
21367c478bd9Sstevel@tonic-gate 	dirent64_t *dp = NULL;
21377c478bd9Sstevel@tonic-gate 	int entry_length = 0;
21387c478bd9Sstevel@tonic-gate 	int space_left = 0;
21397c478bd9Sstevel@tonic-gate 	bitmap4 resbmap;
21407c478bd9Sstevel@tonic-gate 	uint32_t attrlen;
21417c478bd9Sstevel@tonic-gate 	nfs4_ga_res_t gar;
21427c478bd9Sstevel@tonic-gate 	struct nfs4_ga_ext_res ges;
21437c478bd9Sstevel@tonic-gate 	uint64_t last_cookie = 0;
21447c478bd9Sstevel@tonic-gate 	int skip_to_end;
21457c478bd9Sstevel@tonic-gate 	ug_cache_t *pug = NULL;
21467c478bd9Sstevel@tonic-gate 
21477c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
21487c478bd9Sstevel@tonic-gate 	ASSERT(rdc->entries == NULL);
21497c478bd9Sstevel@tonic-gate 	ASSERT(aobjp->dircount > 0);
21507c478bd9Sstevel@tonic-gate 
21517c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
21527c478bd9Sstevel@tonic-gate 		return (FALSE);
21537c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
21547c478bd9Sstevel@tonic-gate 		return (TRUE);
21557c478bd9Sstevel@tonic-gate 
21567c478bd9Sstevel@tonic-gate 	gar.n4g_va.va_mask = 0;
21577c478bd9Sstevel@tonic-gate 	gar.n4g_change_valid = 0;
21587c478bd9Sstevel@tonic-gate 	gar.n4g_mon_fid_valid = 0;
21597c478bd9Sstevel@tonic-gate 	gar.n4g_fsid_valid = 0;
21607c478bd9Sstevel@tonic-gate 	gar.n4g_vsa.vsa_mask = 0;
21617c478bd9Sstevel@tonic-gate 	gar.n4g_attrwhy = NFS4_GETATTR_OP_OK;
21627c478bd9Sstevel@tonic-gate 	ges.n4g_pc4.pc4_cache_valid = 0;
21637c478bd9Sstevel@tonic-gate 	ges.n4g_pc4.pc4_xattr_valid = 0;
21647c478bd9Sstevel@tonic-gate 	gar.n4g_ext_res = &ges;
21657c478bd9Sstevel@tonic-gate 
21667c478bd9Sstevel@tonic-gate 	/* READDIR4res_clnt_free needs to kmem_free this buffer */
21677c478bd9Sstevel@tonic-gate 	rdc->entries = kmem_alloc(aobjp->dircount, KM_SLEEP);
21687c478bd9Sstevel@tonic-gate 
21697c478bd9Sstevel@tonic-gate 	dp = (dirent64_t *)rdc->entries;
21707c478bd9Sstevel@tonic-gate 	rdc->entlen = rdc->buflen = space_left = aobjp->dircount;
21717c478bd9Sstevel@tonic-gate 
21727c478bd9Sstevel@tonic-gate 	/* Fill in dot and dot-dot if needed */
21737c478bd9Sstevel@tonic-gate 	if (rdc->nfs4_cookie == (nfs_cookie4) 0 ||
21740a701b1eSRobert Gordon 	    rdc->nfs4_cookie == (nfs_cookie4) 1) {
21757c478bd9Sstevel@tonic-gate 
21767c478bd9Sstevel@tonic-gate 		if (rdc->nfs4_cookie == (nfs_cookie4)0) {
21777c478bd9Sstevel@tonic-gate 			bcopy(nfs4_dot_entries, rdc->entries,
21780a701b1eSRobert Gordon 			    DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2));
21797c478bd9Sstevel@tonic-gate 			objp->dotp = dp;
21807c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((char *)dp) +
21810a701b1eSRobert Gordon 			    DIRENT64_RECLEN(1));
21827c478bd9Sstevel@tonic-gate 			objp->dotdotp = dp;
21837c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((char *)dp) +
21840a701b1eSRobert Gordon 			    DIRENT64_RECLEN(2));
21857c478bd9Sstevel@tonic-gate 			space_left -= DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2);
21867c478bd9Sstevel@tonic-gate 
21877c478bd9Sstevel@tonic-gate 		} else	{	/* for ".." entry */
21887c478bd9Sstevel@tonic-gate 			bcopy(nfs4_dot_dot_entry, rdc->entries,
21890a701b1eSRobert Gordon 			    DIRENT64_RECLEN(2));
21907c478bd9Sstevel@tonic-gate 			objp->dotp = NULL;
21917c478bd9Sstevel@tonic-gate 			objp->dotdotp = dp;
21927c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((char *)dp) +
21930a701b1eSRobert Gordon 			    DIRENT64_RECLEN(2));
21947c478bd9Sstevel@tonic-gate 			space_left -= DIRENT64_RECLEN(2);
21957c478bd9Sstevel@tonic-gate 		}
21967c478bd9Sstevel@tonic-gate 		/* Magic NFSv4 number for entry after start */
21977c478bd9Sstevel@tonic-gate 		last_cookie = 2;
21987c478bd9Sstevel@tonic-gate 	}
21997c478bd9Sstevel@tonic-gate 
22007c478bd9Sstevel@tonic-gate 	/* Get the cookie VERIFIER */
22017c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
22027c478bd9Sstevel@tonic-gate 		goto noentries;
22037c478bd9Sstevel@tonic-gate 
22047c478bd9Sstevel@tonic-gate 	/* Get the do-we-have-a-next-entry BOOL */
22057c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &more_data))
22067c478bd9Sstevel@tonic-gate 		goto noentries;
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate 	if (aobjp->attr_request & (FATTR4_OWNER_MASK | FATTR4_OWNER_GROUP_MASK))
22097c478bd9Sstevel@tonic-gate 		pug = alloc_ugcache();
22107c478bd9Sstevel@tonic-gate 
22117c478bd9Sstevel@tonic-gate 	skip_to_end = 0;
22127c478bd9Sstevel@tonic-gate 	while (more_data) {
22137c478bd9Sstevel@tonic-gate 		uint_t namelen;
22147c478bd9Sstevel@tonic-gate 		uint64_t cookie;
22157c478bd9Sstevel@tonic-gate 
22167c478bd9Sstevel@tonic-gate 		/* Get the COOKIE */
22177c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&cookie))
22187c478bd9Sstevel@tonic-gate 			goto noentries;
22197c478bd9Sstevel@tonic-gate 
22207c478bd9Sstevel@tonic-gate 		/* Get the LENGTH of the entry name */
22217c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &namelen))
22227c478bd9Sstevel@tonic-gate 			goto noentries;
22237c478bd9Sstevel@tonic-gate 
22247c478bd9Sstevel@tonic-gate 		if (!skip_to_end) {
22257c478bd9Sstevel@tonic-gate 			/*
22267c478bd9Sstevel@tonic-gate 			 * With the length of the directory entry name
22277c478bd9Sstevel@tonic-gate 			 * in hand, figure out if there is room left
22287c478bd9Sstevel@tonic-gate 			 * to encode it for the requestor.  If not,
22297c478bd9Sstevel@tonic-gate 			 * that is okay, but the rest of the readdir
22307c478bd9Sstevel@tonic-gate 			 * operation result must be decoded in the
22317c478bd9Sstevel@tonic-gate 			 * case there are following operations
22327c478bd9Sstevel@tonic-gate 			 * in the compound request.  Therefore, mark
22337c478bd9Sstevel@tonic-gate 			 * the rest of the response as "skip" and
22347c478bd9Sstevel@tonic-gate 			 * decode or skip the remaining data
22357c478bd9Sstevel@tonic-gate 			 */
22367c478bd9Sstevel@tonic-gate 			entry_length = DIRENT64_RECLEN(namelen);
22377c478bd9Sstevel@tonic-gate 			if (space_left < entry_length)
22387c478bd9Sstevel@tonic-gate 				skip_to_end = 1;
22397c478bd9Sstevel@tonic-gate 		}
22407c478bd9Sstevel@tonic-gate 
22417c478bd9Sstevel@tonic-gate 		/* Get the NAME of the entry */
22427c478bd9Sstevel@tonic-gate 		if (!skip_to_end) {
22437c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, dp->d_name, namelen))
22447c478bd9Sstevel@tonic-gate 				goto noentries;
22457c478bd9Sstevel@tonic-gate 			bzero(&dp->d_name[namelen],
22460a701b1eSRobert Gordon 			    DIRENT64_NAMELEN(entry_length) - namelen);
22477c478bd9Sstevel@tonic-gate 			dp->d_off = last_cookie = cookie;
22487c478bd9Sstevel@tonic-gate 			dp->d_reclen = entry_length;
22497c478bd9Sstevel@tonic-gate 		} else {
22507c478bd9Sstevel@tonic-gate 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &namelen))
22517c478bd9Sstevel@tonic-gate 				goto noentries;
22527c478bd9Sstevel@tonic-gate 		}
22537c478bd9Sstevel@tonic-gate 
22547c478bd9Sstevel@tonic-gate 		/* Get the attribute BITMAP */
22557c478bd9Sstevel@tonic-gate 		if (!xdr_bitmap4(xdrs, &resbmap))
22567c478bd9Sstevel@tonic-gate 			goto noentries;
22577c478bd9Sstevel@tonic-gate 		/* Get the LENGTH of the attributes */
22587c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, (uint_t *)&attrlen))
22597c478bd9Sstevel@tonic-gate 			goto noentries;
22607c478bd9Sstevel@tonic-gate 
22617c478bd9Sstevel@tonic-gate 		/* Get the ATTRIBUTES */
22627c478bd9Sstevel@tonic-gate 		if (!skip_to_end) {
22637c478bd9Sstevel@tonic-gate 			uint32_t *ptr;
22647c478bd9Sstevel@tonic-gate 
22657c478bd9Sstevel@tonic-gate 			if (!(resbmap & FATTR4_ACL_MASK) &&
22667c478bd9Sstevel@tonic-gate 			    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen))
22677c478bd9Sstevel@tonic-gate 			    != NULL) {
22687c478bd9Sstevel@tonic-gate 				if (!xdr_ga_fattr_res_inline(ptr, &gar, resbmap,
22690a701b1eSRobert Gordon 				    aobjp->attr_request, aobjp->mi, pug))
22707c478bd9Sstevel@tonic-gate 					goto noentries;
22717c478bd9Sstevel@tonic-gate 			} else {
22727c478bd9Sstevel@tonic-gate 				if (!xdr_ga_fattr_res(xdrs, &gar, resbmap,
22730a701b1eSRobert Gordon 				    aobjp->attr_request, aobjp->mi, pug))
22747c478bd9Sstevel@tonic-gate 					goto noentries;
22757c478bd9Sstevel@tonic-gate 			}
22767c478bd9Sstevel@tonic-gate 
22777c478bd9Sstevel@tonic-gate 			/* Fill in the d_ino per the server's fid values */
22787c478bd9Sstevel@tonic-gate 			/*
22797c478bd9Sstevel@tonic-gate 			 * Important to note that the mounted on fileid
22807c478bd9Sstevel@tonic-gate 			 * is returned in d_ino if supported.  This is
22817c478bd9Sstevel@tonic-gate 			 * expected, readdir returns the mounted on fileid
22827c478bd9Sstevel@tonic-gate 			 * while stat() returns the fileid of the object
22837c478bd9Sstevel@tonic-gate 			 * on "top" of the mount.
22847c478bd9Sstevel@tonic-gate 			 */
22857c478bd9Sstevel@tonic-gate 			if (gar.n4g_mon_fid_valid)
22867c478bd9Sstevel@tonic-gate 				dp->d_ino = gar.n4g_mon_fid;
22877c478bd9Sstevel@tonic-gate 			else if (gar.n4g_va.va_mask & AT_NODEID)
22887c478bd9Sstevel@tonic-gate 				dp->d_ino = gar.n4g_va.va_nodeid;
22897c478bd9Sstevel@tonic-gate 			else
22907c478bd9Sstevel@tonic-gate 				dp->d_ino = 0;
22917c478bd9Sstevel@tonic-gate 
22927c478bd9Sstevel@tonic-gate 			/* See about creating an rnode for this entry */
22937c478bd9Sstevel@tonic-gate 			if ((resbmap &
22947c478bd9Sstevel@tonic-gate 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) ==
22957c478bd9Sstevel@tonic-gate 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) {
22967c478bd9Sstevel@tonic-gate 				nfs4_sharedfh_t *sfhp;
22977c478bd9Sstevel@tonic-gate 				vnode_t *vp;
22987c478bd9Sstevel@tonic-gate 
22997c478bd9Sstevel@tonic-gate 				sfhp = sfh4_put(&ges.n4g_fh_u.n4g_fh,
23000a701b1eSRobert Gordon 				    aobjp->mi, NULL);
23017c478bd9Sstevel@tonic-gate 				vp = makenfs4node(sfhp, &gar,
23020a701b1eSRobert Gordon 				    aobjp->dvp->v_vfsp,
23030a701b1eSRobert Gordon 				    aobjp->t,
23040a701b1eSRobert Gordon 				    aobjp->cr,
23050a701b1eSRobert Gordon 				    aobjp->dvp,
23060a701b1eSRobert Gordon 				    fn_get(VTOSV(aobjp->dvp)->sv_name,
2307bbf2a467SNagakiran Rajashekar 				    dp->d_name, sfhp));
23087c478bd9Sstevel@tonic-gate 				sfh4_rele(&sfhp);
23097c478bd9Sstevel@tonic-gate 				dnlc_update(aobjp->dvp, dp->d_name, vp);
23107c478bd9Sstevel@tonic-gate 				VN_RELE(vp);
23117c478bd9Sstevel@tonic-gate 			}
23127c478bd9Sstevel@tonic-gate 
23137c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((caddr_t)dp) + dp->d_reclen);
23147c478bd9Sstevel@tonic-gate 
23157c478bd9Sstevel@tonic-gate 			space_left -= entry_length;
23167c478bd9Sstevel@tonic-gate 
23177c478bd9Sstevel@tonic-gate 		} else {
23187c478bd9Sstevel@tonic-gate 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &attrlen))
23197c478bd9Sstevel@tonic-gate 				goto noentries;
23207c478bd9Sstevel@tonic-gate 		}
23217c478bd9Sstevel@tonic-gate 
23227c478bd9Sstevel@tonic-gate 		/* Get the do-we-have-a-next-entry BOOL */
23237c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &more_data))
23247c478bd9Sstevel@tonic-gate 			goto noentries;
23257c478bd9Sstevel@tonic-gate 	}
23267c478bd9Sstevel@tonic-gate 
23277c478bd9Sstevel@tonic-gate 	if (pug) {
23287c478bd9Sstevel@tonic-gate 		kmem_free(pug, sizeof (ug_cache_t));
23297c478bd9Sstevel@tonic-gate 		pug = NULL;
23307c478bd9Sstevel@tonic-gate 	}
23317c478bd9Sstevel@tonic-gate 
23327c478bd9Sstevel@tonic-gate 	/*
23337c478bd9Sstevel@tonic-gate 	 * Finish up the rddir cache
23347c478bd9Sstevel@tonic-gate 	 * If no entries were returned, free up buffer &
23357c478bd9Sstevel@tonic-gate 	 * set ncookie to the starting cookie for this
23367c478bd9Sstevel@tonic-gate 	 * readdir request so that the direof caching
23377c478bd9Sstevel@tonic-gate 	 * will work properly.
23387c478bd9Sstevel@tonic-gate 	 */
23397c478bd9Sstevel@tonic-gate 	ASSERT(rdc->entries);
23407c478bd9Sstevel@tonic-gate 	if (last_cookie == 0) {
23417c478bd9Sstevel@tonic-gate 		kmem_free(rdc->entries, rdc->entlen);
23427c478bd9Sstevel@tonic-gate 		rdc->entries = NULL;
23437c478bd9Sstevel@tonic-gate 		last_cookie = rdc->nfs4_cookie;
23447c478bd9Sstevel@tonic-gate 	}
23457c478bd9Sstevel@tonic-gate 
23467c478bd9Sstevel@tonic-gate 	rdc->actlen = rdc->entlen - space_left;
23477c478bd9Sstevel@tonic-gate 	rdc->nfs4_ncookie = last_cookie;
23487c478bd9Sstevel@tonic-gate 
23497c478bd9Sstevel@tonic-gate 	/* Get the EOF marker */
23507c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->eof))
23517c478bd9Sstevel@tonic-gate 		goto noentries;
23527c478bd9Sstevel@tonic-gate 
23537c478bd9Sstevel@tonic-gate 	/*
23547c478bd9Sstevel@tonic-gate 	 * If the server returns eof and there were no
23557c478bd9Sstevel@tonic-gate 	 * skipped entries, set eof
23567c478bd9Sstevel@tonic-gate 	 */
23577c478bd9Sstevel@tonic-gate 	rdc->eof = (objp->eof && !skip_to_end) ? TRUE : FALSE;
23587c478bd9Sstevel@tonic-gate 
23597c478bd9Sstevel@tonic-gate 	/*
23607c478bd9Sstevel@tonic-gate 	 * If we encoded entries we are done
23617c478bd9Sstevel@tonic-gate 	 */
23627c478bd9Sstevel@tonic-gate 	if (rdc->entries) {
23637c478bd9Sstevel@tonic-gate 		rdc->error = 0;
23647c478bd9Sstevel@tonic-gate 		return (TRUE);
23657c478bd9Sstevel@tonic-gate 	}
23667c478bd9Sstevel@tonic-gate 
23677c478bd9Sstevel@tonic-gate 	/*
23687c478bd9Sstevel@tonic-gate 	 * If there were no entries and we skipped because
23697c478bd9Sstevel@tonic-gate 	 * there was not enough space, return EINVAL
23707c478bd9Sstevel@tonic-gate 	 */
23717c478bd9Sstevel@tonic-gate 	if (skip_to_end) {
23727c478bd9Sstevel@tonic-gate 		rdc->error = EINVAL;
23737c478bd9Sstevel@tonic-gate 		return (TRUE);
23747c478bd9Sstevel@tonic-gate 	}
23757c478bd9Sstevel@tonic-gate 
23767c478bd9Sstevel@tonic-gate 	/*
23777c478bd9Sstevel@tonic-gate 	 * No entries, nothing skipped, and EOF, return OK.
23787c478bd9Sstevel@tonic-gate 	 */
23797c478bd9Sstevel@tonic-gate 	if (objp->eof == TRUE) {
23807c478bd9Sstevel@tonic-gate 		rdc->error = 0;
23817c478bd9Sstevel@tonic-gate 		return (TRUE);
23827c478bd9Sstevel@tonic-gate 	}
23837c478bd9Sstevel@tonic-gate 
23847c478bd9Sstevel@tonic-gate 	/*
23857c478bd9Sstevel@tonic-gate 	 * No entries, nothing skipped, and not EOF
23867c478bd9Sstevel@tonic-gate 	 * probably a bad cookie, return ENOENT.
23877c478bd9Sstevel@tonic-gate 	 */
23887c478bd9Sstevel@tonic-gate 	rdc->error = ENOENT;
23897c478bd9Sstevel@tonic-gate 	return (TRUE);
23907c478bd9Sstevel@tonic-gate 
23917c478bd9Sstevel@tonic-gate noentries:
23927c478bd9Sstevel@tonic-gate 	if (rdc->entries) {
23937c478bd9Sstevel@tonic-gate 		kmem_free(rdc->entries, rdc->entlen);
23947c478bd9Sstevel@tonic-gate 		rdc->entries = NULL;
23957c478bd9Sstevel@tonic-gate 	}
23967c478bd9Sstevel@tonic-gate 	if (pug)
23977c478bd9Sstevel@tonic-gate 		kmem_free(pug, sizeof (ug_cache_t));
23987c478bd9Sstevel@tonic-gate 	rdc->error = EIO;
23997c478bd9Sstevel@tonic-gate 	return (FALSE);
24007c478bd9Sstevel@tonic-gate }
24017c478bd9Sstevel@tonic-gate 
24027c478bd9Sstevel@tonic-gate /*
24037c478bd9Sstevel@tonic-gate  * xdr_ga_res
24047c478bd9Sstevel@tonic-gate  *
24057c478bd9Sstevel@tonic-gate  * Returns: FALSE on raw data processing errors, TRUE otherwise.
24067c478bd9Sstevel@tonic-gate  *
24077c478bd9Sstevel@tonic-gate  * This function pre-processes the OP_GETATTR response, and then
24087c478bd9Sstevel@tonic-gate  * calls common routines to process the GETATTR fattr4 results into
24097c478bd9Sstevel@tonic-gate  * vnode attributes and other components that the client is interested
24107c478bd9Sstevel@tonic-gate  * in. If an error other than an RPC error is encountered, the details
24117c478bd9Sstevel@tonic-gate  * of the error are filled into objp, although the result of the
24127c478bd9Sstevel@tonic-gate  * processing is set to TRUE.
24137c478bd9Sstevel@tonic-gate  */
24147c478bd9Sstevel@tonic-gate static bool_t
24157c478bd9Sstevel@tonic-gate xdr_ga_res(XDR *xdrs, GETATTR4res *objp, GETATTR4args *aobjp)
24167c478bd9Sstevel@tonic-gate {
24172f172c55SRobert Thurlow #ifdef INLINE
24187c478bd9Sstevel@tonic-gate 	uint32_t *ptr;
24192f172c55SRobert Thurlow #endif
24207c478bd9Sstevel@tonic-gate 	bitmap4 resbmap;
24217c478bd9Sstevel@tonic-gate 	uint32_t attrlen;
24227c478bd9Sstevel@tonic-gate 
24237c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
24247c478bd9Sstevel@tonic-gate 
24257c478bd9Sstevel@tonic-gate 	/* Initialize objp attribute error values */
24267c478bd9Sstevel@tonic-gate 	objp->ga_res.n4g_attrerr =
24270a701b1eSRobert Gordon 	    objp->ga_res.n4g_attrwhy = NFS4_GETATTR_OP_OK;
24287c478bd9Sstevel@tonic-gate 
24297c478bd9Sstevel@tonic-gate 	if (!xdr_bitmap4(xdrs, &resbmap))
24307c478bd9Sstevel@tonic-gate 		return (FALSE);
24317c478bd9Sstevel@tonic-gate 
24327c478bd9Sstevel@tonic-gate 	/* save the response bitmap for the caller */
24337c478bd9Sstevel@tonic-gate 	objp->ga_res.n4g_resbmap = resbmap;
24347c478bd9Sstevel@tonic-gate 
24357c478bd9Sstevel@tonic-gate 	/* attrlen */
24367c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&attrlen))
24377c478bd9Sstevel@tonic-gate 		return (FALSE);
24387c478bd9Sstevel@tonic-gate 
24397c478bd9Sstevel@tonic-gate 	/*
24407c478bd9Sstevel@tonic-gate 	 * Handle case where request and response bitmaps don't match.
24417c478bd9Sstevel@tonic-gate 	 */
24427c478bd9Sstevel@tonic-gate 	if (aobjp->attr_request && aobjp->attr_request != resbmap) {
24437c478bd9Sstevel@tonic-gate 		bitmap4 deltabmap;
24447c478bd9Sstevel@tonic-gate 
24457c478bd9Sstevel@tonic-gate 		/*
24467c478bd9Sstevel@tonic-gate 		 * Return error for case where server sent extra attributes
24477c478bd9Sstevel@tonic-gate 		 * because the "unknown" attributes may be anywhere in the
24487c478bd9Sstevel@tonic-gate 		 * xdr stream and can't be properly processed.
24497c478bd9Sstevel@tonic-gate 		 */
24507c478bd9Sstevel@tonic-gate 		deltabmap = ((aobjp->attr_request ^ resbmap) & resbmap);
24517c478bd9Sstevel@tonic-gate 		if (deltabmap) {
24527c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrerr = EINVAL;
24537c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_BITMAP_ERR;
24547c478bd9Sstevel@tonic-gate 			return (TRUE);
24557c478bd9Sstevel@tonic-gate 		}
24567c478bd9Sstevel@tonic-gate 
24577c478bd9Sstevel@tonic-gate 		/*
24587c478bd9Sstevel@tonic-gate 		 * Return error for case where there is a mandatory
24597c478bd9Sstevel@tonic-gate 		 * attribute missing in the server response. Note that
24607c478bd9Sstevel@tonic-gate 		 * missing recommended attributes are evaluated in the
24617c478bd9Sstevel@tonic-gate 		 * specific routines that decode the server response.
24627c478bd9Sstevel@tonic-gate 		 */
24637c478bd9Sstevel@tonic-gate 		deltabmap = ((aobjp->attr_request ^ resbmap)
24640a701b1eSRobert Gordon 		    & aobjp->attr_request);
24657c478bd9Sstevel@tonic-gate 		if ((deltabmap & FATTR4_MANDATTR_MASK)) {
24667c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrerr = EINVAL;
24677c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_MANDATTR_ERR;
24687c478bd9Sstevel@tonic-gate 			return (TRUE);
24697c478bd9Sstevel@tonic-gate 		}
24707c478bd9Sstevel@tonic-gate 	}
24717c478bd9Sstevel@tonic-gate 
24727c478bd9Sstevel@tonic-gate 	/* Check to see if the attrs can be inlined and go for it if so */
24732f172c55SRobert Thurlow #ifdef INLINE
24747c478bd9Sstevel@tonic-gate 	if (!(resbmap & FATTR4_ACL_MASK) &&
24757c478bd9Sstevel@tonic-gate 	    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen)) != NULL)
24767c478bd9Sstevel@tonic-gate 		return (xdr_ga_fattr_res_inline(ptr, &objp->ga_res,
24770a701b1eSRobert Gordon 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
24787c478bd9Sstevel@tonic-gate 	else
24792f172c55SRobert Thurlow #endif
24807c478bd9Sstevel@tonic-gate 		return (xdr_ga_fattr_res(xdrs, &objp->ga_res,
24810a701b1eSRobert Gordon 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
24827c478bd9Sstevel@tonic-gate }
24837c478bd9Sstevel@tonic-gate 
24847c478bd9Sstevel@tonic-gate #if defined(DEBUG) && !defined(lint)
24857c478bd9Sstevel@tonic-gate /*
24867c478bd9Sstevel@tonic-gate  * We assume that an enum is a 32-bit value, check it once
24877c478bd9Sstevel@tonic-gate  */
24887c478bd9Sstevel@tonic-gate static enum szchk { SZVAL } szchkvar;
24897c478bd9Sstevel@tonic-gate #endif
24907c478bd9Sstevel@tonic-gate 
24917c478bd9Sstevel@tonic-gate bool_t
24927c478bd9Sstevel@tonic-gate xdr_settime4(XDR *xdrs, settime4 *objp)
24937c478bd9Sstevel@tonic-gate {
24947c478bd9Sstevel@tonic-gate #if defined(DEBUG) && !defined(lint)
24957c478bd9Sstevel@tonic-gate 	ASSERT(sizeof (szchkvar) == sizeof (int32_t));
24967c478bd9Sstevel@tonic-gate #endif
24977c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
24987c478bd9Sstevel@tonic-gate 		return (TRUE);
24997c478bd9Sstevel@tonic-gate 
25007c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->set_it))
25017c478bd9Sstevel@tonic-gate 		return (FALSE);
25027c478bd9Sstevel@tonic-gate 	if (objp->set_it != SET_TO_CLIENT_TIME4)
25037c478bd9Sstevel@tonic-gate 		return (TRUE);
25047c478bd9Sstevel@tonic-gate 	/* xdr_nfstime4 */
25057c478bd9Sstevel@tonic-gate 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->time.seconds))
25067c478bd9Sstevel@tonic-gate 		return (FALSE);
25077c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->time.nseconds));
25087c478bd9Sstevel@tonic-gate }
25097c478bd9Sstevel@tonic-gate 
25107c478bd9Sstevel@tonic-gate static bool_t
25117c478bd9Sstevel@tonic-gate xdr_fattr4(XDR *xdrs, fattr4 *objp)
25127c478bd9Sstevel@tonic-gate {
25137c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
25147c478bd9Sstevel@tonic-gate 		if (!xdr_bitmap4(xdrs, &objp->attrmask))
25157c478bd9Sstevel@tonic-gate 			return (FALSE);
25167c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->attrlist4,
25170a701b1eSRobert Gordon 		    (uint_t *)&objp->attrlist4_len, NFS4_FATTR4_LIMIT));
25187c478bd9Sstevel@tonic-gate 	}
25197c478bd9Sstevel@tonic-gate 
25207c478bd9Sstevel@tonic-gate 	/*
25217c478bd9Sstevel@tonic-gate 	 * Optimized free case
25227c478bd9Sstevel@tonic-gate 	 */
25237c478bd9Sstevel@tonic-gate 	if (objp->attrlist4 != NULL)
25247c478bd9Sstevel@tonic-gate 		kmem_free(objp->attrlist4, objp->attrlist4_len);
25257c478bd9Sstevel@tonic-gate 	return (TRUE);
25267c478bd9Sstevel@tonic-gate }
25277c478bd9Sstevel@tonic-gate 
25287c478bd9Sstevel@tonic-gate static bool_t
25297c478bd9Sstevel@tonic-gate xdr_ACCESS4res(XDR *xdrs, ACCESS4res *objp)
25307c478bd9Sstevel@tonic-gate {
25317c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
25327c478bd9Sstevel@tonic-gate 		return (FALSE);
25337c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
25347c478bd9Sstevel@tonic-gate 		return (TRUE);
25357c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->supported))
25367c478bd9Sstevel@tonic-gate 		return (FALSE);
25377c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->access));
25387c478bd9Sstevel@tonic-gate }
25397c478bd9Sstevel@tonic-gate 
25407c478bd9Sstevel@tonic-gate static bool_t
25417c478bd9Sstevel@tonic-gate xdr_CLOSE4args(XDR *xdrs, CLOSE4args *objp)
25427c478bd9Sstevel@tonic-gate {
25437c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->seqid))
25447c478bd9Sstevel@tonic-gate 		return (FALSE);
25457c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
25467c478bd9Sstevel@tonic-gate 		return (FALSE);
25477c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
25487c478bd9Sstevel@tonic-gate }
25497c478bd9Sstevel@tonic-gate 
25507c478bd9Sstevel@tonic-gate static bool_t
25517c478bd9Sstevel@tonic-gate xdr_CLOSE4res(XDR *xdrs, CLOSE4res *objp)
25527c478bd9Sstevel@tonic-gate {
25537c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
25547c478bd9Sstevel@tonic-gate 		return (FALSE);
25557c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
25567c478bd9Sstevel@tonic-gate 		return (TRUE);
25577c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
25587c478bd9Sstevel@tonic-gate 		return (FALSE);
25597c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
25607c478bd9Sstevel@tonic-gate }
25617c478bd9Sstevel@tonic-gate 
25627c478bd9Sstevel@tonic-gate static bool_t
25637c478bd9Sstevel@tonic-gate xdr_CREATE4args(XDR *xdrs, CREATE4args *objp)
25647c478bd9Sstevel@tonic-gate {
25657c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
25667c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->type))
25677c478bd9Sstevel@tonic-gate 			return (FALSE);
25687c478bd9Sstevel@tonic-gate 		switch (objp->type) {
25697c478bd9Sstevel@tonic-gate 		case NF4LNK:
25707c478bd9Sstevel@tonic-gate 			if (!xdr_bytes(xdrs,
25717c478bd9Sstevel@tonic-gate 			    (char **)&objp->ftype4_u.linkdata.utf8string_val,
25727c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->ftype4_u.linkdata.utf8string_len,
25737c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING))
25747c478bd9Sstevel@tonic-gate 				return (FALSE);
25757c478bd9Sstevel@tonic-gate 			break;
25767c478bd9Sstevel@tonic-gate 		case NF4BLK:
25777c478bd9Sstevel@tonic-gate 		case NF4CHR:
25787c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata1))
25797c478bd9Sstevel@tonic-gate 				return (FALSE);
25807c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata2))
25817c478bd9Sstevel@tonic-gate 				return (FALSE);
25827c478bd9Sstevel@tonic-gate 			break;
25837c478bd9Sstevel@tonic-gate 		case NF4SOCK:
25847c478bd9Sstevel@tonic-gate 		case NF4FIFO:
25857c478bd9Sstevel@tonic-gate 		case NF4DIR:
25867c478bd9Sstevel@tonic-gate 		default:
25877c478bd9Sstevel@tonic-gate 			break;	/* server should return NFS4ERR_BADTYPE */
25887c478bd9Sstevel@tonic-gate 		}
25897c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->objname.utf8string_val,
25900a701b1eSRobert Gordon 		    (uint_t *)&objp->objname.utf8string_len,
25910a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING))
25927c478bd9Sstevel@tonic-gate 			return (FALSE);
25937c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs, &objp->createattrs));
25947c478bd9Sstevel@tonic-gate 	}
25957c478bd9Sstevel@tonic-gate 
25967c478bd9Sstevel@tonic-gate 	/*
25977c478bd9Sstevel@tonic-gate 	 * Optimized free case
25987c478bd9Sstevel@tonic-gate 	 */
25997c478bd9Sstevel@tonic-gate 	if (objp->type == NF4LNK) {
26007c478bd9Sstevel@tonic-gate 		if (objp->ftype4_u.linkdata.utf8string_val != NULL)
26017c478bd9Sstevel@tonic-gate 			kmem_free(objp->ftype4_u.linkdata.utf8string_val,
26020a701b1eSRobert Gordon 			    objp->ftype4_u.linkdata.utf8string_len);
26037c478bd9Sstevel@tonic-gate 	}
26047c478bd9Sstevel@tonic-gate 	if (objp->objname.utf8string_val != NULL)
26057c478bd9Sstevel@tonic-gate 		kmem_free(objp->objname.utf8string_val,
26060a701b1eSRobert Gordon 		    objp->objname.utf8string_len);
26077c478bd9Sstevel@tonic-gate 	return (xdr_fattr4(xdrs, &objp->createattrs));
26087c478bd9Sstevel@tonic-gate }
26097c478bd9Sstevel@tonic-gate 
26107c478bd9Sstevel@tonic-gate static bool_t
26117c478bd9Sstevel@tonic-gate xdr_CREATE4cargs(XDR *xdrs, CREATE4cargs *objp)
26127c478bd9Sstevel@tonic-gate {
26137c478bd9Sstevel@tonic-gate 	int len;
26147c478bd9Sstevel@tonic-gate 
26157c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
26167c478bd9Sstevel@tonic-gate 
26177c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->type))
26187c478bd9Sstevel@tonic-gate 		return (FALSE);
26197c478bd9Sstevel@tonic-gate 	switch (objp->type) {
26207c478bd9Sstevel@tonic-gate 	case NF4LNK:
26217c478bd9Sstevel@tonic-gate 		len = strlen(objp->ftype4_u.clinkdata);
26227c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
26237c478bd9Sstevel@tonic-gate 			return (FALSE);
26247c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len))
26257c478bd9Sstevel@tonic-gate 			return (FALSE);
26267c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->ftype4_u.clinkdata, len))
26277c478bd9Sstevel@tonic-gate 			return (FALSE);
26287c478bd9Sstevel@tonic-gate 		break;
26297c478bd9Sstevel@tonic-gate 	case NF4BLK:
26307c478bd9Sstevel@tonic-gate 	case NF4CHR:
26317c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs,
26320a701b1eSRobert Gordon 		    (int32_t *)&objp->ftype4_u.devdata.specdata1))
26337c478bd9Sstevel@tonic-gate 			return (FALSE);
26347c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs,
26350a701b1eSRobert Gordon 		    (int32_t *)&objp->ftype4_u.devdata.specdata2))
26367c478bd9Sstevel@tonic-gate 			return (FALSE);
26377c478bd9Sstevel@tonic-gate 		break;
26387c478bd9Sstevel@tonic-gate 	case NF4SOCK:
26397c478bd9Sstevel@tonic-gate 	case NF4FIFO:
26407c478bd9Sstevel@tonic-gate 	case NF4DIR:
26417c478bd9Sstevel@tonic-gate 	default:
26427c478bd9Sstevel@tonic-gate 		break;	/* server should return NFS4ERR_BADTYPE */
26437c478bd9Sstevel@tonic-gate 	}
26447c478bd9Sstevel@tonic-gate 
26457c478bd9Sstevel@tonic-gate 	len = strlen(objp->cname);
26467c478bd9Sstevel@tonic-gate 	if (len > NFS4_MAX_UTF8STRING)
26477c478bd9Sstevel@tonic-gate 		return (FALSE);
26487c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, &len))
26497c478bd9Sstevel@tonic-gate 		return (FALSE);
26507c478bd9Sstevel@tonic-gate 	if (!xdr_opaque(xdrs, objp->cname, len))
26517c478bd9Sstevel@tonic-gate 		return (FALSE);
26527c478bd9Sstevel@tonic-gate 
26537c478bd9Sstevel@tonic-gate 	return (xdr_fattr4(xdrs, &objp->createattrs));
26547c478bd9Sstevel@tonic-gate }
26557c478bd9Sstevel@tonic-gate 
26567c478bd9Sstevel@tonic-gate static bool_t
26577c478bd9Sstevel@tonic-gate xdr_CREATE4res(XDR *xdrs, CREATE4res *objp)
26587c478bd9Sstevel@tonic-gate {
26597c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
26607c478bd9Sstevel@tonic-gate 		return (FALSE);
26617c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
26627c478bd9Sstevel@tonic-gate 		return (TRUE);
26637c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
26647c478bd9Sstevel@tonic-gate 		return (FALSE);
26657c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
26667c478bd9Sstevel@tonic-gate 		return (FALSE);
26677c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
26687c478bd9Sstevel@tonic-gate 		return (FALSE);
26697c478bd9Sstevel@tonic-gate 	return (xdr_bitmap4(xdrs, &objp->attrset));
26707c478bd9Sstevel@tonic-gate }
26717c478bd9Sstevel@tonic-gate 
26727c478bd9Sstevel@tonic-gate static bool_t
26737c478bd9Sstevel@tonic-gate xdr_LINK4res(XDR *xdrs, LINK4res *objp)
26747c478bd9Sstevel@tonic-gate {
26757c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
26767c478bd9Sstevel@tonic-gate 		return (FALSE);
26777c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
26787c478bd9Sstevel@tonic-gate 		return (TRUE);
26797c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
26807c478bd9Sstevel@tonic-gate 		return (FALSE);
26817c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
26827c478bd9Sstevel@tonic-gate 		return (FALSE);
26837c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after));
26847c478bd9Sstevel@tonic-gate }
26857c478bd9Sstevel@tonic-gate 
26867c478bd9Sstevel@tonic-gate static bool_t
26877c478bd9Sstevel@tonic-gate xdr_LOCK4args(XDR *xdrs, LOCK4args *objp)
26887c478bd9Sstevel@tonic-gate {
26897c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
26907c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->locktype))
26917c478bd9Sstevel@tonic-gate 			return (FALSE);
26927c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->reclaim))
26937c478bd9Sstevel@tonic-gate 			return (FALSE);
26947c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
26957c478bd9Sstevel@tonic-gate 			return (FALSE);
26967c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
26977c478bd9Sstevel@tonic-gate 			return (FALSE);
26987c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->locker.new_lock_owner))
26997c478bd9Sstevel@tonic-gate 			return (FALSE);
27007c478bd9Sstevel@tonic-gate 		if (objp->locker.new_lock_owner == TRUE) {
27017c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
27020a701b1eSRobert Gordon 			    open_seqid))
27037c478bd9Sstevel@tonic-gate 				return (FALSE);
27047c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
27050a701b1eSRobert Gordon 			    open_stateid.seqid))
27067c478bd9Sstevel@tonic-gate 				return (FALSE);
27077c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->locker.locker4_u.open_owner.
27080a701b1eSRobert Gordon 			    open_stateid.other, 12))
27097c478bd9Sstevel@tonic-gate 				return (FALSE);
27107c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
27110a701b1eSRobert Gordon 			    lock_seqid))
27127c478bd9Sstevel@tonic-gate 				return (FALSE);
27137c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
27140a701b1eSRobert Gordon 			    (u_longlong_t *)&objp->locker.locker4_u.
27150a701b1eSRobert Gordon 			    open_owner.lock_owner.clientid))
27167c478bd9Sstevel@tonic-gate 				return (FALSE);
27177c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs,
27180a701b1eSRobert Gordon 			    (char **)&objp->locker.locker4_u.open_owner.
27190a701b1eSRobert Gordon 			    lock_owner.owner_val,
27200a701b1eSRobert Gordon 			    (uint_t *)&objp->locker.locker4_u.open_owner.
27210a701b1eSRobert Gordon 			    lock_owner.owner_len,
27220a701b1eSRobert Gordon 			    NFS4_OPAQUE_LIMIT));
27237c478bd9Sstevel@tonic-gate 		}
27247c478bd9Sstevel@tonic-gate 
27257c478bd9Sstevel@tonic-gate 		if (objp->locker.new_lock_owner != FALSE)
27267c478bd9Sstevel@tonic-gate 			return (FALSE);
27277c478bd9Sstevel@tonic-gate 
27287c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
27290a701b1eSRobert Gordon 		    lock_stateid.seqid))
27307c478bd9Sstevel@tonic-gate 			return (FALSE);
27317c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->locker.locker4_u.lock_owner.
27320a701b1eSRobert Gordon 		    lock_stateid.other, 12))
27337c478bd9Sstevel@tonic-gate 			return (FALSE);
27347c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
27350a701b1eSRobert Gordon 		    lock_seqid));
27367c478bd9Sstevel@tonic-gate 	}
27377c478bd9Sstevel@tonic-gate 
27387c478bd9Sstevel@tonic-gate 	/*
27397c478bd9Sstevel@tonic-gate 	 * Optimized free case
27407c478bd9Sstevel@tonic-gate 	 */
27417c478bd9Sstevel@tonic-gate 	if (objp->locker.new_lock_owner == TRUE) {
27427c478bd9Sstevel@tonic-gate 		if (objp->locker.locker4_u.open_owner.lock_owner.owner_val !=
27430a701b1eSRobert Gordon 		    NULL) {
27447c478bd9Sstevel@tonic-gate 			kmem_free(objp->locker.locker4_u.open_owner.lock_owner.
27450a701b1eSRobert Gordon 			    owner_val,
27460a701b1eSRobert Gordon 			    objp->locker.locker4_u.open_owner.lock_owner.
27470a701b1eSRobert Gordon 			    owner_len);
27487c478bd9Sstevel@tonic-gate 		}
27497c478bd9Sstevel@tonic-gate 	}
27507c478bd9Sstevel@tonic-gate 
27517c478bd9Sstevel@tonic-gate 	return (TRUE);
27527c478bd9Sstevel@tonic-gate }
27537c478bd9Sstevel@tonic-gate 
27547c478bd9Sstevel@tonic-gate static bool_t
27557c478bd9Sstevel@tonic-gate xdr_LOCK4res(XDR *xdrs, LOCK4res *objp)
27567c478bd9Sstevel@tonic-gate {
27577c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
27587c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
27597c478bd9Sstevel@tonic-gate 			return (FALSE);
27607c478bd9Sstevel@tonic-gate 		if (objp->status == NFS4_OK) {
27617c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs,
27620a701b1eSRobert Gordon 			    &objp->LOCK4res_u.lock_stateid.seqid))
27637c478bd9Sstevel@tonic-gate 				return (FALSE);
27647c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
27650a701b1eSRobert Gordon 			    objp->LOCK4res_u.lock_stateid.other, 12));
27667c478bd9Sstevel@tonic-gate 		}
27677c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4ERR_DENIED)
27687c478bd9Sstevel@tonic-gate 			return (TRUE);
27697c478bd9Sstevel@tonic-gate 
27707c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
27710a701b1eSRobert Gordon 		    denied.offset))
27727c478bd9Sstevel@tonic-gate 			return (FALSE);
27737c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
27740a701b1eSRobert Gordon 		    denied.length))
27757c478bd9Sstevel@tonic-gate 			return (FALSE);
27767c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->LOCK4res_u.denied.locktype))
27777c478bd9Sstevel@tonic-gate 			return (FALSE);
27787c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
27790a701b1eSRobert Gordon 		    denied.owner.clientid))
27807c478bd9Sstevel@tonic-gate 			return (FALSE);
27817c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
27820a701b1eSRobert Gordon 		    (char **)&objp->LOCK4res_u.denied.owner.owner_val,
27830a701b1eSRobert Gordon 		    (uint_t *)&objp->LOCK4res_u.denied.owner.owner_len,
27840a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT));
27857c478bd9Sstevel@tonic-gate 	}
27867c478bd9Sstevel@tonic-gate 
27877c478bd9Sstevel@tonic-gate 	/*
27887c478bd9Sstevel@tonic-gate 	 * Optimized free case
27897c478bd9Sstevel@tonic-gate 	 */
27907c478bd9Sstevel@tonic-gate 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
27917c478bd9Sstevel@tonic-gate 		return (TRUE);
27927c478bd9Sstevel@tonic-gate 
27937c478bd9Sstevel@tonic-gate 	if (objp->LOCK4res_u.denied.owner.owner_val != NULL)
27947c478bd9Sstevel@tonic-gate 		kmem_free(objp->LOCK4res_u.denied.owner.owner_val,
27950a701b1eSRobert Gordon 		    objp->LOCK4res_u.denied.owner.owner_len);
27967c478bd9Sstevel@tonic-gate 	return (TRUE);
27977c478bd9Sstevel@tonic-gate }
27987c478bd9Sstevel@tonic-gate 
27997c478bd9Sstevel@tonic-gate static bool_t
28007c478bd9Sstevel@tonic-gate xdr_LOCKT4args(XDR *xdrs, LOCKT4args *objp)
28017c478bd9Sstevel@tonic-gate {
28027c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
28037c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->locktype))
28047c478bd9Sstevel@tonic-gate 			return (FALSE);
28057c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
28067c478bd9Sstevel@tonic-gate 			return (FALSE);
28077c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
28087c478bd9Sstevel@tonic-gate 			return (FALSE);
28097c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28100a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->owner.clientid))
28117c478bd9Sstevel@tonic-gate 			return (FALSE);
28127c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
28130a701b1eSRobert Gordon 		    (uint_t *)&objp->owner.owner_len,
28140a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT));
28157c478bd9Sstevel@tonic-gate 	}
28167c478bd9Sstevel@tonic-gate 
28177c478bd9Sstevel@tonic-gate 	/*
28187c478bd9Sstevel@tonic-gate 	 * Optimized free case
28197c478bd9Sstevel@tonic-gate 	 */
28207c478bd9Sstevel@tonic-gate 	if (objp->owner.owner_val != NULL)
28217c478bd9Sstevel@tonic-gate 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
28227c478bd9Sstevel@tonic-gate 	return (TRUE);
28237c478bd9Sstevel@tonic-gate }
28247c478bd9Sstevel@tonic-gate 
28257c478bd9Sstevel@tonic-gate static bool_t
28267c478bd9Sstevel@tonic-gate xdr_LOCKT4res(XDR *xdrs, LOCKT4res *objp)
28277c478bd9Sstevel@tonic-gate {
28287c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
28297c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
28307c478bd9Sstevel@tonic-gate 			return (FALSE);
28317c478bd9Sstevel@tonic-gate 		if (objp->status == NFS4_OK)
28327c478bd9Sstevel@tonic-gate 			return (TRUE);
28337c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4ERR_DENIED)
28347c478bd9Sstevel@tonic-gate 			return (TRUE);
28357c478bd9Sstevel@tonic-gate 		/* xdr_LOCK4denied */
28367c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28370a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->denied.offset))
28387c478bd9Sstevel@tonic-gate 			return (FALSE);
28397c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28400a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->denied.length))
28417c478bd9Sstevel@tonic-gate 			return (FALSE);
28427c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->denied.locktype))
28437c478bd9Sstevel@tonic-gate 			return (FALSE);
28447c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28450a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->denied.owner.clientid))
28467c478bd9Sstevel@tonic-gate 			return (FALSE);
28477c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
28487c478bd9Sstevel@tonic-gate 		    (char **)&objp->denied.owner.owner_val,
28497c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->denied.owner.owner_len,
28507c478bd9Sstevel@tonic-gate 		    NFS4_OPAQUE_LIMIT));
28517c478bd9Sstevel@tonic-gate 	}
28527c478bd9Sstevel@tonic-gate 
28537c478bd9Sstevel@tonic-gate 	/*
28547c478bd9Sstevel@tonic-gate 	 * Optimized free case
28557c478bd9Sstevel@tonic-gate 	 */
28567c478bd9Sstevel@tonic-gate 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
28577c478bd9Sstevel@tonic-gate 		return (TRUE);
28587c478bd9Sstevel@tonic-gate 	if (objp->denied.owner.owner_val != NULL)
28597c478bd9Sstevel@tonic-gate 		kmem_free(objp->denied.owner.owner_val,
28600a701b1eSRobert Gordon 		    objp->denied.owner.owner_len);
28617c478bd9Sstevel@tonic-gate 	return (TRUE);
28627c478bd9Sstevel@tonic-gate }
28637c478bd9Sstevel@tonic-gate 
28647c478bd9Sstevel@tonic-gate static bool_t
28657c478bd9Sstevel@tonic-gate xdr_LOCKU4args(XDR *xdrs, LOCKU4args *objp)
28667c478bd9Sstevel@tonic-gate {
28677c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->locktype))
28687c478bd9Sstevel@tonic-gate 		return (FALSE);
28697c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->seqid))
28707c478bd9Sstevel@tonic-gate 		return (FALSE);
28717c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->lock_stateid.seqid))
28727c478bd9Sstevel@tonic-gate 		return (FALSE);
28737c478bd9Sstevel@tonic-gate 	if (!xdr_opaque(xdrs, objp->lock_stateid.other, 12))
28747c478bd9Sstevel@tonic-gate 		return (FALSE);
28757c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
28767c478bd9Sstevel@tonic-gate 		return (FALSE);
28777c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length));
28787c478bd9Sstevel@tonic-gate }
28797c478bd9Sstevel@tonic-gate 
28807c478bd9Sstevel@tonic-gate static bool_t
28817c478bd9Sstevel@tonic-gate xdr_OPEN4args(XDR *xdrs, OPEN4args *objp)
28827c478bd9Sstevel@tonic-gate {
28837c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
28847c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->seqid))
28857c478bd9Sstevel@tonic-gate 			return (FALSE);
28867c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->share_access))
28877c478bd9Sstevel@tonic-gate 			return (FALSE);
28887c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->share_deny))
28897c478bd9Sstevel@tonic-gate 			return (FALSE);
28907c478bd9Sstevel@tonic-gate 
28917c478bd9Sstevel@tonic-gate 		/* xdr_open_owner4 */
28927c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28930a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->owner.clientid))
28947c478bd9Sstevel@tonic-gate 			return (FALSE);
28957c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
28960a701b1eSRobert Gordon 		    (uint_t *)&objp->owner.owner_len,
28970a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT))
28987c478bd9Sstevel@tonic-gate 			return (FALSE);
28997c478bd9Sstevel@tonic-gate 
29007c478bd9Sstevel@tonic-gate 		/* xdr_openflag4 */
29017c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->opentype))
29027c478bd9Sstevel@tonic-gate 			return (FALSE);
29037c478bd9Sstevel@tonic-gate 		if (objp->opentype == OPEN4_CREATE) {
29047c478bd9Sstevel@tonic-gate 
29057c478bd9Sstevel@tonic-gate 			/* xdr_createhow4 */
29067c478bd9Sstevel@tonic-gate 			if (!xdr_int(xdrs, (int *)&objp->mode))
29077c478bd9Sstevel@tonic-gate 				return (FALSE);
29087c478bd9Sstevel@tonic-gate 			switch (objp->mode) {
29097c478bd9Sstevel@tonic-gate 			case UNCHECKED4:
29107c478bd9Sstevel@tonic-gate 			case GUARDED4:
29117c478bd9Sstevel@tonic-gate 				if (!xdr_fattr4(xdrs,
29120a701b1eSRobert Gordon 				    &objp->createhow4_u.createattrs))
29137c478bd9Sstevel@tonic-gate 					return (FALSE);
29147c478bd9Sstevel@tonic-gate 				break;
29157c478bd9Sstevel@tonic-gate 			case EXCLUSIVE4:
29167c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs,
29177c478bd9Sstevel@tonic-gate 				    (u_longlong_t *)&objp->createhow4_u.
29187c478bd9Sstevel@tonic-gate 				    createverf))
29197c478bd9Sstevel@tonic-gate 					return (FALSE);
29207c478bd9Sstevel@tonic-gate 				break;
29217c478bd9Sstevel@tonic-gate 			default:
29227c478bd9Sstevel@tonic-gate 				return (FALSE);
29237c478bd9Sstevel@tonic-gate 			}
29247c478bd9Sstevel@tonic-gate 		}
29257c478bd9Sstevel@tonic-gate 
29267c478bd9Sstevel@tonic-gate 		/* xdr_open_claim4 */
29277c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->claim))
29287c478bd9Sstevel@tonic-gate 			return (FALSE);
29297c478bd9Sstevel@tonic-gate 
29307c478bd9Sstevel@tonic-gate 		switch (objp->claim) {
29317c478bd9Sstevel@tonic-gate 		case CLAIM_NULL:
29327c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
29330a701b1eSRobert Gordon 			    file.utf8string_val,
29340a701b1eSRobert Gordon 			    (uint_t *)&objp->open_claim4_u.file.
29350a701b1eSRobert Gordon 			    utf8string_len,
29360a701b1eSRobert Gordon 			    NFS4_MAX_UTF8STRING));
29377c478bd9Sstevel@tonic-gate 		case CLAIM_PREVIOUS:
29387c478bd9Sstevel@tonic-gate 			return (xdr_int(xdrs,
29390a701b1eSRobert Gordon 			    (int *)&objp->open_claim4_u.delegate_type));
29407c478bd9Sstevel@tonic-gate 		case CLAIM_DELEGATE_CUR:
29417c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (uint_t *)&objp->open_claim4_u.
29420a701b1eSRobert Gordon 			    delegate_cur_info.delegate_stateid.seqid))
29437c478bd9Sstevel@tonic-gate 				return (FALSE);
29447c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->open_claim4_u.
29450a701b1eSRobert Gordon 			    delegate_cur_info.delegate_stateid.other,
29460a701b1eSRobert Gordon 			    12))
29477c478bd9Sstevel@tonic-gate 				return (FALSE);
29487c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
29490a701b1eSRobert Gordon 			    delegate_cur_info.file.utf8string_val,
29507c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->open_claim4_u.
29510a701b1eSRobert Gordon 			    delegate_cur_info.file.utf8string_len,
29527c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING));
29537c478bd9Sstevel@tonic-gate 		case CLAIM_DELEGATE_PREV:
29547c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
29550a701b1eSRobert Gordon 			    file_delegate_prev.utf8string_val,
29567c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->open_claim4_u.
29570a701b1eSRobert Gordon 			    file_delegate_prev.utf8string_len,
29587c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING));
29597c478bd9Sstevel@tonic-gate 		default:
29607c478bd9Sstevel@tonic-gate 			return (FALSE);
29617c478bd9Sstevel@tonic-gate 		}
29627c478bd9Sstevel@tonic-gate 	}
29637c478bd9Sstevel@tonic-gate 
29647c478bd9Sstevel@tonic-gate 	/*
29657c478bd9Sstevel@tonic-gate 	 * Optimized free case
29667c478bd9Sstevel@tonic-gate 	 */
29677c478bd9Sstevel@tonic-gate 	if (objp->owner.owner_val != NULL)
29687c478bd9Sstevel@tonic-gate 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
29697c478bd9Sstevel@tonic-gate 
29707c478bd9Sstevel@tonic-gate 	if (objp->opentype == OPEN4_CREATE) {
29717c478bd9Sstevel@tonic-gate 		switch (objp->mode) {
29727c478bd9Sstevel@tonic-gate 		case UNCHECKED4:
29737c478bd9Sstevel@tonic-gate 		case GUARDED4:
29747c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
29750a701b1eSRobert Gordon 			    &objp->createhow4_u.createattrs);
29767c478bd9Sstevel@tonic-gate 			break;
29777c478bd9Sstevel@tonic-gate 		case EXCLUSIVE4:
29787c478bd9Sstevel@tonic-gate 		default:
29797c478bd9Sstevel@tonic-gate 			break;
29807c478bd9Sstevel@tonic-gate 		}
29817c478bd9Sstevel@tonic-gate 	}
29827c478bd9Sstevel@tonic-gate 
29837c478bd9Sstevel@tonic-gate 	switch (objp->claim) {
29847c478bd9Sstevel@tonic-gate 	case CLAIM_NULL:
29857c478bd9Sstevel@tonic-gate 		if (objp->open_claim4_u.file.utf8string_val != NULL)
29867c478bd9Sstevel@tonic-gate 			kmem_free(objp->open_claim4_u.file.utf8string_val,
29870a701b1eSRobert Gordon 			    objp->open_claim4_u.file.utf8string_len);
29887c478bd9Sstevel@tonic-gate 		return (TRUE);
29897c478bd9Sstevel@tonic-gate 	case CLAIM_PREVIOUS:
29907c478bd9Sstevel@tonic-gate 		return (TRUE);
29917c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_CUR:
29927c478bd9Sstevel@tonic-gate 		if (objp->open_claim4_u.delegate_cur_info.file.utf8string_val !=
29930a701b1eSRobert Gordon 		    NULL) {
29947c478bd9Sstevel@tonic-gate 			kmem_free(objp->open_claim4_u.delegate_cur_info.file.
29950a701b1eSRobert Gordon 			    utf8string_val,
29960a701b1eSRobert Gordon 			    objp->open_claim4_u.delegate_cur_info.file.
29970a701b1eSRobert Gordon 			    utf8string_len);
29987c478bd9Sstevel@tonic-gate 		}
29997c478bd9Sstevel@tonic-gate 		return (TRUE);
30007c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_PREV:
30017c478bd9Sstevel@tonic-gate 		if (objp->open_claim4_u.file_delegate_prev.utf8string_val !=
30020a701b1eSRobert Gordon 		    NULL) {
30037c478bd9Sstevel@tonic-gate 			kmem_free(objp->open_claim4_u.file_delegate_prev.
30040a701b1eSRobert Gordon 			    utf8string_val,
30050a701b1eSRobert Gordon 			    objp->open_claim4_u.file_delegate_prev.
30060a701b1eSRobert Gordon 			    utf8string_len);
30077c478bd9Sstevel@tonic-gate 		}
30087c478bd9Sstevel@tonic-gate 		return (TRUE);
30097c478bd9Sstevel@tonic-gate 	default:
30107c478bd9Sstevel@tonic-gate 		return (TRUE);
30117c478bd9Sstevel@tonic-gate 	}
30127c478bd9Sstevel@tonic-gate }
30137c478bd9Sstevel@tonic-gate 
30147c478bd9Sstevel@tonic-gate static bool_t
30157c478bd9Sstevel@tonic-gate xdr_OPEN4cargs(XDR *xdrs, OPEN4cargs *objp)
30167c478bd9Sstevel@tonic-gate {
30177c478bd9Sstevel@tonic-gate 	int op;
30187c478bd9Sstevel@tonic-gate 	int len;
30197c478bd9Sstevel@tonic-gate 	rpc_inline_t *ptr;
30207c478bd9Sstevel@tonic-gate 
30217c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
30227c478bd9Sstevel@tonic-gate 
30237c478bd9Sstevel@tonic-gate 	/*
30247c478bd9Sstevel@tonic-gate 	 * We must always define the client's open_owner to be
30257c478bd9Sstevel@tonic-gate 	 * 4 byte aligned and sized.
30267c478bd9Sstevel@tonic-gate 	 */
30277c478bd9Sstevel@tonic-gate 	ASSERT(objp->owner.owner_len <= NFS4_OPAQUE_LIMIT);
30287c478bd9Sstevel@tonic-gate 	ASSERT(!(objp->owner.owner_len % BYTES_PER_XDR_UNIT));
30297c478bd9Sstevel@tonic-gate 
30307c478bd9Sstevel@tonic-gate 	len = objp->owner.owner_len;
30317c478bd9Sstevel@tonic-gate 	if ((ptr = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + len)) != NULL) {
30327c478bd9Sstevel@tonic-gate 		int i;
30337c478bd9Sstevel@tonic-gate 		int32_t *ip;
30347c478bd9Sstevel@tonic-gate 
30357c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, OP_OPEN);
30367c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->seqid);
30377c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->share_access);
30387c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->share_deny);
30397c478bd9Sstevel@tonic-gate 
30407c478bd9Sstevel@tonic-gate 		/* xdr_open_owner4 */
30417c478bd9Sstevel@tonic-gate 		IXDR_PUT_HYPER(ptr, objp->owner.clientid);
30427c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->owner.owner_len);
30437c478bd9Sstevel@tonic-gate 		/* We know this is very short so don't bcopy */
30447c478bd9Sstevel@tonic-gate 		ip = (int32_t *)objp->owner.owner_val;
30457c478bd9Sstevel@tonic-gate 		len /= BYTES_PER_XDR_UNIT;
30467c478bd9Sstevel@tonic-gate 		for (i = 0; i < len; i++)
30477c478bd9Sstevel@tonic-gate 			*ptr++ = *ip++;
30487c478bd9Sstevel@tonic-gate 
30497c478bd9Sstevel@tonic-gate 		/* xdr_openflag4 */
30507c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->opentype);
30517c478bd9Sstevel@tonic-gate 	} else {
30527c478bd9Sstevel@tonic-gate 		op = OP_OPEN;
30537c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&op))
30547c478bd9Sstevel@tonic-gate 			return (FALSE);
30557c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->seqid))
30567c478bd9Sstevel@tonic-gate 			return (FALSE);
30577c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_access))
30587c478bd9Sstevel@tonic-gate 			return (FALSE);
30597c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_deny))
30607c478bd9Sstevel@tonic-gate 			return (FALSE);
30617c478bd9Sstevel@tonic-gate 
30627c478bd9Sstevel@tonic-gate 		/* xdr_open_owner4 */
30637c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
30640a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->owner.clientid))
30657c478bd9Sstevel@tonic-gate 			return (FALSE);
30667c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->owner.owner_len))
30677c478bd9Sstevel@tonic-gate 			return (FALSE);
30687c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->owner.owner_val,
30690a701b1eSRobert Gordon 		    objp->owner.owner_len))
30707c478bd9Sstevel@tonic-gate 			return (FALSE);
30717c478bd9Sstevel@tonic-gate 
30727c478bd9Sstevel@tonic-gate 		/* xdr_openflag4 */
30737c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->opentype))
30747c478bd9Sstevel@tonic-gate 			return (FALSE);
30757c478bd9Sstevel@tonic-gate 	}
30767c478bd9Sstevel@tonic-gate 
30777c478bd9Sstevel@tonic-gate 	if (objp->opentype == OPEN4_CREATE) {
30787c478bd9Sstevel@tonic-gate 		/* xdr_createhow4 */
30797c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->mode))
30807c478bd9Sstevel@tonic-gate 			return (FALSE);
30817c478bd9Sstevel@tonic-gate 		switch (objp->mode) {
30827c478bd9Sstevel@tonic-gate 		case UNCHECKED4:
30837c478bd9Sstevel@tonic-gate 		case GUARDED4:
30847c478bd9Sstevel@tonic-gate 			if (!xdr_fattr4(xdrs,
30850a701b1eSRobert Gordon 			    &objp->createhow4_u.createattrs))
30867c478bd9Sstevel@tonic-gate 				return (FALSE);
30877c478bd9Sstevel@tonic-gate 			break;
30887c478bd9Sstevel@tonic-gate 		case EXCLUSIVE4:
30897c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
30907c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->createhow4_u.
30917c478bd9Sstevel@tonic-gate 			    createverf))
30927c478bd9Sstevel@tonic-gate 				return (FALSE);
30937c478bd9Sstevel@tonic-gate 			break;
30947c478bd9Sstevel@tonic-gate 		default:
30957c478bd9Sstevel@tonic-gate 			return (FALSE);
30967c478bd9Sstevel@tonic-gate 		}
30977c478bd9Sstevel@tonic-gate 	}
30987c478bd9Sstevel@tonic-gate 
30997c478bd9Sstevel@tonic-gate 	/* xdr_open_claim4 */
31007c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->claim))
31017c478bd9Sstevel@tonic-gate 		return (FALSE);
31027c478bd9Sstevel@tonic-gate 
31037c478bd9Sstevel@tonic-gate 	switch (objp->claim) {
31047c478bd9Sstevel@tonic-gate 	case CLAIM_NULL:
31057c478bd9Sstevel@tonic-gate 		len = strlen(objp->open_claim4_u.cfile);
31067c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
31077c478bd9Sstevel@tonic-gate 			return (FALSE);
31087c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
31097c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
31100a701b1eSRobert Gordon 			    objp->open_claim4_u.cfile, len));
31117c478bd9Sstevel@tonic-gate 		}
31127c478bd9Sstevel@tonic-gate 		return (FALSE);
31137c478bd9Sstevel@tonic-gate 	case CLAIM_PREVIOUS:
31147c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs,
31150a701b1eSRobert Gordon 		    (int32_t *)&objp->open_claim4_u.delegate_type));
31167c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_CUR:
31177c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->open_claim4_u.
31180a701b1eSRobert Gordon 		    delegate_cur_info.delegate_stateid.seqid))
31197c478bd9Sstevel@tonic-gate 			return (FALSE);
31207c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->open_claim4_u.
31210a701b1eSRobert Gordon 		    delegate_cur_info.delegate_stateid.other,
31220a701b1eSRobert Gordon 		    12))
31237c478bd9Sstevel@tonic-gate 			return (FALSE);
31247c478bd9Sstevel@tonic-gate 		len = strlen(objp->open_claim4_u.delegate_cur_info.cfile);
31257c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
31267c478bd9Sstevel@tonic-gate 			return (FALSE);
31277c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
31287c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
31290a701b1eSRobert Gordon 			    objp->open_claim4_u.delegate_cur_info.cfile,
31300a701b1eSRobert Gordon 			    len));
31317c478bd9Sstevel@tonic-gate 		}
31327c478bd9Sstevel@tonic-gate 		return (FALSE);
31337c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_PREV:
31347c478bd9Sstevel@tonic-gate 		len = strlen(objp->open_claim4_u.cfile_delegate_prev);
31357c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
31367c478bd9Sstevel@tonic-gate 			return (FALSE);
31377c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
31387c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
31390a701b1eSRobert Gordon 			    objp->open_claim4_u.cfile_delegate_prev, len));
31407c478bd9Sstevel@tonic-gate 		}
31417c478bd9Sstevel@tonic-gate 		return (FALSE);
31427c478bd9Sstevel@tonic-gate 	default:
31437c478bd9Sstevel@tonic-gate 		return (FALSE);
31447c478bd9Sstevel@tonic-gate 	}
31457c478bd9Sstevel@tonic-gate }
31467c478bd9Sstevel@tonic-gate 
31477c478bd9Sstevel@tonic-gate static bool_t
31487c478bd9Sstevel@tonic-gate xdr_OPEN4res(XDR *xdrs, OPEN4res *objp)
31497c478bd9Sstevel@tonic-gate {
31507c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
31517c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
31527c478bd9Sstevel@tonic-gate 			return (FALSE);
31537c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
31547c478bd9Sstevel@tonic-gate 			return (TRUE);
31557c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
31567c478bd9Sstevel@tonic-gate 			return (FALSE);
31577c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->stateid.other, 12))
31587c478bd9Sstevel@tonic-gate 			return (FALSE);
31597c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->cinfo.atomic))
31607c478bd9Sstevel@tonic-gate 			return (FALSE);
31617c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
31620a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->cinfo.before))
31637c478bd9Sstevel@tonic-gate 			return (FALSE);
31647c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
31657c478bd9Sstevel@tonic-gate 			return (FALSE);
31667c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->rflags))
31677c478bd9Sstevel@tonic-gate 			return (FALSE);
31687c478bd9Sstevel@tonic-gate 		if (!xdr_bitmap4(xdrs, &objp->attrset))
31697c478bd9Sstevel@tonic-gate 			return (FALSE);
31707c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
31710a701b1eSRobert Gordon 		    (int *)&objp->delegation.delegation_type))
31727c478bd9Sstevel@tonic-gate 			return (FALSE);
31737c478bd9Sstevel@tonic-gate 		switch (objp->delegation.delegation_type) {
31747c478bd9Sstevel@tonic-gate 		case OPEN_DELEGATE_NONE:
31757c478bd9Sstevel@tonic-gate 			return (TRUE);
31767c478bd9Sstevel@tonic-gate 		case OPEN_DELEGATE_READ:
31777c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->delegation.
31780a701b1eSRobert Gordon 			    open_delegation4_u.read.stateid.seqid))
31797c478bd9Sstevel@tonic-gate 				return (FALSE);
31807c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->delegation.
31810a701b1eSRobert Gordon 			    open_delegation4_u.read.stateid.other,
31820a701b1eSRobert Gordon 			    12))
31837c478bd9Sstevel@tonic-gate 				return (FALSE);
31847c478bd9Sstevel@tonic-gate 			if (!xdr_bool(xdrs, &objp->delegation.
31850a701b1eSRobert Gordon 			    open_delegation4_u.read.recall))
31867c478bd9Sstevel@tonic-gate 				return (FALSE);
31877c478bd9Sstevel@tonic-gate 			return (xdr_nfsace4(xdrs, &objp->delegation.
31880a701b1eSRobert Gordon 			    open_delegation4_u.read.permissions));
31897c478bd9Sstevel@tonic-gate 		case OPEN_DELEGATE_WRITE:
31907c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->delegation.
31910a701b1eSRobert Gordon 			    open_delegation4_u.write.stateid.seqid))
31927c478bd9Sstevel@tonic-gate 				return (FALSE);
31937c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->delegation.
31940a701b1eSRobert Gordon 			    open_delegation4_u.write.stateid.other,
31950a701b1eSRobert Gordon 			    12))
31967c478bd9Sstevel@tonic-gate 				return (FALSE);
31977c478bd9Sstevel@tonic-gate 			if (!xdr_bool(xdrs, &objp->delegation.
31980a701b1eSRobert Gordon 			    open_delegation4_u.write.recall))
31997c478bd9Sstevel@tonic-gate 				return (FALSE);
32007c478bd9Sstevel@tonic-gate 			if (!xdr_int(xdrs, (int *)&objp->delegation.
32010a701b1eSRobert Gordon 			    open_delegation4_u.write.space_limit.
32020a701b1eSRobert Gordon 			    limitby))
32037c478bd9Sstevel@tonic-gate 				return (FALSE);
32047c478bd9Sstevel@tonic-gate 			switch (objp->delegation.
32050a701b1eSRobert Gordon 			    open_delegation4_u.write.space_limit.
32060a701b1eSRobert Gordon 			    limitby) {
32077c478bd9Sstevel@tonic-gate 			case NFS_LIMIT_SIZE:
32087c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs,
32097c478bd9Sstevel@tonic-gate 				    (u_longlong_t *)&objp->delegation.
32107c478bd9Sstevel@tonic-gate 				    open_delegation4_u.write.space_limit.
32117c478bd9Sstevel@tonic-gate 				    nfs_space_limit4_u.filesize))
32127c478bd9Sstevel@tonic-gate 					return (FALSE);
32137c478bd9Sstevel@tonic-gate 				break;
32147c478bd9Sstevel@tonic-gate 			case NFS_LIMIT_BLOCKS:
32157c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs,
32167c478bd9Sstevel@tonic-gate 				    &objp->delegation.open_delegation4_u.write.
32177c478bd9Sstevel@tonic-gate 				    space_limit.nfs_space_limit4_u.
32187c478bd9Sstevel@tonic-gate 				    mod_blocks.num_blocks))
32197c478bd9Sstevel@tonic-gate 					return (FALSE);
32207c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &objp->delegation.
32217c478bd9Sstevel@tonic-gate 				    open_delegation4_u.write.space_limit.
32227c478bd9Sstevel@tonic-gate 				    nfs_space_limit4_u.mod_blocks.
32237c478bd9Sstevel@tonic-gate 				    bytes_per_block))
32247c478bd9Sstevel@tonic-gate 					return (FALSE);
32257c478bd9Sstevel@tonic-gate 				break;
32267c478bd9Sstevel@tonic-gate 			default:
32277c478bd9Sstevel@tonic-gate 				return (FALSE);
32287c478bd9Sstevel@tonic-gate 			}
32297c478bd9Sstevel@tonic-gate 			return (xdr_nfsace4(xdrs, &objp->delegation.
32307c478bd9Sstevel@tonic-gate 			    open_delegation4_u.write.permissions));
32317c478bd9Sstevel@tonic-gate 		}
32327c478bd9Sstevel@tonic-gate 		return (FALSE);
32337c478bd9Sstevel@tonic-gate 	}
32347c478bd9Sstevel@tonic-gate 
32357c478bd9Sstevel@tonic-gate 	/*
32367c478bd9Sstevel@tonic-gate 	 * Optimized free case
32377c478bd9Sstevel@tonic-gate 	 */
32387c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
32397c478bd9Sstevel@tonic-gate 		return (TRUE);
32407c478bd9Sstevel@tonic-gate 
32417c478bd9Sstevel@tonic-gate 	switch (objp->delegation.delegation_type) {
32427c478bd9Sstevel@tonic-gate 	case OPEN_DELEGATE_NONE:
32437c478bd9Sstevel@tonic-gate 		return (TRUE);
32447c478bd9Sstevel@tonic-gate 	case OPEN_DELEGATE_READ:
32457c478bd9Sstevel@tonic-gate 		return (xdr_nfsace4(xdrs, &objp->delegation.
32460a701b1eSRobert Gordon 		    open_delegation4_u.read.permissions));
32477c478bd9Sstevel@tonic-gate 	case OPEN_DELEGATE_WRITE:
32487c478bd9Sstevel@tonic-gate 		switch (objp->delegation.
32490a701b1eSRobert Gordon 		    open_delegation4_u.write.space_limit.limitby) {
32507c478bd9Sstevel@tonic-gate 		case NFS_LIMIT_SIZE:
32517c478bd9Sstevel@tonic-gate 		case NFS_LIMIT_BLOCKS:
32527c478bd9Sstevel@tonic-gate 			break;
32537c478bd9Sstevel@tonic-gate 		default:
32547c478bd9Sstevel@tonic-gate 			return (FALSE);
32557c478bd9Sstevel@tonic-gate 		}
32567c478bd9Sstevel@tonic-gate 		return (xdr_nfsace4(xdrs, &objp->delegation.
32570a701b1eSRobert Gordon 		    open_delegation4_u.write.permissions));
32587c478bd9Sstevel@tonic-gate 	}
32597c478bd9Sstevel@tonic-gate 	return (FALSE);
32607c478bd9Sstevel@tonic-gate }
32617c478bd9Sstevel@tonic-gate 
32627c478bd9Sstevel@tonic-gate static bool_t
32637c478bd9Sstevel@tonic-gate xdr_OPEN_CONFIRM4res(XDR *xdrs, OPEN_CONFIRM4res *objp)
32647c478bd9Sstevel@tonic-gate {
32657c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
32667c478bd9Sstevel@tonic-gate 		return (FALSE);
32677c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
32687c478bd9Sstevel@tonic-gate 		return (TRUE);
32697c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
32707c478bd9Sstevel@tonic-gate 		return (FALSE);
32717c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
32727c478bd9Sstevel@tonic-gate }
32737c478bd9Sstevel@tonic-gate 
32747c478bd9Sstevel@tonic-gate static bool_t
32757c478bd9Sstevel@tonic-gate xdr_OPEN_DOWNGRADE4args(XDR *xdrs, OPEN_DOWNGRADE4args *objp)
32767c478bd9Sstevel@tonic-gate {
32777c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
32787c478bd9Sstevel@tonic-gate 		return (FALSE);
32797c478bd9Sstevel@tonic-gate 	if (!xdr_opaque(xdrs, objp->open_stateid.other, 12))
32807c478bd9Sstevel@tonic-gate 		return (FALSE);
32817c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->seqid))
32827c478bd9Sstevel@tonic-gate 		return (FALSE);
32837c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->share_access))
32847c478bd9Sstevel@tonic-gate 		return (FALSE);
32857c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->share_deny));
32867c478bd9Sstevel@tonic-gate }
32877c478bd9Sstevel@tonic-gate 
32887c478bd9Sstevel@tonic-gate static bool_t
32897c478bd9Sstevel@tonic-gate xdr_OPEN_DOWNGRADE4res(XDR *xdrs, OPEN_DOWNGRADE4res *objp)
32907c478bd9Sstevel@tonic-gate {
32917c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
32927c478bd9Sstevel@tonic-gate 		return (FALSE);
32937c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
32947c478bd9Sstevel@tonic-gate 		return (TRUE);
32957c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
32967c478bd9Sstevel@tonic-gate 		return (FALSE);
32977c478bd9Sstevel@tonic-gate 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
32987c478bd9Sstevel@tonic-gate }
32997c478bd9Sstevel@tonic-gate 
33007c478bd9Sstevel@tonic-gate static bool_t
33017c478bd9Sstevel@tonic-gate xdr_READ4args(XDR *xdrs, READ4args *objp)
33027c478bd9Sstevel@tonic-gate {
33030a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
33040a701b1eSRobert Gordon 	rdma_wlist_conn_info_t rwci;
33050a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
33060a701b1eSRobert Gordon 
33077c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->stateid.seqid))
33087c478bd9Sstevel@tonic-gate 		return (FALSE);
33097c478bd9Sstevel@tonic-gate 	if (!xdr_opaque(xdrs, objp->stateid.other, 12))
33107c478bd9Sstevel@tonic-gate 		return (FALSE);
33117c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
33127c478bd9Sstevel@tonic-gate 		return (FALSE);
33130a701b1eSRobert Gordon 	if (!xdr_u_int(xdrs, &objp->count))
33140a701b1eSRobert Gordon 		return (FALSE);
33150a701b1eSRobert Gordon 
33160a701b1eSRobert Gordon 	DTRACE_PROBE1(xdr__i__read4args_buf_len,
33170a701b1eSRobert Gordon 	    int, objp->count);
33180a701b1eSRobert Gordon 
33190a701b1eSRobert Gordon 	objp->wlist = NULL;
33200a701b1eSRobert Gordon 
33210a701b1eSRobert Gordon 	if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
33220a701b1eSRobert Gordon 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
33230a701b1eSRobert Gordon 		rci.rci_len = objp->count;
33240a701b1eSRobert Gordon 		(void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
33250a701b1eSRobert Gordon 	}
33260a701b1eSRobert Gordon 
33270a701b1eSRobert Gordon 	if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
33280a701b1eSRobert Gordon 		return (TRUE);
33290a701b1eSRobert Gordon 
33300a701b1eSRobert Gordon 	if (xdrs->x_op == XDR_ENCODE) {
33310a701b1eSRobert Gordon 		if (objp->res_uiop != NULL) {
33320a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_UIO_CHUNK;
33330a701b1eSRobert Gordon 			rci.rci_a.rci_uiop = objp->res_uiop;
33340a701b1eSRobert Gordon 			rci.rci_len = objp->count;
33350a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
33360a701b1eSRobert Gordon 		} else {
33370a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_ADDR_CHUNK;
33380a701b1eSRobert Gordon 			rci.rci_a.rci_addr = objp->res_data_val_alt;
33390a701b1eSRobert Gordon 			rci.rci_len = objp->count;
33400a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
33410a701b1eSRobert Gordon 		}
33420a701b1eSRobert Gordon 
33430a701b1eSRobert Gordon 		return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
33440a701b1eSRobert Gordon 	}
33450a701b1eSRobert Gordon 
33460a701b1eSRobert Gordon 	/* XDR_DECODE case */
33470a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
33480a701b1eSRobert Gordon 	objp->wlist = rwci.rwci_wlist;
33490a701b1eSRobert Gordon 	objp->conn = rwci.rwci_conn;
33500a701b1eSRobert Gordon 
33510a701b1eSRobert Gordon 	return (TRUE);
33527c478bd9Sstevel@tonic-gate }
33537c478bd9Sstevel@tonic-gate 
33547c478bd9Sstevel@tonic-gate static bool_t
33557c478bd9Sstevel@tonic-gate xdr_READ4res(XDR *xdrs, READ4res *objp)
33567c478bd9Sstevel@tonic-gate {
33577c478bd9Sstevel@tonic-gate 	mblk_t *mp;
33587c478bd9Sstevel@tonic-gate 
33597c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
33607c478bd9Sstevel@tonic-gate 		return (FALSE);
33617c478bd9Sstevel@tonic-gate 
33627c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE) {
33637c478bd9Sstevel@tonic-gate 		/*
33647c478bd9Sstevel@tonic-gate 		 * Optimized free case
33657c478bd9Sstevel@tonic-gate 		 */
33667c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
33677c478bd9Sstevel@tonic-gate 			return (TRUE);
33687c478bd9Sstevel@tonic-gate 		if (objp->data_val != NULL)
33697c478bd9Sstevel@tonic-gate 			kmem_free(objp->data_val, objp->data_len);
33707c478bd9Sstevel@tonic-gate 		return (TRUE);
33717c478bd9Sstevel@tonic-gate 	}
33727c478bd9Sstevel@tonic-gate 
33737c478bd9Sstevel@tonic-gate 	/* on with ENCODE paths */
33747c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->status))
33757c478bd9Sstevel@tonic-gate 		return (FALSE);
33767c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
33777c478bd9Sstevel@tonic-gate 		return (TRUE);
33787c478bd9Sstevel@tonic-gate 
33797c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, &objp->eof))
33807c478bd9Sstevel@tonic-gate 		return (FALSE);
33817c478bd9Sstevel@tonic-gate 
33827c478bd9Sstevel@tonic-gate 	mp = objp->mblk;
3383*e36d7b11SSebastien Roy 	if (mp != NULL) {
3384*e36d7b11SSebastien Roy 		if (xdrs->x_ops == &xdrmblk_ops) {
3385*e36d7b11SSebastien Roy 			if (xdrmblk_putmblk(xdrs, mp, objp->data_len)) {
3386*e36d7b11SSebastien Roy 				objp->mblk = NULL;
3387*e36d7b11SSebastien Roy 				return (TRUE);
3388*e36d7b11SSebastien Roy 			} else {
3389*e36d7b11SSebastien Roy 				return (FALSE);
3390*e36d7b11SSebastien Roy 			}
3391*e36d7b11SSebastien Roy 		} else if (mp->b_cont != NULL) {
3392*e36d7b11SSebastien Roy 			/*
3393*e36d7b11SSebastien Roy 			 * See xdr_READ3res() for an explanation of why we need
3394*e36d7b11SSebastien Roy 			 * to do a pullup here.
3395*e36d7b11SSebastien Roy 			 */
3396*e36d7b11SSebastien Roy 			if (pullupmsg(mp, -1) == 0)
3397*e36d7b11SSebastien Roy 				return (FALSE);
3398*e36d7b11SSebastien Roy 			objp->data_val = (caddr_t)mp->b_rptr;
33997c478bd9Sstevel@tonic-gate 		}
3400*e36d7b11SSebastien Roy 	} else {
34010a701b1eSRobert Gordon 		if (xdr_u_int(xdrs, &objp->data_len) == FALSE) {
34020a701b1eSRobert Gordon 			return (FALSE);
34030a701b1eSRobert Gordon 		}
34040a701b1eSRobert Gordon 		/*
34050a701b1eSRobert Gordon 		 * If read data sent by wlist (RDMA_WRITE), don't do
34060a701b1eSRobert Gordon 		 * xdr_bytes() below.   RDMA_WRITE transfers the data.
34070a701b1eSRobert Gordon 		 * Note: this is encode-only because the client code
34080a701b1eSRobert Gordon 		 * uses xdr_READ4res_clnt to decode results.
34090a701b1eSRobert Gordon 		 */
34100a701b1eSRobert Gordon 		if (objp->wlist) {
34110a701b1eSRobert Gordon 			if (objp->data_len != 0) {
34120a701b1eSRobert Gordon 				return (xdrrdma_send_read_data(
3413f837ee4aSSiddheshwar Mahesh 				    xdrs, objp->data_len, objp->wlist));
34140a701b1eSRobert Gordon 			}
34150a701b1eSRobert Gordon 			return (TRUE);
34160a701b1eSRobert Gordon 		}
34177c478bd9Sstevel@tonic-gate 	}
34180a701b1eSRobert Gordon 
34197c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, (char **)&objp->data_val,
34200a701b1eSRobert Gordon 	    (uint_t *)&objp->data_len,
34210a701b1eSRobert Gordon 	    objp->data_len));
34227c478bd9Sstevel@tonic-gate }
34237c478bd9Sstevel@tonic-gate 
34247c478bd9Sstevel@tonic-gate static bool_t
34257c478bd9Sstevel@tonic-gate xdr_READ4res_clnt(XDR *xdrs, READ4res *objp, READ4args *aobjp)
34267c478bd9Sstevel@tonic-gate {
34277c478bd9Sstevel@tonic-gate 	mblk_t *mp;
34287c478bd9Sstevel@tonic-gate 	size_t n;
34297c478bd9Sstevel@tonic-gate 	int error;
34307c478bd9Sstevel@tonic-gate 	uint_t size = aobjp->res_maxsize;
34310a701b1eSRobert Gordon 	count4 ocount;
34327c478bd9Sstevel@tonic-gate 
34337c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
34347c478bd9Sstevel@tonic-gate 		return (FALSE);
34357c478bd9Sstevel@tonic-gate 
34367c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE) {
34377c478bd9Sstevel@tonic-gate 		/*
34387c478bd9Sstevel@tonic-gate 		 * Optimized free case
34397c478bd9Sstevel@tonic-gate 		 */
34407c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
34417c478bd9Sstevel@tonic-gate 			return (TRUE);
34427c478bd9Sstevel@tonic-gate 		if (objp->data_val != NULL)
34437c478bd9Sstevel@tonic-gate 			kmem_free(objp->data_val, objp->data_len);
34447c478bd9Sstevel@tonic-gate 		return (TRUE);
34457c478bd9Sstevel@tonic-gate 	}
34467c478bd9Sstevel@tonic-gate 
34477c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
34487c478bd9Sstevel@tonic-gate 		return (FALSE);
34497c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
34507c478bd9Sstevel@tonic-gate 		return (TRUE);
34517c478bd9Sstevel@tonic-gate 
34527c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, &objp->eof))
34537c478bd9Sstevel@tonic-gate 		return (FALSE);
34547c478bd9Sstevel@tonic-gate 
34557c478bd9Sstevel@tonic-gate 
34567c478bd9Sstevel@tonic-gate 	/*
34577c478bd9Sstevel@tonic-gate 	 * This is a special case such that the caller is providing a
34587c478bd9Sstevel@tonic-gate 	 * uio as a guide to eventual data location; this is used for
34597c478bd9Sstevel@tonic-gate 	 * handling DIRECTIO reads.
34607c478bd9Sstevel@tonic-gate 	 */
34617c478bd9Sstevel@tonic-gate 	if (aobjp->res_uiop != NULL) {
34627c478bd9Sstevel@tonic-gate 		struct uio *uiop = aobjp->res_uiop;
34637c478bd9Sstevel@tonic-gate 		int32_t *ptr;
34647c478bd9Sstevel@tonic-gate 
34657c478bd9Sstevel@tonic-gate 		if (xdrs->x_ops == &xdrmblk_ops) {
34667c478bd9Sstevel@tonic-gate 			if (!xdrmblk_getmblk(xdrs, &mp, &objp->data_len))
34677c478bd9Sstevel@tonic-gate 				return (FALSE);
34687c478bd9Sstevel@tonic-gate 
34697c478bd9Sstevel@tonic-gate 			if (objp->data_len == 0)
34707c478bd9Sstevel@tonic-gate 				return (TRUE);
34717c478bd9Sstevel@tonic-gate 
34727c478bd9Sstevel@tonic-gate 			if (objp->data_len > size)
34737c478bd9Sstevel@tonic-gate 				return (FALSE);
34747c478bd9Sstevel@tonic-gate 
34757c478bd9Sstevel@tonic-gate 			size = objp->data_len;
34767c478bd9Sstevel@tonic-gate 			do {
34777c478bd9Sstevel@tonic-gate 				n = MIN(size, mp->b_wptr - mp->b_rptr);
34787c478bd9Sstevel@tonic-gate 				if ((n = MIN(uiop->uio_resid, n)) != 0) {
34797c478bd9Sstevel@tonic-gate 
34807c478bd9Sstevel@tonic-gate 					error =	uiomove((char *)mp->b_rptr, n,
34810a701b1eSRobert Gordon 					    UIO_READ, uiop);
34827c478bd9Sstevel@tonic-gate 					if (error)
34837c478bd9Sstevel@tonic-gate 						return (FALSE);
34847c478bd9Sstevel@tonic-gate 					mp->b_rptr += n;
34857c478bd9Sstevel@tonic-gate 					size -= n;
34867c478bd9Sstevel@tonic-gate 				}
34877c478bd9Sstevel@tonic-gate 
34887c478bd9Sstevel@tonic-gate 				while (mp && (mp->b_rptr >= mp->b_wptr))
34897c478bd9Sstevel@tonic-gate 					mp = mp->b_cont;
34907c478bd9Sstevel@tonic-gate 			} while (mp && size > 0 && uiop->uio_resid > 0);
34917c478bd9Sstevel@tonic-gate 
34927c478bd9Sstevel@tonic-gate 			return (TRUE);
34937c478bd9Sstevel@tonic-gate 		}
34947c478bd9Sstevel@tonic-gate 
34950a701b1eSRobert Gordon 		if (xdrs->x_ops == &xdrrdma_ops) {
34960a701b1eSRobert Gordon 			struct clist *cl;
34970a701b1eSRobert Gordon 
34980a701b1eSRobert Gordon 			XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
34990a701b1eSRobert Gordon 
35000a701b1eSRobert Gordon 			objp->wlist = cl;
35010a701b1eSRobert Gordon 
35020a701b1eSRobert Gordon 			if (objp->wlist) {
35030a701b1eSRobert Gordon 				/* opaque count */
35040a701b1eSRobert Gordon 				if (!xdr_u_int(xdrs, &ocount)) {
35050a701b1eSRobert Gordon 					objp->wlist = NULL;
35060a701b1eSRobert Gordon 					return (FALSE);
35070a701b1eSRobert Gordon 				}
35080a701b1eSRobert Gordon 
3509f837ee4aSSiddheshwar Mahesh 				objp->wlist_len = clist_len(cl);
3510f837ee4aSSiddheshwar Mahesh 				objp->data_len = ocount;
35110a701b1eSRobert Gordon 
3512f837ee4aSSiddheshwar Mahesh 				if (objp->wlist_len !=
3513f837ee4aSSiddheshwar Mahesh 				    roundup(
3514f837ee4aSSiddheshwar Mahesh 				    objp->data_len, BYTES_PER_XDR_UNIT)) {
35150a701b1eSRobert Gordon 					DTRACE_PROBE2(
35160a701b1eSRobert Gordon 					    xdr__e__read4resuio_clnt_fail,
35170a701b1eSRobert Gordon 					    int, ocount,
35180a701b1eSRobert Gordon 					    int, objp->data_len);
35190a701b1eSRobert Gordon 					objp->wlist = NULL;
35200a701b1eSRobert Gordon 					return (FALSE);
35210a701b1eSRobert Gordon 				}
35220a701b1eSRobert Gordon 
35230a701b1eSRobert Gordon 				uiop->uio_resid -= objp->data_len;
35240a701b1eSRobert Gordon 				uiop->uio_iov->iov_len -= objp->data_len;
35250a701b1eSRobert Gordon 				uiop->uio_iov->iov_base += objp->data_len;
35260a701b1eSRobert Gordon 				uiop->uio_loffset += objp->data_len;
35270a701b1eSRobert Gordon 
35280a701b1eSRobert Gordon 				objp->wlist = NULL;
35290a701b1eSRobert Gordon 				return (TRUE);
35300a701b1eSRobert Gordon 			}
35310a701b1eSRobert Gordon 		}
35320a701b1eSRobert Gordon 
35337c478bd9Sstevel@tonic-gate 		/*
35340a701b1eSRobert Gordon 		 * This isn't an xdrmblk stream nor RDMA.
35350a701b1eSRobert Gordon 		 * Handle the likely case that it can be
35360a701b1eSRobert Gordon 		 * inlined (ex. xdrmem).
35377c478bd9Sstevel@tonic-gate 		 */
35387c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&objp->data_len))
35397c478bd9Sstevel@tonic-gate 			return (FALSE);
35407c478bd9Sstevel@tonic-gate 
35417c478bd9Sstevel@tonic-gate 		if (objp->data_len == 0)
35427c478bd9Sstevel@tonic-gate 			return (TRUE);
35437c478bd9Sstevel@tonic-gate 
35447c478bd9Sstevel@tonic-gate 		if (objp->data_len > size)
35457c478bd9Sstevel@tonic-gate 			return (FALSE);
35467c478bd9Sstevel@tonic-gate 
35477c478bd9Sstevel@tonic-gate 		size = (int)objp->data_len;
35487c478bd9Sstevel@tonic-gate 		if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
35497c478bd9Sstevel@tonic-gate 			return (uiomove(ptr, size, UIO_READ, uiop) ?
35500a701b1eSRobert Gordon 			    FALSE : TRUE);
35517c478bd9Sstevel@tonic-gate 
35527c478bd9Sstevel@tonic-gate 		/*
35537c478bd9Sstevel@tonic-gate 		 * Handle some other (unlikely) stream type that will
35547c478bd9Sstevel@tonic-gate 		 * need a copy.
35557c478bd9Sstevel@tonic-gate 		 */
35567c478bd9Sstevel@tonic-gate 		if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
35577c478bd9Sstevel@tonic-gate 			return (FALSE);
35587c478bd9Sstevel@tonic-gate 
35597c478bd9Sstevel@tonic-gate 		if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
35607c478bd9Sstevel@tonic-gate 			kmem_free(ptr, size);
35617c478bd9Sstevel@tonic-gate 			return (FALSE);
35627c478bd9Sstevel@tonic-gate 		}
35637c478bd9Sstevel@tonic-gate 		error = uiomove(ptr, size, UIO_READ, uiop);
35647c478bd9Sstevel@tonic-gate 		kmem_free(ptr, size);
35657c478bd9Sstevel@tonic-gate 
35667c478bd9Sstevel@tonic-gate 		return (error ? FALSE : TRUE);
35677c478bd9Sstevel@tonic-gate 	}
35687c478bd9Sstevel@tonic-gate 
35697c478bd9Sstevel@tonic-gate 	/*
35707c478bd9Sstevel@tonic-gate 	 * Check for the other special case of the caller providing
35717c478bd9Sstevel@tonic-gate 	 * the target area for the data.
35727c478bd9Sstevel@tonic-gate 	 */
35730a701b1eSRobert Gordon 	if (aobjp->res_data_val_alt == NULL)
35740a701b1eSRobert Gordon 		return (FALSE);
35757c478bd9Sstevel@tonic-gate 
35760a701b1eSRobert Gordon 	/*
35770a701b1eSRobert Gordon 	 * If read data received via RDMA_WRITE, don't do xdr_bytes().
35780a701b1eSRobert Gordon 	 * RDMA_WRITE already moved the data so decode length of
35790a701b1eSRobert Gordon 	 * RDMA_WRITE.
35800a701b1eSRobert Gordon 	 */
35810a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops) {
35820a701b1eSRobert Gordon 		struct clist *cl;
35830a701b1eSRobert Gordon 
35840a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
35850a701b1eSRobert Gordon 
35860a701b1eSRobert Gordon 		objp->wlist = cl;
35870a701b1eSRobert Gordon 
35880a701b1eSRobert Gordon 		/*
35890a701b1eSRobert Gordon 		 * Data transferred through inline if
35900a701b1eSRobert Gordon 		 * objp->wlist == NULL
35910a701b1eSRobert Gordon 		 */
35920a701b1eSRobert Gordon 		if (objp->wlist) {
35930a701b1eSRobert Gordon 			/* opaque count */
35940a701b1eSRobert Gordon 			if (!xdr_u_int(xdrs, &ocount)) {
35950a701b1eSRobert Gordon 				objp->wlist = NULL;
35960a701b1eSRobert Gordon 				return (FALSE);
35970a701b1eSRobert Gordon 			}
35980a701b1eSRobert Gordon 
3599f837ee4aSSiddheshwar Mahesh 			objp->wlist_len = clist_len(cl);
3600f837ee4aSSiddheshwar Mahesh 			objp->data_len = ocount;
36010a701b1eSRobert Gordon 
3602f837ee4aSSiddheshwar Mahesh 			if (objp->wlist_len !=
3603f837ee4aSSiddheshwar Mahesh 			    roundup(
3604f837ee4aSSiddheshwar Mahesh 			    objp->data_len, BYTES_PER_XDR_UNIT)) {
36050a701b1eSRobert Gordon 				DTRACE_PROBE2(
36060a701b1eSRobert Gordon 				    xdr__e__read4res_clnt_fail,
36070a701b1eSRobert Gordon 				    int, ocount,
36080a701b1eSRobert Gordon 				    int, objp->data_len);
36090a701b1eSRobert Gordon 				objp->wlist = NULL;
36100a701b1eSRobert Gordon 				return (FALSE);
36110a701b1eSRobert Gordon 			}
36120a701b1eSRobert Gordon 
36130a701b1eSRobert Gordon 			objp->wlist = NULL;
36140a701b1eSRobert Gordon 			return (TRUE);
36150a701b1eSRobert Gordon 		}
36160a701b1eSRobert Gordon 	}
36170a701b1eSRobert Gordon 
36180a701b1eSRobert Gordon 	return (xdr_bytes(xdrs, (char **)&aobjp->res_data_val_alt,
36190a701b1eSRobert Gordon 	    (uint_t *)&objp->data_len,
36200a701b1eSRobert Gordon 	    aobjp->res_maxsize));
36217c478bd9Sstevel@tonic-gate }
36227c478bd9Sstevel@tonic-gate 
36237c478bd9Sstevel@tonic-gate static bool_t
36247c478bd9Sstevel@tonic-gate xdr_READDIR4args(XDR *xdrs, READDIR4args *objp)
36257c478bd9Sstevel@tonic-gate {
36260a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
36270a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
36280a701b1eSRobert Gordon 
36290a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
36300a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
36310a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
36320a701b1eSRobert Gordon 		rci.rci_len = objp->maxcount;
36330a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
36340a701b1eSRobert Gordon 	}
36350a701b1eSRobert Gordon 
36367c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookie))
36377c478bd9Sstevel@tonic-gate 		return (FALSE);
36387c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
36397c478bd9Sstevel@tonic-gate 		return (FALSE);
36407c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->dircount))
36417c478bd9Sstevel@tonic-gate 		return (FALSE);
36427c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->maxcount))
36437c478bd9Sstevel@tonic-gate 		return (FALSE);
36447c478bd9Sstevel@tonic-gate 	return (xdr_bitmap4(xdrs, &objp->attr_request));
36457c478bd9Sstevel@tonic-gate }
36467c478bd9Sstevel@tonic-gate 
36477c478bd9Sstevel@tonic-gate /* ARGSUSED */
36487c478bd9Sstevel@tonic-gate static bool_t
36497c478bd9Sstevel@tonic-gate xdrmblk_putmblk_rd(XDR *xdrs, mblk_t *m)
36507c478bd9Sstevel@tonic-gate {
36517c478bd9Sstevel@tonic-gate 	if (((m->b_wptr - m->b_rptr) % BYTES_PER_XDR_UNIT) != 0)
36527c478bd9Sstevel@tonic-gate 		return (FALSE);
36537c478bd9Sstevel@tonic-gate 
36547c478bd9Sstevel@tonic-gate 	/* LINTED pointer alignment */
36557c478bd9Sstevel@tonic-gate 	((mblk_t *)xdrs->x_base)->b_cont = m;
36567c478bd9Sstevel@tonic-gate 	xdrs->x_base = (caddr_t)m;
36577c478bd9Sstevel@tonic-gate 	xdrs->x_handy = 0;
36587c478bd9Sstevel@tonic-gate 	return (TRUE);
36597c478bd9Sstevel@tonic-gate }
36607c478bd9Sstevel@tonic-gate 
36617c478bd9Sstevel@tonic-gate bool_t
36627c478bd9Sstevel@tonic-gate xdr_READDIR4res(XDR *xdrs, READDIR4res *objp)
36637c478bd9Sstevel@tonic-gate {
36647c478bd9Sstevel@tonic-gate 	mblk_t *mp = objp->mblk;
36657c478bd9Sstevel@tonic-gate 	bool_t ret_val;
36667c478bd9Sstevel@tonic-gate 	uint_t flags = 0;
36677c478bd9Sstevel@tonic-gate 
36687c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
36697c478bd9Sstevel@tonic-gate 
36707c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
36717c478bd9Sstevel@tonic-gate 		return (FALSE);
36727c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
36737c478bd9Sstevel@tonic-gate 		return (TRUE);
36747c478bd9Sstevel@tonic-gate 	if (mp == NULL)
36757c478bd9Sstevel@tonic-gate 		return (FALSE);
36767c478bd9Sstevel@tonic-gate 
36777c478bd9Sstevel@tonic-gate 	if (xdrs->x_ops == &xdrmblk_ops) {
36787c478bd9Sstevel@tonic-gate 		if (xdrmblk_putmblk_rd(xdrs, mp)
36790a701b1eSRobert Gordon 		    == TRUE) {
36807c478bd9Sstevel@tonic-gate 			/* mblk successfully inserted into outgoing chain */
36817c478bd9Sstevel@tonic-gate 			objp->mblk = NULL;
36827c478bd9Sstevel@tonic-gate 			return (TRUE);
36837c478bd9Sstevel@tonic-gate 		}
36847c478bd9Sstevel@tonic-gate 	}
36857c478bd9Sstevel@tonic-gate 
36867c478bd9Sstevel@tonic-gate 	ASSERT(mp->b_cont == NULL);
36877c478bd9Sstevel@tonic-gate 
36887c478bd9Sstevel@tonic-gate 	/*
36890a701b1eSRobert Gordon 	 * If transport is RDMA, the pre-encoded m_blk needs to be moved
36907c478bd9Sstevel@tonic-gate 	 * without being chunked.
36910a701b1eSRobert Gordon 	 * Check if chunking is enabled for the xdr stream.
36920a701b1eSRobert Gordon 	 * If it is enabled, disable it temporarily for this op,
36930a701b1eSRobert Gordon 	 * then re-enable.
36947c478bd9Sstevel@tonic-gate 	 */
36950a701b1eSRobert Gordon 	XDR_CONTROL(xdrs, XDR_RDMA_GET_FLAGS, &flags);
36960a701b1eSRobert Gordon 
36970a701b1eSRobert Gordon 	if (!(flags & XDR_RDMA_CHUNK))
36987c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len));
36997c478bd9Sstevel@tonic-gate 
37000a701b1eSRobert Gordon 	flags &= ~XDR_RDMA_CHUNK;
37010a701b1eSRobert Gordon 
37020a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
37030a701b1eSRobert Gordon 
37047c478bd9Sstevel@tonic-gate 	ret_val = xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len);
37050a701b1eSRobert Gordon 
37060a701b1eSRobert Gordon 	flags |= XDR_RDMA_CHUNK;
37070a701b1eSRobert Gordon 
37080a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
37090a701b1eSRobert Gordon 
37107c478bd9Sstevel@tonic-gate 	return (ret_val);
37117c478bd9Sstevel@tonic-gate }
37127c478bd9Sstevel@tonic-gate 
37137c478bd9Sstevel@tonic-gate static bool_t
37147c478bd9Sstevel@tonic-gate xdr_READLINK4res(XDR *xdrs, READLINK4res *objp)
37157c478bd9Sstevel@tonic-gate {
37167c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
37177c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
37187c478bd9Sstevel@tonic-gate 			return (FALSE);
37197c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
37207c478bd9Sstevel@tonic-gate 			return (TRUE);
37217c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->link.utf8string_val,
37220a701b1eSRobert Gordon 		    (uint_t *)&objp->link.utf8string_len,
37230a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
37247c478bd9Sstevel@tonic-gate 	}
37257c478bd9Sstevel@tonic-gate 
37267c478bd9Sstevel@tonic-gate 	/*
37277c478bd9Sstevel@tonic-gate 	 * Optimized free case
37287c478bd9Sstevel@tonic-gate 	 */
37297c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
37307c478bd9Sstevel@tonic-gate 		return (TRUE);
37317c478bd9Sstevel@tonic-gate 	if (objp->link.utf8string_val != NULL)
37327c478bd9Sstevel@tonic-gate 		kmem_free(objp->link.utf8string_val, objp->link.utf8string_len);
37337c478bd9Sstevel@tonic-gate 	return (TRUE);
37347c478bd9Sstevel@tonic-gate }
37357c478bd9Sstevel@tonic-gate 
37367c478bd9Sstevel@tonic-gate static bool_t
37377c478bd9Sstevel@tonic-gate xdr_REMOVE4res(XDR *xdrs, REMOVE4res *objp)
37387c478bd9Sstevel@tonic-gate {
37397c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
37407c478bd9Sstevel@tonic-gate 		return (FALSE);
37417c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
37427c478bd9Sstevel@tonic-gate 		return (TRUE);
37437c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
37447c478bd9Sstevel@tonic-gate 		return (FALSE);
37457c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
37467c478bd9Sstevel@tonic-gate 		return (FALSE);
37477c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs,
37480a701b1eSRobert Gordon 	    (u_longlong_t *)&objp->cinfo.after));
37497c478bd9Sstevel@tonic-gate }
37507c478bd9Sstevel@tonic-gate 
37517c478bd9Sstevel@tonic-gate static bool_t
37527c478bd9Sstevel@tonic-gate xdr_RENAME4res(XDR *xdrs, RENAME4res *objp)
37537c478bd9Sstevel@tonic-gate {
37547c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
37557c478bd9Sstevel@tonic-gate 		return (FALSE);
37567c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
37577c478bd9Sstevel@tonic-gate 		return (TRUE);
37587c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->source_cinfo.atomic))
37597c478bd9Sstevel@tonic-gate 		return (FALSE);
37607c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs,
37617c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->source_cinfo.before))
37627c478bd9Sstevel@tonic-gate 		return (FALSE);
37637c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs,
37647c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->source_cinfo.after))
37657c478bd9Sstevel@tonic-gate 		return (FALSE);
37667c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->target_cinfo.atomic))
37677c478bd9Sstevel@tonic-gate 		return (FALSE);
37687c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs,
37697c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->target_cinfo.before))
37707c478bd9Sstevel@tonic-gate 		return (FALSE);
37717c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs,
37720a701b1eSRobert Gordon 	    (u_longlong_t *)&objp->target_cinfo.after));
37737c478bd9Sstevel@tonic-gate }
37747c478bd9Sstevel@tonic-gate 
37757c478bd9Sstevel@tonic-gate static bool_t
37767c478bd9Sstevel@tonic-gate xdr_secinfo4(XDR *xdrs, secinfo4 *objp)
37777c478bd9Sstevel@tonic-gate {
37787c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
37797c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->flavor))
37807c478bd9Sstevel@tonic-gate 			return (FALSE);
37817c478bd9Sstevel@tonic-gate 		if (objp->flavor != RPCSEC_GSS)
37827c478bd9Sstevel@tonic-gate 			return (TRUE);
37837c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs,
37840a701b1eSRobert Gordon 		    (char **)&objp->flavor_info.oid.sec_oid4_val,
37850a701b1eSRobert Gordon 		    (uint_t *)&objp->flavor_info.oid.sec_oid4_len,
37860a701b1eSRobert Gordon 		    NFS4_MAX_SECOID4))
37877c478bd9Sstevel@tonic-gate 			return (FALSE);
37887c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->flavor_info.qop))
37897c478bd9Sstevel@tonic-gate 			return (FALSE);
37907c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs, (int *)&objp->flavor_info.service));
37917c478bd9Sstevel@tonic-gate 	}
37927c478bd9Sstevel@tonic-gate 
37937c478bd9Sstevel@tonic-gate 	/*
37947c478bd9Sstevel@tonic-gate 	 * Optimized free path
37957c478bd9Sstevel@tonic-gate 	 */
37967c478bd9Sstevel@tonic-gate 	if (objp->flavor != RPCSEC_GSS)
37977c478bd9Sstevel@tonic-gate 		return (TRUE);
37987c478bd9Sstevel@tonic-gate 
37997c478bd9Sstevel@tonic-gate 	if (objp->flavor_info.oid.sec_oid4_val != NULL)
38007c478bd9Sstevel@tonic-gate 		kmem_free(objp->flavor_info.oid.sec_oid4_val,
38010a701b1eSRobert Gordon 		    objp->flavor_info.oid.sec_oid4_len);
38027c478bd9Sstevel@tonic-gate 	return (TRUE);
38037c478bd9Sstevel@tonic-gate }
38047c478bd9Sstevel@tonic-gate 
38057c478bd9Sstevel@tonic-gate static bool_t
38067c478bd9Sstevel@tonic-gate xdr_SETCLIENTID4args(XDR *xdrs, SETCLIENTID4args *objp)
38077c478bd9Sstevel@tonic-gate {
38087c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
38097c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
38100a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->client.verifier))
38117c478bd9Sstevel@tonic-gate 			return (FALSE);
38127c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->client.id_val,
38130a701b1eSRobert Gordon 		    (uint_t *)&objp->client.id_len, NFS4_OPAQUE_LIMIT))
38147c478bd9Sstevel@tonic-gate 			return (FALSE);
38157c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->callback.cb_program))
38167c478bd9Sstevel@tonic-gate 			return (FALSE);
38177c478bd9Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_netid,
38180a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT))
38197c478bd9Sstevel@tonic-gate 			return (FALSE);
38207c478bd9Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_addr,
38210a701b1eSRobert Gordon 		    NFS4_OPAQUE_LIMIT))
38227c478bd9Sstevel@tonic-gate 			return (FALSE);
38237c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->callback_ident));
38247c478bd9Sstevel@tonic-gate 	}
38257c478bd9Sstevel@tonic-gate 
38267c478bd9Sstevel@tonic-gate 	/*
38277c478bd9Sstevel@tonic-gate 	 * Optimized free case
38287c478bd9Sstevel@tonic-gate 	 */
38297c478bd9Sstevel@tonic-gate 	if (objp->client.id_val != NULL)
38307c478bd9Sstevel@tonic-gate 		kmem_free(objp->client.id_val, objp->client.id_len);
38317c478bd9Sstevel@tonic-gate 	(void) xdr_string(xdrs, &objp->callback.cb_location.r_netid,
38320a701b1eSRobert Gordon 	    NFS4_OPAQUE_LIMIT);
38337c478bd9Sstevel@tonic-gate 	return (xdr_string(xdrs, &objp->callback.cb_location.r_addr,
38340a701b1eSRobert Gordon 	    NFS4_OPAQUE_LIMIT));
38357c478bd9Sstevel@tonic-gate }
38367c478bd9Sstevel@tonic-gate 
38377c478bd9Sstevel@tonic-gate static bool_t
38387c478bd9Sstevel@tonic-gate xdr_SETCLIENTID4res(XDR *xdrs, SETCLIENTID4res *objp)
38397c478bd9Sstevel@tonic-gate {
38407c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
38417c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
38427c478bd9Sstevel@tonic-gate 			return (FALSE);
38437c478bd9Sstevel@tonic-gate 		switch (objp->status) {
38447c478bd9Sstevel@tonic-gate 		case NFS4_OK:
38457c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
38467c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.resok4.
38477c478bd9Sstevel@tonic-gate 			    clientid))
38487c478bd9Sstevel@tonic-gate 				return (FALSE);
38497c478bd9Sstevel@tonic-gate 			return (xdr_u_longlong_t(xdrs,
38507c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.
38510a701b1eSRobert Gordon 			    resok4.setclientid_confirm));
38527c478bd9Sstevel@tonic-gate 		case NFS4ERR_CLID_INUSE:
38537c478bd9Sstevel@tonic-gate 			if (!xdr_string(xdrs,
38540a701b1eSRobert Gordon 			    &objp->SETCLIENTID4res_u.client_using.
38550a701b1eSRobert Gordon 			    r_netid, NFS4_OPAQUE_LIMIT))
38567c478bd9Sstevel@tonic-gate 				return (FALSE);
38577c478bd9Sstevel@tonic-gate 			return (xdr_string(xdrs,
38580a701b1eSRobert Gordon 			    &objp->SETCLIENTID4res_u.client_using.
38590a701b1eSRobert Gordon 			    r_addr, NFS4_OPAQUE_LIMIT));
38607c478bd9Sstevel@tonic-gate 		}
38617c478bd9Sstevel@tonic-gate 		return (TRUE);
38627c478bd9Sstevel@tonic-gate 	}
38637c478bd9Sstevel@tonic-gate 
38647c478bd9Sstevel@tonic-gate 	/*
38657c478bd9Sstevel@tonic-gate 	 * Optimized free case
38667c478bd9Sstevel@tonic-gate 	 */
38677c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4ERR_CLID_INUSE)
38687c478bd9Sstevel@tonic-gate 		return (TRUE);
38697c478bd9Sstevel@tonic-gate 
38707c478bd9Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_netid,
38710a701b1eSRobert Gordon 	    NFS4_OPAQUE_LIMIT))
38727c478bd9Sstevel@tonic-gate 		return (FALSE);
38737c478bd9Sstevel@tonic-gate 	return (xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_addr,
38740a701b1eSRobert Gordon 	    NFS4_OPAQUE_LIMIT));
38757c478bd9Sstevel@tonic-gate }
38767c478bd9Sstevel@tonic-gate 
38777c478bd9Sstevel@tonic-gate static bool_t
38787c478bd9Sstevel@tonic-gate xdr_WRITE4args(XDR *xdrs, WRITE4args *objp)
38797c478bd9Sstevel@tonic-gate {
38807c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
38817c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
38827c478bd9Sstevel@tonic-gate 			return (FALSE);
38837c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->stateid.other, 12))
38847c478bd9Sstevel@tonic-gate 			return (FALSE);
38857c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
38867c478bd9Sstevel@tonic-gate 			return (FALSE);
38877c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->stable))
38887c478bd9Sstevel@tonic-gate 			return (FALSE);
38897c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
38907c478bd9Sstevel@tonic-gate 			if (xdrs->x_ops == &xdrmblk_ops) {
38917c478bd9Sstevel@tonic-gate 				objp->data_val = NULL;
38927c478bd9Sstevel@tonic-gate 				return (xdrmblk_getmblk(xdrs, &objp->mblk,
38930a701b1eSRobert Gordon 				    &objp->data_len));
38947c478bd9Sstevel@tonic-gate 			}
38957c478bd9Sstevel@tonic-gate 			objp->mblk = NULL;
38960a701b1eSRobert Gordon 			if (xdrs->x_ops == &xdrrdmablk_ops) {
38970a701b1eSRobert Gordon 				int retval;
38980a701b1eSRobert Gordon 				retval = xdrrdma_getrdmablk(xdrs,
38990a701b1eSRobert Gordon 				    &objp->rlist,
39000a701b1eSRobert Gordon 				    &objp->data_len,
39010a701b1eSRobert Gordon 				    &objp->conn, NFS4_DATA_LIMIT);
39020a701b1eSRobert Gordon 				if (retval == FALSE)
39030a701b1eSRobert Gordon 					return (FALSE);
3904f837ee4aSSiddheshwar Mahesh 				return (xdrrdma_read_from_client(objp->rlist,
39050a701b1eSRobert Gordon 				    &objp->conn, objp->data_len));
39060a701b1eSRobert Gordon 			}
39077c478bd9Sstevel@tonic-gate 		}
39080a701b1eSRobert Gordon 		/* Else fall thru for the xdr_bytes(). */
39097c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->data_val,
39100a701b1eSRobert Gordon 		    (uint_t *)&objp->data_len, NFS4_DATA_LIMIT));
39110a701b1eSRobert Gordon 	}
39120a701b1eSRobert Gordon 	if (objp->rlist != NULL) {
39130a701b1eSRobert Gordon 		(void) xdrrdma_free_clist(objp->conn, objp->rlist);
39140a701b1eSRobert Gordon 		objp->rlist = NULL;
39150a701b1eSRobert Gordon 		objp->data_val = NULL;
39160a701b1eSRobert Gordon 
39170a701b1eSRobert Gordon 		return (TRUE);
39187c478bd9Sstevel@tonic-gate 	}
39197c478bd9Sstevel@tonic-gate 
39207c478bd9Sstevel@tonic-gate 	/*
39217c478bd9Sstevel@tonic-gate 	 * Optimized free case
39227c478bd9Sstevel@tonic-gate 	 */
39237c478bd9Sstevel@tonic-gate 	if (objp->data_val != NULL)
39247c478bd9Sstevel@tonic-gate 		kmem_free(objp->data_val, objp->data_len);
39257c478bd9Sstevel@tonic-gate 	return (TRUE);
39267c478bd9Sstevel@tonic-gate }
39277c478bd9Sstevel@tonic-gate 
39287c478bd9Sstevel@tonic-gate static bool_t
39297c478bd9Sstevel@tonic-gate xdr_WRITE4res(XDR *xdrs, WRITE4res *objp)
39307c478bd9Sstevel@tonic-gate {
39317c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
39327c478bd9Sstevel@tonic-gate 		return (FALSE);
39337c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
39347c478bd9Sstevel@tonic-gate 		return (TRUE);
39357c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->count))
39367c478bd9Sstevel@tonic-gate 		return (FALSE);
39377c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->committed))
39387c478bd9Sstevel@tonic-gate 		return (FALSE);
39397c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs,
39400a701b1eSRobert Gordon 	    (u_longlong_t *)&objp->writeverf));
39417c478bd9Sstevel@tonic-gate }
39427c478bd9Sstevel@tonic-gate 
39437c478bd9Sstevel@tonic-gate static bool_t
39447c46fb7fSek xdr_snfs_argop4_free(XDR *xdrs, nfs_argop4 **arrayp, int len)
39457c478bd9Sstevel@tonic-gate {
39467c478bd9Sstevel@tonic-gate 	int i;
39477c478bd9Sstevel@tonic-gate 	nfs_argop4 *array = *arrayp;
39487c478bd9Sstevel@tonic-gate 
39497c478bd9Sstevel@tonic-gate 	/*
39507c478bd9Sstevel@tonic-gate 	 * Optimized XDR_FREE only args array
39517c478bd9Sstevel@tonic-gate 	 */
39527c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_FREE);
39537c478bd9Sstevel@tonic-gate 
39547c478bd9Sstevel@tonic-gate 	/*
39557c478bd9Sstevel@tonic-gate 	 * Nothing to do?
39567c478bd9Sstevel@tonic-gate 	 */
39577c478bd9Sstevel@tonic-gate 	if (array == NULL)
39587c478bd9Sstevel@tonic-gate 		return (TRUE);
39597c478bd9Sstevel@tonic-gate 
39607c478bd9Sstevel@tonic-gate 	for (i = 0; i < len; i++) {
39617c478bd9Sstevel@tonic-gate 		/*
39627c478bd9Sstevel@tonic-gate 		 * These should be ordered by frequency of use
39637c478bd9Sstevel@tonic-gate 		 */
39647c478bd9Sstevel@tonic-gate 		switch (array[i].argop) {
3965297b4d80SVitaliy Gusev 		case OP_PUTFH: {
3966297b4d80SVitaliy Gusev 			nfs_fh4 *objp = &array[i].nfs_argop4_u.opputfh.object;
3967297b4d80SVitaliy Gusev 
3968297b4d80SVitaliy Gusev 			if (objp->nfs_fh4_val != NULL) {
3969297b4d80SVitaliy Gusev 				kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
39707c478bd9Sstevel@tonic-gate 			}
39717c478bd9Sstevel@tonic-gate 			continue;
3972297b4d80SVitaliy Gusev 		}
39737c478bd9Sstevel@tonic-gate 		case OP_GETATTR:
39747c478bd9Sstevel@tonic-gate 		case OP_GETFH:
39757c478bd9Sstevel@tonic-gate 			continue;
39767c478bd9Sstevel@tonic-gate 		case OP_LOOKUP:
39777c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oplookup.objname.
39780a701b1eSRobert Gordon 			    utf8string_val != NULL) {
39797c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oplookup.
39800a701b1eSRobert Gordon 				    objname.utf8string_val,
39810a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.oplookup.
39820a701b1eSRobert Gordon 				    objname.utf8string_len);
39837c478bd9Sstevel@tonic-gate 			}
39847c478bd9Sstevel@tonic-gate 			continue;
39857c478bd9Sstevel@tonic-gate 		case OP_OPEN:
39867c478bd9Sstevel@tonic-gate 			(void) xdr_OPEN4args(xdrs,
39870a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opopen);
39887c478bd9Sstevel@tonic-gate 			continue;
39897c478bd9Sstevel@tonic-gate 		case OP_CLOSE:
39907c478bd9Sstevel@tonic-gate 		case OP_ACCESS:
39917c478bd9Sstevel@tonic-gate 		case OP_READ:
39927c478bd9Sstevel@tonic-gate 			continue;
39937c478bd9Sstevel@tonic-gate 		case OP_WRITE:
39947c478bd9Sstevel@tonic-gate 			(void) xdr_WRITE4args(xdrs,
39950a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opwrite);
39967c478bd9Sstevel@tonic-gate 			continue;
39977c478bd9Sstevel@tonic-gate 		case OP_DELEGRETURN:
39987c478bd9Sstevel@tonic-gate 		case OP_LOOKUPP:
39997c478bd9Sstevel@tonic-gate 		case OP_READDIR:
40007c478bd9Sstevel@tonic-gate 			continue;
40017c478bd9Sstevel@tonic-gate 		case OP_REMOVE:
40027c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.opremove.target.
40030a701b1eSRobert Gordon 			    utf8string_val != NULL) {
40047c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.opremove.target.
40050a701b1eSRobert Gordon 				    utf8string_val,
40060a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.opremove.target.
40070a701b1eSRobert Gordon 				    utf8string_len);
40087c478bd9Sstevel@tonic-gate 			}
40097c478bd9Sstevel@tonic-gate 			continue;
40107c478bd9Sstevel@tonic-gate 		case OP_COMMIT:
40117c478bd9Sstevel@tonic-gate 			continue;
40127c478bd9Sstevel@tonic-gate 		case OP_CREATE:
40137c478bd9Sstevel@tonic-gate 			(void) xdr_CREATE4args(xdrs,
40140a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opcreate);
40157c478bd9Sstevel@tonic-gate 			continue;
40167c478bd9Sstevel@tonic-gate 		case OP_DELEGPURGE:
40177c478bd9Sstevel@tonic-gate 			continue;
40187c478bd9Sstevel@tonic-gate 		case OP_LINK:
40197c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oplink.newname.
40200a701b1eSRobert Gordon 			    utf8string_val != NULL) {
40217c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oplink.newname.
40220a701b1eSRobert Gordon 				    utf8string_val,
40230a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.oplink.newname.
40240a701b1eSRobert Gordon 				    utf8string_len);
40257c478bd9Sstevel@tonic-gate 			}
40267c478bd9Sstevel@tonic-gate 			continue;
40277c478bd9Sstevel@tonic-gate 		case OP_LOCK:
40287c478bd9Sstevel@tonic-gate 			(void) xdr_LOCK4args(xdrs,
40290a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.oplock);
40307c478bd9Sstevel@tonic-gate 			continue;
40317c478bd9Sstevel@tonic-gate 		case OP_LOCKT:
40327c478bd9Sstevel@tonic-gate 			(void) xdr_LOCKT4args(xdrs,
40330a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.oplockt);
40347c478bd9Sstevel@tonic-gate 			continue;
40357c478bd9Sstevel@tonic-gate 		case OP_LOCKU:
40367c478bd9Sstevel@tonic-gate 			continue;
40377c478bd9Sstevel@tonic-gate 		case OP_NVERIFY:
40387c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
40397c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opnverify.obj_attributes);
40407c478bd9Sstevel@tonic-gate 			continue;
40417c478bd9Sstevel@tonic-gate 		case OP_OPENATTR:
40427c478bd9Sstevel@tonic-gate 		case OP_OPEN_CONFIRM:
40437c478bd9Sstevel@tonic-gate 		case OP_OPEN_DOWNGRADE:
40447c478bd9Sstevel@tonic-gate 		case OP_PUTPUBFH:
40457c478bd9Sstevel@tonic-gate 		case OP_PUTROOTFH:
40467c478bd9Sstevel@tonic-gate 		case OP_READLINK:
40477c478bd9Sstevel@tonic-gate 			continue;
40487c478bd9Sstevel@tonic-gate 		case OP_RENAME:
40497c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oprename.oldname.
40500a701b1eSRobert Gordon 			    utf8string_val != NULL) {
40517c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oprename.
40520a701b1eSRobert Gordon 				    oldname.utf8string_val,
40530a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.oprename.
40540a701b1eSRobert Gordon 				    oldname.utf8string_len);
40557c478bd9Sstevel@tonic-gate 			}
40567c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oprename.newname.
40570a701b1eSRobert Gordon 			    utf8string_val != NULL) {
40587c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oprename.
40590a701b1eSRobert Gordon 				    newname.utf8string_val,
40600a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.oprename.
40610a701b1eSRobert Gordon 				    newname.utf8string_len);
40627c478bd9Sstevel@tonic-gate 			}
40637c478bd9Sstevel@tonic-gate 			continue;
40647c478bd9Sstevel@tonic-gate 		case OP_RENEW:
40657c478bd9Sstevel@tonic-gate 		case OP_RESTOREFH:
40667c478bd9Sstevel@tonic-gate 		case OP_SAVEFH:
40677c478bd9Sstevel@tonic-gate 			continue;
40687c478bd9Sstevel@tonic-gate 		case OP_SECINFO:
40697c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.opsecinfo.name.
40700a701b1eSRobert Gordon 			    utf8string_val != NULL) {
40717c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.opsecinfo.name.
40720a701b1eSRobert Gordon 				    utf8string_val,
40730a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.opsecinfo.name.
40740a701b1eSRobert Gordon 				    utf8string_len);
40757c478bd9Sstevel@tonic-gate 			}
40767c478bd9Sstevel@tonic-gate 			continue;
40777c478bd9Sstevel@tonic-gate 		case OP_SETATTR:
40787c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
40797c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opsetattr.obj_attributes);
40807c478bd9Sstevel@tonic-gate 			continue;
40817c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID:
40827c478bd9Sstevel@tonic-gate 			(void) xdr_SETCLIENTID4args(xdrs,
40830a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opsetclientid);
40847c478bd9Sstevel@tonic-gate 			continue;
40857c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID_CONFIRM:
40867c478bd9Sstevel@tonic-gate 			continue;
40877c478bd9Sstevel@tonic-gate 		case OP_VERIFY:
40887c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
40890a701b1eSRobert Gordon 			    &array[i].nfs_argop4_u.opverify.obj_attributes);
40907c478bd9Sstevel@tonic-gate 			continue;
40917c478bd9Sstevel@tonic-gate 		case OP_RELEASE_LOCKOWNER:
40927c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oprelease_lockowner.
40930a701b1eSRobert Gordon 			    lock_owner.owner_val != NULL) {
40947c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.
40957c478bd9Sstevel@tonic-gate 				    oprelease_lockowner.lock_owner.owner_val,
40960a701b1eSRobert Gordon 				    array[i].nfs_argop4_u.
40977c478bd9Sstevel@tonic-gate 				    oprelease_lockowner.lock_owner.owner_len);
40987c478bd9Sstevel@tonic-gate 			}
40997c478bd9Sstevel@tonic-gate 			continue;
41007c478bd9Sstevel@tonic-gate 		case OP_ILLEGAL:
41017c478bd9Sstevel@tonic-gate 			continue;
41027c478bd9Sstevel@tonic-gate 		default:
41037c478bd9Sstevel@tonic-gate 			/*
41047c478bd9Sstevel@tonic-gate 			 * An invalid op is a coding error, it should never
41057c478bd9Sstevel@tonic-gate 			 * have been decoded.
41067c478bd9Sstevel@tonic-gate 			 * Don't error because the caller cannot finish
41077c478bd9Sstevel@tonic-gate 			 * freeing the residual memory of the array.
41087c478bd9Sstevel@tonic-gate 			 */
41097c478bd9Sstevel@tonic-gate 			continue;
41107c478bd9Sstevel@tonic-gate 		}
41117c478bd9Sstevel@tonic-gate 	}
41127c478bd9Sstevel@tonic-gate 
41137c478bd9Sstevel@tonic-gate 	kmem_free(*arrayp, len * sizeof (nfs_argop4));
41147c478bd9Sstevel@tonic-gate 	*arrayp = NULL;
41157c478bd9Sstevel@tonic-gate 	return (TRUE);
41167c478bd9Sstevel@tonic-gate }
41177c478bd9Sstevel@tonic-gate 
41187c478bd9Sstevel@tonic-gate static bool_t
41197c478bd9Sstevel@tonic-gate xdr_nfs_argop4(XDR *xdrs, nfs_argop4 *objp)
41207c478bd9Sstevel@tonic-gate {
41210a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
41220a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
41230a701b1eSRobert Gordon 
41247c478bd9Sstevel@tonic-gate 	/*
41257c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
41267c478bd9Sstevel@tonic-gate 	 */
41277c478bd9Sstevel@tonic-gate 	switch (objp->argop) {
41287c478bd9Sstevel@tonic-gate 	case OP_PUTFH:
41297c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
41307c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_val,
41317c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_len,
41327c478bd9Sstevel@tonic-gate 		    NFS4_FHSIZE));
41337c478bd9Sstevel@tonic-gate 	case OP_GETATTR:
41348ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		/*
41358ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 * ACLs can become relatively large ( > 8K) and the default
41368ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 * 8K reply chunk of RDMA may not suffice. Check for
41378ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 * get ACL bit and if it's RDMA, add a chunk equal the size
41388ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 * of the transfer size to the reply chunk list.
41398ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 */
41408ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
41418ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		    (xdrs->x_op == XDR_ENCODE) &&
41428ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		    (objp->nfs_argop4_u.opgetattr.attr_request &
41438ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		    FATTR4_ACL_MASK)) {
41448ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			rci.rci_type = RCI_REPLY_CHUNK;
41458ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			rci.rci_len = objp->nfs_argop4_u.opgetattr.mi->mi_tsize;
41468ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
41478ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 
41488ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			DTRACE_PROBE1(xdr__i__argop4__getattr, int,
41498ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			    rci.rci_len);
41508ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		}
41517c478bd9Sstevel@tonic-gate 		return (xdr_bitmap4(xdrs,
41520a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opgetattr.attr_request));
41537c478bd9Sstevel@tonic-gate 	case OP_GETFH:
41547c478bd9Sstevel@tonic-gate 		return (TRUE);
41557c478bd9Sstevel@tonic-gate 	case OP_LOOKUP:
41567c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oplookup.
41570a701b1eSRobert Gordon 		    objname.utf8string_val,
41580a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.oplookup.
41590a701b1eSRobert Gordon 		    objname.utf8string_len,
41600a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
41617c478bd9Sstevel@tonic-gate 	case OP_OPEN:
41627c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4args(xdrs, &objp->nfs_argop4_u.opopen));
41637c478bd9Sstevel@tonic-gate 	case OP_CLOSE:
41647c478bd9Sstevel@tonic-gate 		return (xdr_CLOSE4args(xdrs, &objp->nfs_argop4_u.opclose));
41657c478bd9Sstevel@tonic-gate 	case OP_ACCESS:
41667c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs,
41670a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opaccess.access));
41687c478bd9Sstevel@tonic-gate 	case OP_READ:
41697c478bd9Sstevel@tonic-gate 		return (xdr_READ4args(xdrs, &objp->nfs_argop4_u.opread));
41707c478bd9Sstevel@tonic-gate 	case OP_WRITE:
41717c478bd9Sstevel@tonic-gate 		return (xdr_WRITE4args(xdrs, &objp->nfs_argop4_u.opwrite));
41727c478bd9Sstevel@tonic-gate 	case OP_DELEGRETURN:
41737c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs,
41747c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opdelegreturn.deleg_stateid.seqid))
41757c478bd9Sstevel@tonic-gate 			return (FALSE);
41767c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs,
41777c478bd9Sstevel@tonic-gate 		    objp->nfs_argop4_u.opdelegreturn.deleg_stateid.other, 12));
41787c478bd9Sstevel@tonic-gate 	case OP_LOOKUPP:
41797c478bd9Sstevel@tonic-gate 		return (TRUE);
41807c478bd9Sstevel@tonic-gate 	case OP_READDIR:
41817c478bd9Sstevel@tonic-gate 		return (xdr_READDIR4args(xdrs, &objp->nfs_argop4_u.opreaddir));
41827c478bd9Sstevel@tonic-gate 	case OP_REMOVE:
41837c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.opremove.
41840a701b1eSRobert Gordon 		    target.utf8string_val,
41850a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.opremove.
41860a701b1eSRobert Gordon 		    target.utf8string_len,
41870a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
41887c478bd9Sstevel@tonic-gate 	case OP_COMMIT:
41897c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
41907c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_argop4_u.opcommit.offset))
41917c478bd9Sstevel@tonic-gate 			return (FALSE);
41927c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opcommit.count));
41937c478bd9Sstevel@tonic-gate 	case OP_CREATE:
41947c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4args(xdrs, &objp->nfs_argop4_u.opcreate));
41957c478bd9Sstevel@tonic-gate 	case OP_DELEGPURGE:
41967c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
41977c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_argop4_u.opdelegpurge.clientid));
41987c478bd9Sstevel@tonic-gate 	case OP_LINK:
41997c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
42007c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.oplink.newname.utf8string_val,
42017c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.oplink.newname.utf8string_len,
42027c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
42037c478bd9Sstevel@tonic-gate 	case OP_LOCK:
42047c478bd9Sstevel@tonic-gate 		return (xdr_LOCK4args(xdrs, &objp->nfs_argop4_u.oplock));
42057c478bd9Sstevel@tonic-gate 	case OP_LOCKT:
42067c478bd9Sstevel@tonic-gate 		return (xdr_LOCKT4args(xdrs, &objp->nfs_argop4_u.oplockt));
42077c478bd9Sstevel@tonic-gate 	case OP_LOCKU:
42087c478bd9Sstevel@tonic-gate 		return (xdr_LOCKU4args(xdrs, &objp->nfs_argop4_u.oplocku));
42097c478bd9Sstevel@tonic-gate 	case OP_NVERIFY:
42107c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
42110a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opnverify.obj_attributes));
42127c478bd9Sstevel@tonic-gate 	case OP_OPENATTR:
42137c478bd9Sstevel@tonic-gate 		return (xdr_bool(xdrs,
42140a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opopenattr.createdir));
42157c478bd9Sstevel@tonic-gate 	case OP_OPEN_CONFIRM:
42167c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
42170a701b1eSRobert Gordon 		    open_stateid.seqid))
42187c478bd9Sstevel@tonic-gate 			return (FALSE);
42197c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opopen_confirm.
42200a701b1eSRobert Gordon 		    open_stateid.other, 12))
42217c478bd9Sstevel@tonic-gate 			return (FALSE);
42227c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
42230a701b1eSRobert Gordon 		    seqid));
42247c478bd9Sstevel@tonic-gate 	case OP_OPEN_DOWNGRADE:
42257c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_DOWNGRADE4args(xdrs,
42260a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opopen_downgrade));
42277c478bd9Sstevel@tonic-gate 	case OP_PUTPUBFH:
42287c478bd9Sstevel@tonic-gate 		return (TRUE);
42297c478bd9Sstevel@tonic-gate 	case OP_PUTROOTFH:
42307c478bd9Sstevel@tonic-gate 		return (TRUE);
42317c478bd9Sstevel@tonic-gate 	case OP_READLINK:
42320a701b1eSRobert Gordon 		if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
42330a701b1eSRobert Gordon 		    xdrs->x_op == XDR_ENCODE) {
42340a701b1eSRobert Gordon 			rci.rci_type = RCI_REPLY_CHUNK;
42350a701b1eSRobert Gordon 			rci.rci_len = MAXPATHLEN;
42360a701b1eSRobert Gordon 			XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
42370a701b1eSRobert Gordon 		}
42387c478bd9Sstevel@tonic-gate 		return (TRUE);
42397c478bd9Sstevel@tonic-gate 	case OP_RENAME:
42407c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
42410a701b1eSRobert Gordon 		    oldname.utf8string_val,
42420a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.oprename.
42430a701b1eSRobert Gordon 		    oldname.utf8string_len,
42440a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING))
42457c478bd9Sstevel@tonic-gate 			return (FALSE);
42467c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
42470a701b1eSRobert Gordon 		    newname.utf8string_val,
42480a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.oprename.
42490a701b1eSRobert Gordon 		    newname.utf8string_len,
42500a701b1eSRobert Gordon 		    NFS4_MAX_UTF8STRING));
42517c478bd9Sstevel@tonic-gate 	case OP_RENEW:
42527c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
42530a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_argop4_u.oprenew.clientid));
42547c478bd9Sstevel@tonic-gate 	case OP_RESTOREFH:
42557c478bd9Sstevel@tonic-gate 		return (TRUE);
42567c478bd9Sstevel@tonic-gate 	case OP_SAVEFH:
42577c478bd9Sstevel@tonic-gate 		return (TRUE);
42587c478bd9Sstevel@tonic-gate 	case OP_SECINFO:
42597c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
42607c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.opsecinfo.name.utf8string_val,
42617c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.opsecinfo.name.utf8string_len,
42627c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
42637c478bd9Sstevel@tonic-gate 	case OP_SETATTR:
42647c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opsetattr.
42650a701b1eSRobert Gordon 		    stateid.seqid))
42667c478bd9Sstevel@tonic-gate 			return (FALSE);
42677c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opsetattr.
42680a701b1eSRobert Gordon 		    stateid.other, 12))
42697c478bd9Sstevel@tonic-gate 			return (FALSE);
42707c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs, &objp->nfs_argop4_u.opsetattr.
42710a701b1eSRobert Gordon 		    obj_attributes));
42727c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID:
42737c478bd9Sstevel@tonic-gate 		return (xdr_SETCLIENTID4args(xdrs,
42740a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opsetclientid));
42757c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID_CONFIRM:
42767c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->nfs_argop4_u.
42770a701b1eSRobert Gordon 		    opsetclientid_confirm.clientid))
42787c478bd9Sstevel@tonic-gate 			return (FALSE);
42797c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
42800a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_argop4_u.
42810a701b1eSRobert Gordon 		    opsetclientid_confirm.setclientid_confirm));
42827c478bd9Sstevel@tonic-gate 	case OP_VERIFY:
42837c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
42840a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opverify.obj_attributes));
42857c478bd9Sstevel@tonic-gate 	case OP_RELEASE_LOCKOWNER:
42867c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
42870a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_argop4_u.
42880a701b1eSRobert Gordon 		    oprelease_lockowner.lock_owner.clientid))
42897c478bd9Sstevel@tonic-gate 			return (FALSE);
42907c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
42910a701b1eSRobert Gordon 		    (char **)&objp->nfs_argop4_u.oprelease_lockowner.
42920a701b1eSRobert Gordon 		    lock_owner.owner_val,
42930a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_argop4_u.oprelease_lockowner.
42940a701b1eSRobert Gordon 		    lock_owner.owner_len, NFS4_OPAQUE_LIMIT));
42957c478bd9Sstevel@tonic-gate 	case OP_ILLEGAL:
42967c478bd9Sstevel@tonic-gate 		return (TRUE);
42977c478bd9Sstevel@tonic-gate 	}
42987c478bd9Sstevel@tonic-gate 	return (FALSE);
42997c478bd9Sstevel@tonic-gate }
43007c478bd9Sstevel@tonic-gate 
43017c46fb7fSek static bool_t
43027c46fb7fSek xdr_cnfs_argop4_wrap(XDR *xdrs, nfs_argop4 *objp)
43037c46fb7fSek {
43047c46fb7fSek 	if (!xdr_int(xdrs, (int *)&objp->argop))
43057c46fb7fSek 		return (FALSE);
43067c46fb7fSek 
43077c46fb7fSek 	return (xdr_nfs_argop4(xdrs, objp));
43087c46fb7fSek }
43097c46fb7fSek 
43107c46fb7fSek static bool_t
43117c46fb7fSek xdr_snfs_argop4(XDR *xdrs, nfs_argop4 *objp)
43127c46fb7fSek {
43137c46fb7fSek 	if (!xdr_int(xdrs, (int *)&objp->argop))
43147c46fb7fSek 		return (FALSE);
43157c46fb7fSek 
43167c46fb7fSek 	switch (objp->argop) {
43177c46fb7fSek 	case OP_PUTFH:
43187c46fb7fSek 		return (xdr_decode_nfs_fh4(xdrs,
43190a701b1eSRobert Gordon 		    &objp->nfs_argop4_u.opputfh.object));
43207c46fb7fSek 	default:
43217c46fb7fSek 		return (xdr_nfs_argop4(xdrs, objp));
43227c46fb7fSek 	}
43237c46fb7fSek }
43247c46fb7fSek 
43257c478bd9Sstevel@tonic-gate /*
43267c478bd9Sstevel@tonic-gate  * Client side encode only arg op processing
43277c478bd9Sstevel@tonic-gate  */
43287c478bd9Sstevel@tonic-gate static bool_t
43297c478bd9Sstevel@tonic-gate xdr_cnfs_argop4(XDR *xdrs, nfs_argop4 *objp)
43307c478bd9Sstevel@tonic-gate {
43317c478bd9Sstevel@tonic-gate 	int len;
43327c478bd9Sstevel@tonic-gate 	int op;
43337c478bd9Sstevel@tonic-gate 	nfs4_sharedfh_t *sfh;
43347c478bd9Sstevel@tonic-gate 	mntinfo4_t *mi;
43357c478bd9Sstevel@tonic-gate 	rpc_inline_t *ptr;
43367c478bd9Sstevel@tonic-gate 
43377c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
43387c478bd9Sstevel@tonic-gate 
43397c478bd9Sstevel@tonic-gate 	/*
43407c478bd9Sstevel@tonic-gate 	 * Special case the private pseudo ops
43417c478bd9Sstevel@tonic-gate 	 */
43427c478bd9Sstevel@tonic-gate 	if (!(objp->argop & SUNW_PRIVATE_OP))
43437c46fb7fSek 		return (xdr_cnfs_argop4_wrap(xdrs, objp));
43447c478bd9Sstevel@tonic-gate 
43457c478bd9Sstevel@tonic-gate 	/*
43467c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
43477c478bd9Sstevel@tonic-gate 	 */
43487c478bd9Sstevel@tonic-gate 	switch (objp->argop) {
43497c478bd9Sstevel@tonic-gate 	case OP_CPUTFH:
43507c478bd9Sstevel@tonic-gate 		/*
43517c478bd9Sstevel@tonic-gate 		 * We are passed in the file handle as a nfs4_sharedfh_t *
43527c478bd9Sstevel@tonic-gate 		 * We need to acquire the correct locks so we can copy it out.
43537c478bd9Sstevel@tonic-gate 		 */
43547c478bd9Sstevel@tonic-gate 		sfh = (nfs4_sharedfh_t *)objp->nfs_argop4_u.opcputfh.sfh;
43557c478bd9Sstevel@tonic-gate 		mi = sfh->sfh_mi;
43567c478bd9Sstevel@tonic-gate 		(void) nfs_rw_enter_sig(&mi->mi_fh_lock, RW_READER, 0);
43577c478bd9Sstevel@tonic-gate 
43587c478bd9Sstevel@tonic-gate 		len = sfh->sfh_fh.nfs_fh4_len;
43597c478bd9Sstevel@tonic-gate 		ASSERT(len <= NFS4_FHSIZE);
43607c478bd9Sstevel@tonic-gate 
43617c478bd9Sstevel@tonic-gate 		/*
43627c478bd9Sstevel@tonic-gate 		 * First try and inline the copy
43637c478bd9Sstevel@tonic-gate 		 * Must first be a multiple of BYTES_PER_XDR_UNIT
43647c478bd9Sstevel@tonic-gate 		 */
43657c478bd9Sstevel@tonic-gate 		if (!(len % BYTES_PER_XDR_UNIT) &&
43667c478bd9Sstevel@tonic-gate 		    (ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + len)) !=
43670a701b1eSRobert Gordon 		    NULL) {
43687c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, OP_PUTFH);
43697c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, len);
43707c478bd9Sstevel@tonic-gate 			bcopy(sfh->sfh_fh.nfs_fh4_val, ptr, len);
43717c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
43727c478bd9Sstevel@tonic-gate 			return (TRUE);
43737c478bd9Sstevel@tonic-gate 		}
43747c478bd9Sstevel@tonic-gate 
43757c478bd9Sstevel@tonic-gate 		op = OP_PUTFH;
43767c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &op)) {
43777c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
43787c478bd9Sstevel@tonic-gate 			return (FALSE);
43797c478bd9Sstevel@tonic-gate 		}
43807c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len)) {
43817c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
43827c478bd9Sstevel@tonic-gate 			return (FALSE);
43837c478bd9Sstevel@tonic-gate 		}
43847c478bd9Sstevel@tonic-gate 		if (!(len % BYTES_PER_XDR_UNIT)) {
43857c478bd9Sstevel@tonic-gate 			if (XDR_PUTBYTES(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
43867c478bd9Sstevel@tonic-gate 				nfs_rw_exit(&mi->mi_fh_lock);
43877c478bd9Sstevel@tonic-gate 				return (TRUE);
43887c478bd9Sstevel@tonic-gate 			}
43897c478bd9Sstevel@tonic-gate 		} else if (xdr_opaque(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
43907c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
43917c478bd9Sstevel@tonic-gate 			return (TRUE);
43927c478bd9Sstevel@tonic-gate 		}
43937c478bd9Sstevel@tonic-gate 		nfs_rw_exit(&mi->mi_fh_lock);
43947c478bd9Sstevel@tonic-gate 		return (FALSE);
43957c478bd9Sstevel@tonic-gate 	case OP_CLOOKUP:
43967c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opclookup.cname);
43977c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
43987c478bd9Sstevel@tonic-gate 			return (FALSE);
43997c478bd9Sstevel@tonic-gate 		op = OP_LOOKUP;
44007c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
44017c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
44027c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
44030a701b1eSRobert Gordon 				    objp->nfs_argop4_u.opclookup.cname,
44040a701b1eSRobert Gordon 				    len));
44057c478bd9Sstevel@tonic-gate 			}
44067c478bd9Sstevel@tonic-gate 		}
44077c478bd9Sstevel@tonic-gate 		return (FALSE);
44087c478bd9Sstevel@tonic-gate 	case OP_COPEN:
44097c478bd9Sstevel@tonic-gate 		/* op processing inlined in xdr_OPEN4cargs */
44107c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4cargs(xdrs, &objp->nfs_argop4_u.opcopen));
44117c478bd9Sstevel@tonic-gate 	case OP_CREMOVE:
44127c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcremove.ctarget);
44137c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44147c478bd9Sstevel@tonic-gate 			return (FALSE);
44157c478bd9Sstevel@tonic-gate 		op = OP_REMOVE;
44167c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
44177c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
44187c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
44190a701b1eSRobert Gordon 				    objp->nfs_argop4_u.opcremove.ctarget,
44200a701b1eSRobert Gordon 				    len));
44217c478bd9Sstevel@tonic-gate 			}
44227c478bd9Sstevel@tonic-gate 		}
44237c478bd9Sstevel@tonic-gate 		return (FALSE);
44247c478bd9Sstevel@tonic-gate 	case OP_CCREATE:
44257c478bd9Sstevel@tonic-gate 		op = OP_CREATE;
44267c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &op))
44277c478bd9Sstevel@tonic-gate 			return (FALSE);
44287c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4cargs(xdrs, &objp->nfs_argop4_u.opccreate));
44297c478bd9Sstevel@tonic-gate 	case OP_CLINK:
44307c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opclink.cnewname);
44317c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44327c478bd9Sstevel@tonic-gate 			return (FALSE);
44337c478bd9Sstevel@tonic-gate 		op = OP_LINK;
44347c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
44357c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
44367c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
44370a701b1eSRobert Gordon 				    objp->nfs_argop4_u.opclink.cnewname,
44380a701b1eSRobert Gordon 				    len));
44397c478bd9Sstevel@tonic-gate 			}
44407c478bd9Sstevel@tonic-gate 		}
44417c478bd9Sstevel@tonic-gate 		return (FALSE);
44427c478bd9Sstevel@tonic-gate 	case OP_CRENAME:
44437c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcrename.coldname);
44447c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44457c478bd9Sstevel@tonic-gate 			return (FALSE);
44467c478bd9Sstevel@tonic-gate 		op = OP_RENAME;
44477c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &op))
44487c478bd9Sstevel@tonic-gate 			return (FALSE);
44497c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len))
44507c478bd9Sstevel@tonic-gate 			return (FALSE);
44517c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs,
44520a701b1eSRobert Gordon 		    objp->nfs_argop4_u.opcrename.coldname, len))
44537c478bd9Sstevel@tonic-gate 			return (FALSE);
44547c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcrename.cnewname);
44557c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44567c478bd9Sstevel@tonic-gate 			return (FALSE);
44577c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
44587c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
44590a701b1eSRobert Gordon 			    objp->nfs_argop4_u.opcrename.cnewname, len));
44607c478bd9Sstevel@tonic-gate 		}
44617c478bd9Sstevel@tonic-gate 		return (FALSE);
44627c478bd9Sstevel@tonic-gate 	case OP_CSECINFO:
44637c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcsecinfo.cname);
44647c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44657c478bd9Sstevel@tonic-gate 			return (FALSE);
44667c478bd9Sstevel@tonic-gate 		op = OP_SECINFO;
44677c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
44687c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
44697c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
44700a701b1eSRobert Gordon 				    objp->nfs_argop4_u.opcsecinfo.cname,
44710a701b1eSRobert Gordon 				    len));
44727c478bd9Sstevel@tonic-gate 			}
44737c478bd9Sstevel@tonic-gate 		}
44747c478bd9Sstevel@tonic-gate 		return (FALSE);
44757c478bd9Sstevel@tonic-gate 	}
44767c478bd9Sstevel@tonic-gate 	return (FALSE);
44777c478bd9Sstevel@tonic-gate }
44787c478bd9Sstevel@tonic-gate 
44797c478bd9Sstevel@tonic-gate /*
44807c478bd9Sstevel@tonic-gate  * Note that the len and decode_len will only be different in the case
44817c478bd9Sstevel@tonic-gate  * of the client's use of this free function.  If the server is
44827c478bd9Sstevel@tonic-gate  * freeing results, then the len/decode_len will always match.
44837c478bd9Sstevel@tonic-gate  */
44847c478bd9Sstevel@tonic-gate static bool_t
44857c478bd9Sstevel@tonic-gate xdr_nfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
44867c478bd9Sstevel@tonic-gate {
44877c478bd9Sstevel@tonic-gate 	int i;
44887c478bd9Sstevel@tonic-gate 	nfs_resop4 *array = *arrayp;
44892f172c55SRobert Thurlow 	nfs4_ga_res_t *gr;
44907c478bd9Sstevel@tonic-gate 
44917c478bd9Sstevel@tonic-gate 	/*
44927c478bd9Sstevel@tonic-gate 	 * Optimized XDR_FREE only results array
44937c478bd9Sstevel@tonic-gate 	 */
44947c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_FREE);
44957c478bd9Sstevel@tonic-gate 
44967c478bd9Sstevel@tonic-gate 	if (array == NULL)
44977c478bd9Sstevel@tonic-gate 		return (TRUE);
44987c478bd9Sstevel@tonic-gate 
44997c478bd9Sstevel@tonic-gate 	for (i = 0; i < decode_len; i++) {
45007c478bd9Sstevel@tonic-gate 		/*
45017c478bd9Sstevel@tonic-gate 		 * These should be ordered by frequency of use
45027c478bd9Sstevel@tonic-gate 		 */
45037c478bd9Sstevel@tonic-gate 		switch (array[i].resop) {
45047c478bd9Sstevel@tonic-gate 		case OP_PUTFH:
45057c478bd9Sstevel@tonic-gate 			continue;
45067c478bd9Sstevel@tonic-gate 		case OP_GETATTR:
45077c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetattr.status != NFS4_OK)
45087c478bd9Sstevel@tonic-gate 				continue;
45092f172c55SRobert Thurlow 
45102f172c55SRobert Thurlow 			gr = &array[i].nfs_resop4_u.opgetattr.ga_res;
45112f172c55SRobert Thurlow 			if (gr->n4g_ext_res) {
45122f172c55SRobert Thurlow 				if (gr->n4g_resbmap & FATTR4_FS_LOCATIONS_MASK)
45132f172c55SRobert Thurlow 					(void) xdr_fattr4_fs_locations(xdrs,
45142f172c55SRobert Thurlow 					    &gr->n4g_ext_res->n4g_fslocations);
45152f172c55SRobert Thurlow 				kmem_free(gr->n4g_ext_res,
45160a701b1eSRobert Gordon 				    sizeof (struct nfs4_ga_ext_res));
45172f172c55SRobert Thurlow 			}
45187c478bd9Sstevel@tonic-gate 			continue;
45197c478bd9Sstevel@tonic-gate 		case OP_GETFH:
45207c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetfh.status != NFS4_OK)
45217c478bd9Sstevel@tonic-gate 				continue;
45227c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetfh.object.nfs_fh4_val !=
45230a701b1eSRobert Gordon 			    NULL) {
45247c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_resop4_u.opgetfh.object.
45250a701b1eSRobert Gordon 				    nfs_fh4_val,
45260a701b1eSRobert Gordon 				    array[i].nfs_resop4_u.opgetfh.object.
45270a701b1eSRobert Gordon 				    nfs_fh4_len);
45287c478bd9Sstevel@tonic-gate 			}
45297c478bd9Sstevel@tonic-gate 			continue;
45307c478bd9Sstevel@tonic-gate 		case OP_LOOKUP:
45317c478bd9Sstevel@tonic-gate 			continue;
45327c478bd9Sstevel@tonic-gate 		case OP_OPEN:
45337c478bd9Sstevel@tonic-gate 			(void) xdr_OPEN4res(xdrs, &array[i].nfs_resop4_u.
45340a701b1eSRobert Gordon 			    opopen);
45357c478bd9Sstevel@tonic-gate 			continue;
45367c478bd9Sstevel@tonic-gate 		case OP_CLOSE:
45377c478bd9Sstevel@tonic-gate 		case OP_ACCESS:
45387c478bd9Sstevel@tonic-gate 			continue;
45397c478bd9Sstevel@tonic-gate 		case OP_READ:
45407c478bd9Sstevel@tonic-gate 			(void) xdr_READ4res(xdrs,
45410a701b1eSRobert Gordon 			    &array[i].nfs_resop4_u.opread);
45427c478bd9Sstevel@tonic-gate 			continue;
45437c478bd9Sstevel@tonic-gate 		case OP_WRITE:
45447c478bd9Sstevel@tonic-gate 		case OP_DELEGRETURN:
45457c478bd9Sstevel@tonic-gate 		case OP_LOOKUPP:
45467c478bd9Sstevel@tonic-gate 		case OP_READDIR:
45477c478bd9Sstevel@tonic-gate 		case OP_REMOVE:
45487c478bd9Sstevel@tonic-gate 		case OP_COMMIT:
45497c478bd9Sstevel@tonic-gate 		case OP_CREATE:
45507c478bd9Sstevel@tonic-gate 		case OP_DELEGPURGE:
45517c478bd9Sstevel@tonic-gate 		case OP_LINK:
45527c478bd9Sstevel@tonic-gate 			continue;
45537c478bd9Sstevel@tonic-gate 		case OP_LOCK:
45547c478bd9Sstevel@tonic-gate 			(void) xdr_LOCK4res(xdrs, &array[i].nfs_resop4_u.
45550a701b1eSRobert Gordon 			    oplock);
45567c478bd9Sstevel@tonic-gate 			continue;
45577c478bd9Sstevel@tonic-gate 		case OP_LOCKT:
45587c478bd9Sstevel@tonic-gate 			(void) xdr_LOCKT4res(xdrs, &array[i].nfs_resop4_u.
45590a701b1eSRobert Gordon 			    oplockt);
45607c478bd9Sstevel@tonic-gate 			continue;
45617c478bd9Sstevel@tonic-gate 		case OP_LOCKU:
45627c478bd9Sstevel@tonic-gate 		case OP_NVERIFY:
45637c478bd9Sstevel@tonic-gate 		case OP_OPENATTR:
45647c478bd9Sstevel@tonic-gate 		case OP_OPEN_CONFIRM:
45657c478bd9Sstevel@tonic-gate 		case OP_OPEN_DOWNGRADE:
45667c478bd9Sstevel@tonic-gate 		case OP_PUTPUBFH:
45677c478bd9Sstevel@tonic-gate 		case OP_PUTROOTFH:
45687c478bd9Sstevel@tonic-gate 		case OP_RENAME:
45697c478bd9Sstevel@tonic-gate 		case OP_RENEW:
45707c478bd9Sstevel@tonic-gate 		case OP_RESTOREFH:
45717c478bd9Sstevel@tonic-gate 		case OP_SAVEFH:
45727c478bd9Sstevel@tonic-gate 			continue;
45737c478bd9Sstevel@tonic-gate 		case OP_READLINK:
45747c478bd9Sstevel@tonic-gate 			(void) xdr_READLINK4res(xdrs, &array[i].nfs_resop4_u.
45750a701b1eSRobert Gordon 			    opreadlink);
45767c478bd9Sstevel@tonic-gate 			continue;
45777c478bd9Sstevel@tonic-gate 		case OP_SECINFO:
45787c478bd9Sstevel@tonic-gate 			(void) xdr_array(xdrs,
45790a701b1eSRobert Gordon 			    (char **)&array[i].nfs_resop4_u.opsecinfo.
45800a701b1eSRobert Gordon 			    SECINFO4resok_val,
45810a701b1eSRobert Gordon 			    (uint_t *)&array[i].nfs_resop4_u.opsecinfo.
45820a701b1eSRobert Gordon 			    SECINFO4resok_len,
45830a701b1eSRobert Gordon 			    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
45840a701b1eSRobert Gordon 			    (xdrproc_t)xdr_secinfo4);
45857c478bd9Sstevel@tonic-gate 			continue;
45867c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID:
45877c478bd9Sstevel@tonic-gate 			(void) xdr_SETCLIENTID4res(xdrs,
45880a701b1eSRobert Gordon 			    &array[i].nfs_resop4_u.opsetclientid);
45897c478bd9Sstevel@tonic-gate 			continue;
45907c478bd9Sstevel@tonic-gate 		case OP_SETATTR:
45917c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID_CONFIRM:
45927c478bd9Sstevel@tonic-gate 		case OP_VERIFY:
45937c478bd9Sstevel@tonic-gate 		case OP_RELEASE_LOCKOWNER:
45947c478bd9Sstevel@tonic-gate 		case OP_ILLEGAL:
45957c478bd9Sstevel@tonic-gate 			continue;
45967c478bd9Sstevel@tonic-gate 		default:
45977c478bd9Sstevel@tonic-gate 			/*
45987c478bd9Sstevel@tonic-gate 			 * An invalid op is a coding error, it should never
45997c478bd9Sstevel@tonic-gate 			 * have been decoded.
46007c478bd9Sstevel@tonic-gate 			 * Don't error because the caller cannot finish
46017c478bd9Sstevel@tonic-gate 			 * freeing the residual memory of the array.
46027c478bd9Sstevel@tonic-gate 			 */
46037c478bd9Sstevel@tonic-gate 			continue;
46047c478bd9Sstevel@tonic-gate 		}
46057c478bd9Sstevel@tonic-gate 	}
46067c478bd9Sstevel@tonic-gate 
46077c478bd9Sstevel@tonic-gate 	kmem_free(*arrayp, len * sizeof (nfs_resop4));
46087c478bd9Sstevel@tonic-gate 	*arrayp = NULL;
46097c478bd9Sstevel@tonic-gate 	return (TRUE);
46107c478bd9Sstevel@tonic-gate }
46117c478bd9Sstevel@tonic-gate 
46127c46fb7fSek static bool_t
46137c46fb7fSek xdr_snfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
46147c46fb7fSek {
46157c46fb7fSek 	return (xdr_nfs_resop4_free(xdrs, arrayp, len, decode_len));
46167c46fb7fSek }
46177c46fb7fSek 
46187c478bd9Sstevel@tonic-gate static bool_t
46197c478bd9Sstevel@tonic-gate xdr_nfs_resop4(XDR *xdrs, nfs_resop4 *objp)
46207c478bd9Sstevel@tonic-gate {
46217c478bd9Sstevel@tonic-gate 	/*
46227c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
46237c478bd9Sstevel@tonic-gate 	 */
46247c478bd9Sstevel@tonic-gate 	switch (objp->resop) {
46257c478bd9Sstevel@tonic-gate 	case OP_PUTFH:
46267c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46270a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
46287c478bd9Sstevel@tonic-gate 	case OP_GETATTR:
46297c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
46300a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
46317c478bd9Sstevel@tonic-gate 			return (FALSE);
46327c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
46337c478bd9Sstevel@tonic-gate 			return (TRUE);
46347c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
46350a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opgetattr.obj_attributes));
46367c478bd9Sstevel@tonic-gate 	case OP_GETFH:
46377c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
46380a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
46397c478bd9Sstevel@tonic-gate 			return (FALSE);
46407c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
46417c478bd9Sstevel@tonic-gate 			return (TRUE);
46427c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
46437c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
46447c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
46457c478bd9Sstevel@tonic-gate 		    NFS4_FHSIZE));
46467c478bd9Sstevel@tonic-gate 	case OP_LOOKUP:
46477c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46480a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
46497c478bd9Sstevel@tonic-gate 	case OP_OPEN:
46507c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
46517c478bd9Sstevel@tonic-gate 	case OP_CLOSE:
46527c478bd9Sstevel@tonic-gate 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
46537c478bd9Sstevel@tonic-gate 	case OP_ACCESS:
46547c478bd9Sstevel@tonic-gate 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
46557c478bd9Sstevel@tonic-gate 	case OP_READ:
46567c478bd9Sstevel@tonic-gate 		return (xdr_READ4res(xdrs, &objp->nfs_resop4_u.opread));
46577c478bd9Sstevel@tonic-gate 	case OP_WRITE:
46587c478bd9Sstevel@tonic-gate 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
46597c478bd9Sstevel@tonic-gate 	case OP_DELEGRETURN:
46607c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46610a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
46627c478bd9Sstevel@tonic-gate 	case OP_LOOKUPP:
46637c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46640a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
46657c478bd9Sstevel@tonic-gate 	case OP_READDIR:
46667c478bd9Sstevel@tonic-gate 		return (xdr_READDIR4res(xdrs, &objp->nfs_resop4_u.opreaddir));
46677c478bd9Sstevel@tonic-gate 	case OP_REMOVE:
46687c478bd9Sstevel@tonic-gate 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
46697c478bd9Sstevel@tonic-gate 
46707c478bd9Sstevel@tonic-gate 	case OP_COMMIT:
46717c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
46720a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
46737c478bd9Sstevel@tonic-gate 			return (FALSE);
46747c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
46757c478bd9Sstevel@tonic-gate 			return (TRUE);
46767c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
46770a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
46780a701b1eSRobert Gordon 		    writeverf));
46797c478bd9Sstevel@tonic-gate 	case OP_CREATE:
46807c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
46817c478bd9Sstevel@tonic-gate 	case OP_DELEGPURGE:
46827c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46830a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
46847c478bd9Sstevel@tonic-gate 	case OP_LINK:
46857c478bd9Sstevel@tonic-gate 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
46867c478bd9Sstevel@tonic-gate 	case OP_LOCK:
46877c478bd9Sstevel@tonic-gate 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
46887c478bd9Sstevel@tonic-gate 	case OP_LOCKT:
46897c478bd9Sstevel@tonic-gate 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
46907c478bd9Sstevel@tonic-gate 	case OP_LOCKU:
46917c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
46920a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
46937c478bd9Sstevel@tonic-gate 			return (FALSE);
46947c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
46957c478bd9Sstevel@tonic-gate 			return (TRUE);
46967c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs,
46977c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
46987c478bd9Sstevel@tonic-gate 			return (FALSE);
46997c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs,
47007c478bd9Sstevel@tonic-gate 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
47017c478bd9Sstevel@tonic-gate 		    12));
47027c478bd9Sstevel@tonic-gate 	case OP_NVERIFY:
47037c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47040a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
47057c478bd9Sstevel@tonic-gate 	case OP_OPENATTR:
47067c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47070a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
47087c478bd9Sstevel@tonic-gate 	case OP_OPEN_CONFIRM:
47097c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_CONFIRM4res(xdrs,
47100a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opopen_confirm));
47117c478bd9Sstevel@tonic-gate 	case OP_OPEN_DOWNGRADE:
47127c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
47130a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opopen_downgrade));
47147c478bd9Sstevel@tonic-gate 	case OP_PUTPUBFH:
47157c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47160a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
47177c478bd9Sstevel@tonic-gate 	case OP_PUTROOTFH:
47187c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47190a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
47207c478bd9Sstevel@tonic-gate 	case OP_READLINK:
47217c478bd9Sstevel@tonic-gate 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
47227c478bd9Sstevel@tonic-gate 	case OP_RENAME:
47237c478bd9Sstevel@tonic-gate 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
47247c478bd9Sstevel@tonic-gate 	case OP_RENEW:
47257c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47260a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
47277c478bd9Sstevel@tonic-gate 	case OP_RESTOREFH:
47287c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47290a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
47307c478bd9Sstevel@tonic-gate 	case OP_SAVEFH:
47317c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47320a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
47337c478bd9Sstevel@tonic-gate 	case OP_SECINFO:
47347c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
47350a701b1eSRobert Gordon 		    status))
47367c478bd9Sstevel@tonic-gate 			return (FALSE);
47377c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
47387c478bd9Sstevel@tonic-gate 			return (TRUE);
47397c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
47400a701b1eSRobert Gordon 		    SECINFO4resok_val,
47410a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
47420a701b1eSRobert Gordon 		    SECINFO4resok_len,
47430a701b1eSRobert Gordon 		    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
47440a701b1eSRobert Gordon 		    (xdrproc_t)xdr_secinfo4));
47457c478bd9Sstevel@tonic-gate 	case OP_SETATTR:
47467c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
47470a701b1eSRobert Gordon 		    status))
47487c478bd9Sstevel@tonic-gate 			return (FALSE);
47497c478bd9Sstevel@tonic-gate 		return (xdr_bitmap4(xdrs,
47500a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opsetattr.attrsset));
47517c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID:
47527c478bd9Sstevel@tonic-gate 		return (xdr_SETCLIENTID4res(xdrs,
47530a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opsetclientid));
47547c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID_CONFIRM:
47557c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47560a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
47570a701b1eSRobert Gordon 		    status));
47587c478bd9Sstevel@tonic-gate 	case OP_VERIFY:
47597c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47600a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
47617c478bd9Sstevel@tonic-gate 	case OP_RELEASE_LOCKOWNER:
47627c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47637c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
47647c478bd9Sstevel@tonic-gate 	case OP_ILLEGAL:
47657c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47660a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
47677c478bd9Sstevel@tonic-gate 	}
47687c478bd9Sstevel@tonic-gate 	return (FALSE);
47697c478bd9Sstevel@tonic-gate }
47707c478bd9Sstevel@tonic-gate 
47717c46fb7fSek static bool_t
47727c46fb7fSek xdr_snfs_resop4(XDR *xdrs, nfs_resop4 *objp)
47737c46fb7fSek {
47747c46fb7fSek 	if (!xdr_int(xdrs, (int *)&objp->resop))
47757c46fb7fSek 		return (FALSE);
47767c46fb7fSek 
47777c46fb7fSek 	switch (objp->resop) {
47787c46fb7fSek 	case OP_GETFH:
47797c46fb7fSek 		if (!XDR_PUTINT32(xdrs,
47807c46fb7fSek 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
47817c46fb7fSek 			return (FALSE);
47827c46fb7fSek 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
47837c46fb7fSek 			return (TRUE);
47847c46fb7fSek 		return (xdr_encode_nfs_fh4(xdrs,
4785eac3aab7Srobinson 		    &objp->nfs_resop4_u.opgetfh.object));
47867c46fb7fSek 	default:
47877c46fb7fSek 		return (xdr_nfs_resop4(xdrs, objp));
47887c46fb7fSek 	}
47897c46fb7fSek }
47907c46fb7fSek 
47917c478bd9Sstevel@tonic-gate static bool_t
47927c478bd9Sstevel@tonic-gate xdr_nfs_resop4_clnt(XDR *xdrs, nfs_resop4 *objp, nfs_argop4 *aobjp)
47937c478bd9Sstevel@tonic-gate {
47947c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->resop))
47957c478bd9Sstevel@tonic-gate 		return (FALSE);
47967c478bd9Sstevel@tonic-gate 	/*
47977c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
47987c478bd9Sstevel@tonic-gate 	 */
47997c478bd9Sstevel@tonic-gate 	switch (objp->resop) {
48007c478bd9Sstevel@tonic-gate 	case OP_PUTFH:
48017c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48020a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
48037c478bd9Sstevel@tonic-gate 	case OP_GETATTR:
48047c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
48050a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
48067c478bd9Sstevel@tonic-gate 			return (FALSE);
48077c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
48087c478bd9Sstevel@tonic-gate 			return (TRUE);
48097c478bd9Sstevel@tonic-gate 		return (xdr_ga_res(xdrs,
48100a701b1eSRobert Gordon 		    (GETATTR4res *)&objp->nfs_resop4_u.opgetattr,
48110a701b1eSRobert Gordon 		    &aobjp->nfs_argop4_u.opgetattr));
48127c478bd9Sstevel@tonic-gate 	case OP_GETFH:
48137c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
48140a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
48157c478bd9Sstevel@tonic-gate 			return (FALSE);
48167c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
48177c478bd9Sstevel@tonic-gate 			return (TRUE);
48187c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
48197c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
48207c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
48217c478bd9Sstevel@tonic-gate 		    NFS4_FHSIZE));
48227c478bd9Sstevel@tonic-gate 	case OP_LOOKUP:
48237c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48240a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
48257c478bd9Sstevel@tonic-gate 	case OP_NVERIFY:
48267c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48270a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
48287c478bd9Sstevel@tonic-gate 	case OP_OPEN:
48297c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
48307c478bd9Sstevel@tonic-gate 	case OP_CLOSE:
48317c478bd9Sstevel@tonic-gate 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
48327c478bd9Sstevel@tonic-gate 	case OP_ACCESS:
48337c478bd9Sstevel@tonic-gate 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
48347c478bd9Sstevel@tonic-gate 	case OP_READ:
48357c478bd9Sstevel@tonic-gate 		return (xdr_READ4res_clnt(xdrs, &objp->nfs_resop4_u.opread,
48360a701b1eSRobert Gordon 		    &aobjp->nfs_argop4_u.opread));
48377c478bd9Sstevel@tonic-gate 	case OP_WRITE:
48387c478bd9Sstevel@tonic-gate 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
48397c478bd9Sstevel@tonic-gate 	case OP_DELEGRETURN:
48407c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48410a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
48427c478bd9Sstevel@tonic-gate 	case OP_LOOKUPP:
48437c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48440a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
48457c478bd9Sstevel@tonic-gate 	case OP_READDIR:
48467c478bd9Sstevel@tonic-gate 		return (xdr_READDIR4res_clnt(xdrs,
48470a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opreaddirclnt,
48480a701b1eSRobert Gordon 		    &aobjp->nfs_argop4_u.opreaddir));
48497c478bd9Sstevel@tonic-gate 	case OP_REMOVE:
48507c478bd9Sstevel@tonic-gate 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
48517c478bd9Sstevel@tonic-gate 
48527c478bd9Sstevel@tonic-gate 	case OP_COMMIT:
48537c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
48540a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
48557c478bd9Sstevel@tonic-gate 			return (FALSE);
48567c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
48577c478bd9Sstevel@tonic-gate 			return (TRUE);
48587c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
48590a701b1eSRobert Gordon 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
48600a701b1eSRobert Gordon 		    writeverf));
48617c478bd9Sstevel@tonic-gate 	case OP_CREATE:
48627c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
48637c478bd9Sstevel@tonic-gate 	case OP_DELEGPURGE:
48647c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48650a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
48667c478bd9Sstevel@tonic-gate 	case OP_LINK:
48677c478bd9Sstevel@tonic-gate 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
48687c478bd9Sstevel@tonic-gate 	case OP_LOCK:
48697c478bd9Sstevel@tonic-gate 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
48707c478bd9Sstevel@tonic-gate 	case OP_LOCKT:
48717c478bd9Sstevel@tonic-gate 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
48727c478bd9Sstevel@tonic-gate 	case OP_LOCKU:
48737c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
48740a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
48757c478bd9Sstevel@tonic-gate 			return (FALSE);
48767c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
48777c478bd9Sstevel@tonic-gate 			return (TRUE);
48787c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs,
48797c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
48807c478bd9Sstevel@tonic-gate 			return (FALSE);
48817c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs,
48827c478bd9Sstevel@tonic-gate 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
48837c478bd9Sstevel@tonic-gate 		    12));
48847c478bd9Sstevel@tonic-gate 	case OP_OPENATTR:
48857c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48860a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
48877c478bd9Sstevel@tonic-gate 	case OP_OPEN_CONFIRM:
48887c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_CONFIRM4res(xdrs,
48890a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opopen_confirm));
48907c478bd9Sstevel@tonic-gate 	case OP_OPEN_DOWNGRADE:
48917c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
48920a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opopen_downgrade));
48937c478bd9Sstevel@tonic-gate 	case OP_PUTPUBFH:
48947c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48950a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
48967c478bd9Sstevel@tonic-gate 	case OP_PUTROOTFH:
48977c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48980a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
48997c478bd9Sstevel@tonic-gate 	case OP_READLINK:
49007c478bd9Sstevel@tonic-gate 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
49017c478bd9Sstevel@tonic-gate 	case OP_RENAME:
49027c478bd9Sstevel@tonic-gate 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
49037c478bd9Sstevel@tonic-gate 	case OP_RENEW:
49047c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49050a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
49067c478bd9Sstevel@tonic-gate 	case OP_RESTOREFH:
49077c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49080a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
49097c478bd9Sstevel@tonic-gate 	case OP_SAVEFH:
49107c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49110a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
49127c478bd9Sstevel@tonic-gate 	case OP_SECINFO:
49137c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
49140a701b1eSRobert Gordon 		    status))
49157c478bd9Sstevel@tonic-gate 			return (FALSE);
49167c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
49177c478bd9Sstevel@tonic-gate 			return (TRUE);
49187c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
49190a701b1eSRobert Gordon 		    SECINFO4resok_val,
49200a701b1eSRobert Gordon 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
49210a701b1eSRobert Gordon 		    SECINFO4resok_len,
49220a701b1eSRobert Gordon 		    ~0, sizeof (secinfo4), (xdrproc_t)xdr_secinfo4));
49237c478bd9Sstevel@tonic-gate 	case OP_SETATTR:
49247c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
49250a701b1eSRobert Gordon 		    status))
49267c478bd9Sstevel@tonic-gate 			return (FALSE);
49277c478bd9Sstevel@tonic-gate 		return (xdr_bitmap4(xdrs,
49280a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opsetattr.attrsset));
49297c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID:
49307c478bd9Sstevel@tonic-gate 		return (xdr_SETCLIENTID4res(xdrs,
49310a701b1eSRobert Gordon 		    &objp->nfs_resop4_u.opsetclientid));
49327c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID_CONFIRM:
49337c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49340a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
49350a701b1eSRobert Gordon 		    status));
49367c478bd9Sstevel@tonic-gate 	case OP_VERIFY:
49377c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49380a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
49397c478bd9Sstevel@tonic-gate 	case OP_RELEASE_LOCKOWNER:
49407c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49417c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
49427c478bd9Sstevel@tonic-gate 	case OP_ILLEGAL:
49437c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49440a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
49457c478bd9Sstevel@tonic-gate 	}
49467c478bd9Sstevel@tonic-gate 	return (FALSE);
49477c478bd9Sstevel@tonic-gate }
49487c478bd9Sstevel@tonic-gate 
49497c478bd9Sstevel@tonic-gate bool_t
49507c478bd9Sstevel@tonic-gate xdr_COMPOUND4args_clnt(XDR *xdrs, COMPOUND4args_clnt *objp)
49517c478bd9Sstevel@tonic-gate {
49527c478bd9Sstevel@tonic-gate 	static int32_t twelve = 12;
49537c478bd9Sstevel@tonic-gate 	static int32_t minorversion = NFS4_MINORVERSION;
49547c478bd9Sstevel@tonic-gate 	uint32_t *ctagp;
49557c478bd9Sstevel@tonic-gate 	rpc_inline_t *ptr;
49560a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
49570a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
49587c478bd9Sstevel@tonic-gate 
49597c478bd9Sstevel@tonic-gate 	/*
49607c478bd9Sstevel@tonic-gate 	 * XDR_ENCODE only
49617c478bd9Sstevel@tonic-gate 	 */
49627c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
49637c478bd9Sstevel@tonic-gate 		return (TRUE);
49647c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
49657c478bd9Sstevel@tonic-gate 		return (FALSE);
49667c478bd9Sstevel@tonic-gate 
49677c478bd9Sstevel@tonic-gate 	ctagp = (uint32_t *)&nfs4_ctags[objp->ctag].ct_tag;
49687c478bd9Sstevel@tonic-gate 
49697c478bd9Sstevel@tonic-gate 	if ((ptr = XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT)) != NULL) {
49707c478bd9Sstevel@tonic-gate 		/*
49717c478bd9Sstevel@tonic-gate 		 * Efficiently encode fixed length tags, could be longlongs
49727c478bd9Sstevel@tonic-gate 		 * but 8 byte XDR alignment not assured
49737c478bd9Sstevel@tonic-gate 		 */
49747c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, 12);
49757c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, ctagp[0]);
49767c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, ctagp[1]);
49777c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, ctagp[2]);
49787c478bd9Sstevel@tonic-gate 
49797c478bd9Sstevel@tonic-gate 		/*
49807c478bd9Sstevel@tonic-gate 		 * Fixed minor version for now
49817c478bd9Sstevel@tonic-gate 		 */
49827c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, NFS4_MINORVERSION);
49837c478bd9Sstevel@tonic-gate 	} else {
49847c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &twelve))
49857c478bd9Sstevel@tonic-gate 			return (FALSE);
49867c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[0]))
49877c478bd9Sstevel@tonic-gate 			return (FALSE);
49887c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[1]))
49897c478bd9Sstevel@tonic-gate 			return (FALSE);
49907c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[2]))
49917c478bd9Sstevel@tonic-gate 			return (FALSE);
49927c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&minorversion))
49937c478bd9Sstevel@tonic-gate 			return (FALSE);
49947c478bd9Sstevel@tonic-gate 	}
49950a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) {
49960a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
49970a701b1eSRobert Gordon 		rci.rci_len = MAXPATHLEN * 2;
49980a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
49990a701b1eSRobert Gordon 	}
50007c478bd9Sstevel@tonic-gate 
50017c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->array,
50020a701b1eSRobert Gordon 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
50030a701b1eSRobert Gordon 	    sizeof (nfs_argop4), (xdrproc_t)xdr_cnfs_argop4));
50047c478bd9Sstevel@tonic-gate }
50057c478bd9Sstevel@tonic-gate 
50067c478bd9Sstevel@tonic-gate bool_t
50077c46fb7fSek xdr_COMPOUND4args_srv(XDR *xdrs, COMPOUND4args *objp)
50087c478bd9Sstevel@tonic-gate {
50097c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
50100a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
50110a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
50127c478bd9Sstevel@tonic-gate 		return (FALSE);
50137c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->minorversion))
50147c478bd9Sstevel@tonic-gate 		return (FALSE);
50157c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE)
50167c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->array,
50170a701b1eSRobert Gordon 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
50180a701b1eSRobert Gordon 		    sizeof (nfs_argop4), (xdrproc_t)xdr_snfs_argop4));
50197c478bd9Sstevel@tonic-gate 
50207c46fb7fSek 	return (xdr_snfs_argop4_free(xdrs, &objp->array, objp->array_len));
50217c478bd9Sstevel@tonic-gate }
50227c478bd9Sstevel@tonic-gate 
50237c478bd9Sstevel@tonic-gate bool_t
50247c478bd9Sstevel@tonic-gate xdr_COMPOUND4res_clnt(XDR *xdrs, COMPOUND4res_clnt *objp)
50257c478bd9Sstevel@tonic-gate {
50267c478bd9Sstevel@tonic-gate 	uint32_t len;
50277c478bd9Sstevel@tonic-gate 	int32_t *ptr;
50287c478bd9Sstevel@tonic-gate 	nfs_argop4 *argop;
50297c478bd9Sstevel@tonic-gate 	nfs_resop4 *resop;
50307c478bd9Sstevel@tonic-gate 
50317c478bd9Sstevel@tonic-gate 	/*
50327c478bd9Sstevel@tonic-gate 	 * No XDR_ENCODE
50337c478bd9Sstevel@tonic-gate 	 */
50347c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
50357c478bd9Sstevel@tonic-gate 		return (FALSE);
50367c478bd9Sstevel@tonic-gate 
50377c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
50387c478bd9Sstevel@tonic-gate 		if ((ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL) {
50397c478bd9Sstevel@tonic-gate 			objp->status = IXDR_GET_U_INT32(ptr);
50407c478bd9Sstevel@tonic-gate 			len = IXDR_GET_U_INT32(ptr);
50417c478bd9Sstevel@tonic-gate 		} else {
50427c478bd9Sstevel@tonic-gate 			if (!xdr_int(xdrs, (int32_t *)&objp->status))
50437c478bd9Sstevel@tonic-gate 				return (FALSE);
50447c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (uint32_t *)&len))
50457c478bd9Sstevel@tonic-gate 				return (FALSE);
50467c478bd9Sstevel@tonic-gate 		}
50477c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
50487c478bd9Sstevel@tonic-gate 			return (FALSE);
50497c478bd9Sstevel@tonic-gate 		/*
50507c478bd9Sstevel@tonic-gate 		 * Ignore the tag
50517c478bd9Sstevel@tonic-gate 		 */
50527c478bd9Sstevel@tonic-gate 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &len))
50537c478bd9Sstevel@tonic-gate 			return (FALSE);
50547c478bd9Sstevel@tonic-gate 
50557c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->array_len))
50567c478bd9Sstevel@tonic-gate 			return (FALSE);
50577c478bd9Sstevel@tonic-gate 
50587c478bd9Sstevel@tonic-gate 		if (objp->array_len > objp->argsp->array_len)
50597c478bd9Sstevel@tonic-gate 			return (FALSE);
50607c478bd9Sstevel@tonic-gate 
50612c2d21e9SRichard Lowe 		if (objp->status == NFS4_OK &&
50627c478bd9Sstevel@tonic-gate 		    objp->array_len != objp->argsp->array_len)
50637c478bd9Sstevel@tonic-gate 			return (FALSE);
50647c478bd9Sstevel@tonic-gate 
50657c478bd9Sstevel@tonic-gate 		/* Alloc the results array */
50667c478bd9Sstevel@tonic-gate 		argop = objp->argsp->array;
50677c478bd9Sstevel@tonic-gate 		len = objp->array_len * sizeof (nfs_resop4);
50687c478bd9Sstevel@tonic-gate 		objp->decode_len = 0;
50697c478bd9Sstevel@tonic-gate 		objp->array = resop = kmem_zalloc(len, KM_SLEEP);
50707c478bd9Sstevel@tonic-gate 
50717c478bd9Sstevel@tonic-gate 		for (len = 0; len < objp->array_len;
50720a701b1eSRobert Gordon 		    len++, resop++, argop++, objp->decode_len++) {
50737c478bd9Sstevel@tonic-gate 			if (!xdr_nfs_resop4_clnt(xdrs, resop, argop)) {
50747c478bd9Sstevel@tonic-gate 				/*
50757c478bd9Sstevel@tonic-gate 				 * Make sure to free anything that may
50767c478bd9Sstevel@tonic-gate 				 * have been allocated along the way.
50777c478bd9Sstevel@tonic-gate 				 */
50787c478bd9Sstevel@tonic-gate 				xdrs->x_op = XDR_FREE;
50797c478bd9Sstevel@tonic-gate 				(void) xdr_nfs_resop4_free(xdrs, &objp->array,
50800a701b1eSRobert Gordon 				    objp->array_len,
50810a701b1eSRobert Gordon 				    objp->decode_len);
50827c478bd9Sstevel@tonic-gate 				return (FALSE);
50837c478bd9Sstevel@tonic-gate 			}
50847c478bd9Sstevel@tonic-gate 		}
50857c478bd9Sstevel@tonic-gate 		return (TRUE);
50867c478bd9Sstevel@tonic-gate 	}
50877c478bd9Sstevel@tonic-gate 	return (xdr_nfs_resop4_free(xdrs, &objp->array,
50880a701b1eSRobert Gordon 	    objp->array_len, objp->decode_len));
50897c478bd9Sstevel@tonic-gate }
50907c478bd9Sstevel@tonic-gate 
50917c478bd9Sstevel@tonic-gate bool_t
50927c46fb7fSek xdr_COMPOUND4res_srv(XDR *xdrs, COMPOUND4res *objp)
50937c478bd9Sstevel@tonic-gate {
50947c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
50957c478bd9Sstevel@tonic-gate 		return (FALSE);
50967c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
50970a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
50980a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
50997c478bd9Sstevel@tonic-gate 		return (FALSE);
51007c478bd9Sstevel@tonic-gate 
51017c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE)
51027c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->array,
51030a701b1eSRobert Gordon 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
51040a701b1eSRobert Gordon 		    sizeof (nfs_resop4), (xdrproc_t)xdr_snfs_resop4));
51057c478bd9Sstevel@tonic-gate 
51067c46fb7fSek 	return (xdr_snfs_resop4_free(xdrs, &objp->array,
51070a701b1eSRobert Gordon 	    objp->array_len, objp->array_len));
51087c478bd9Sstevel@tonic-gate }
51097c478bd9Sstevel@tonic-gate 
5110eac3aab7Srobinson /*
5111eac3aab7Srobinson  * NFS server side callback, initiating the callback request so it
5112eac3aab7Srobinson  * is the RPC client. Must convert from server's internal filehandle
5113eac3aab7Srobinson  * format to wire format.
5114eac3aab7Srobinson  */
51157c478bd9Sstevel@tonic-gate static bool_t
5116eac3aab7Srobinson xdr_snfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
51177c478bd9Sstevel@tonic-gate {
5118eac3aab7Srobinson 	CB_GETATTR4args *gargs;
5119eac3aab7Srobinson 	CB_RECALL4args *rargs;
5120eac3aab7Srobinson 
5121eac3aab7Srobinson 	ASSERT(xdrs->x_op == XDR_ENCODE);
5122eac3aab7Srobinson 
5123eac3aab7Srobinson 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->argop))
5124eac3aab7Srobinson 		return (FALSE);
5125eac3aab7Srobinson 
5126eac3aab7Srobinson 	switch (objp->argop) {
5127eac3aab7Srobinson 	case OP_CB_GETATTR:
5128eac3aab7Srobinson 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
5129eac3aab7Srobinson 
5130eac3aab7Srobinson 		if (!xdr_encode_nfs_fh4(xdrs, &gargs->fh))
5131eac3aab7Srobinson 			return (FALSE);
5132eac3aab7Srobinson 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
5133eac3aab7Srobinson 	case OP_CB_RECALL:
5134eac3aab7Srobinson 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
5135eac3aab7Srobinson 
5136eac3aab7Srobinson 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->stateid.seqid))
5137eac3aab7Srobinson 			return (FALSE);
5138eac3aab7Srobinson 		if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
5139eac3aab7Srobinson 			return (FALSE);
5140eac3aab7Srobinson 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->truncate))
5141eac3aab7Srobinson 			return (FALSE);
5142eac3aab7Srobinson 		return (xdr_encode_nfs_fh4(xdrs, &rargs->fh));
5143eac3aab7Srobinson 	case OP_CB_ILLEGAL:
5144eac3aab7Srobinson 		return (TRUE);
5145eac3aab7Srobinson 	}
5146eac3aab7Srobinson 	return (FALSE);
5147eac3aab7Srobinson }
5148eac3aab7Srobinson 
5149eac3aab7Srobinson /*
5150eac3aab7Srobinson  * NFS client side callback, receiving the callback request so it
5151eac3aab7Srobinson  * is the RPC server. Must treat the file handles as opaque.
5152eac3aab7Srobinson  */
5153eac3aab7Srobinson static bool_t
5154eac3aab7Srobinson xdr_cnfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
5155eac3aab7Srobinson {
5156eac3aab7Srobinson 	CB_GETATTR4args *gargs;
5157eac3aab7Srobinson 	CB_RECALL4args *rargs;
5158eac3aab7Srobinson 
5159eac3aab7Srobinson 	ASSERT(xdrs->x_op != XDR_ENCODE);
5160eac3aab7Srobinson 
51617c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->argop))
51627c478bd9Sstevel@tonic-gate 		return (FALSE);
51637c478bd9Sstevel@tonic-gate 	switch (objp->argop) {
51647c478bd9Sstevel@tonic-gate 	case OP_CB_GETATTR:
5165eac3aab7Srobinson 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
5166eac3aab7Srobinson 
5167eac3aab7Srobinson 		if (!xdr_bytes(xdrs, (char **)&gargs->fh.nfs_fh4_val,
5168eac3aab7Srobinson 		    (uint_t *)&gargs->fh.nfs_fh4_len, NFS4_FHSIZE))
51697c478bd9Sstevel@tonic-gate 			return (FALSE);
5170eac3aab7Srobinson 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
51717c478bd9Sstevel@tonic-gate 	case OP_CB_RECALL:
5172eac3aab7Srobinson 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
5173eac3aab7Srobinson 
5174eac3aab7Srobinson 		if (!xdr_u_int(xdrs, &rargs->stateid.seqid))
51757c478bd9Sstevel@tonic-gate 			return (FALSE);
5176eac3aab7Srobinson 		if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
51777c478bd9Sstevel@tonic-gate 			return (FALSE);
5178eac3aab7Srobinson 		if (!xdr_bool(xdrs, &rargs->truncate))
51797c478bd9Sstevel@tonic-gate 			return (FALSE);
5180eac3aab7Srobinson 		return (xdr_bytes(xdrs, (char **)&rargs->fh.nfs_fh4_val,
5181eac3aab7Srobinson 		    (uint_t *)&rargs->fh.nfs_fh4_len, NFS4_FHSIZE));
51827c478bd9Sstevel@tonic-gate 	case OP_CB_ILLEGAL:
51837c478bd9Sstevel@tonic-gate 		return (TRUE);
51847c478bd9Sstevel@tonic-gate 	}
51857c478bd9Sstevel@tonic-gate 	return (FALSE);
51867c478bd9Sstevel@tonic-gate }
51877c478bd9Sstevel@tonic-gate 
51887c478bd9Sstevel@tonic-gate static bool_t
51897c478bd9Sstevel@tonic-gate xdr_nfs_cb_resop4(XDR *xdrs, nfs_cb_resop4 *objp)
51907c478bd9Sstevel@tonic-gate {
51917c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->resop))
51927c478bd9Sstevel@tonic-gate 		return (FALSE);
51937c478bd9Sstevel@tonic-gate 	switch (objp->resop) {
51947c478bd9Sstevel@tonic-gate 	case OP_CB_GETATTR:
51957c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
51960a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbgetattr.
51970a701b1eSRobert Gordon 		    status))
51987c478bd9Sstevel@tonic-gate 			return (FALSE);
51997c478bd9Sstevel@tonic-gate 		if (objp->nfs_cb_resop4_u.opcbgetattr.status != NFS4_OK)
52007c478bd9Sstevel@tonic-gate 			return (TRUE);
52017c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
52020a701b1eSRobert Gordon 		    &objp->nfs_cb_resop4_u.opcbgetattr.
52030a701b1eSRobert Gordon 		    obj_attributes));
52047c478bd9Sstevel@tonic-gate 	case OP_CB_RECALL:
52057c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
52060a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbrecall.status));
52077c478bd9Sstevel@tonic-gate 	case OP_CB_ILLEGAL:
52087c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
52090a701b1eSRobert Gordon 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbillegal.status));
52107c478bd9Sstevel@tonic-gate 	}
52117c478bd9Sstevel@tonic-gate 	return (FALSE);
52127c478bd9Sstevel@tonic-gate }
52137c478bd9Sstevel@tonic-gate 
5214eac3aab7Srobinson /*
5215eac3aab7Srobinson  * The NFS client side callback, RPC server
5216eac3aab7Srobinson  */
5217eac3aab7Srobinson bool_t
5218eac3aab7Srobinson xdr_CB_COMPOUND4args_clnt(XDR *xdrs, CB_COMPOUND4args *objp)
5219eac3aab7Srobinson {
5220eac3aab7Srobinson 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
52210a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
52220a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
5223eac3aab7Srobinson 		return (FALSE);
5224eac3aab7Srobinson 	if (!xdr_u_int(xdrs, &objp->minorversion))
5225eac3aab7Srobinson 		return (FALSE);
5226eac3aab7Srobinson 	if (!xdr_u_int(xdrs, &objp->callback_ident))
5227eac3aab7Srobinson 		return (FALSE);
5228eac3aab7Srobinson 	return (xdr_array(xdrs, (char **)&objp->array,
52290a701b1eSRobert Gordon 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
52300a701b1eSRobert Gordon 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_cnfs_cb_argop4));
5231eac3aab7Srobinson }
5232eac3aab7Srobinson 
5233eac3aab7Srobinson /*
5234eac3aab7Srobinson  * The NFS server side callback, RPC client
5235eac3aab7Srobinson  */
52367c478bd9Sstevel@tonic-gate bool_t
5237eac3aab7Srobinson xdr_CB_COMPOUND4args_srv(XDR *xdrs, CB_COMPOUND4args *objp)
52387c478bd9Sstevel@tonic-gate {
52397c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
52400a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
52410a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
52427c478bd9Sstevel@tonic-gate 		return (FALSE);
52437c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->minorversion))
52447c478bd9Sstevel@tonic-gate 		return (FALSE);
52457c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->callback_ident))
52467c478bd9Sstevel@tonic-gate 		return (FALSE);
52477c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->array,
52480a701b1eSRobert Gordon 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
52490a701b1eSRobert Gordon 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_snfs_cb_argop4));
52507c478bd9Sstevel@tonic-gate }
52517c478bd9Sstevel@tonic-gate 
52527c478bd9Sstevel@tonic-gate bool_t
52537c478bd9Sstevel@tonic-gate xdr_CB_COMPOUND4res(XDR *xdrs, CB_COMPOUND4res *objp)
52547c478bd9Sstevel@tonic-gate {
52557c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
52567c478bd9Sstevel@tonic-gate 		return (FALSE);
52577c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
52580a701b1eSRobert Gordon 	    (uint_t *)&objp->tag.utf8string_len,
52590a701b1eSRobert Gordon 	    NFS4_MAX_UTF8STRING))
52607c478bd9Sstevel@tonic-gate 		return (FALSE);
52617c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->array,
52620a701b1eSRobert Gordon 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
52630a701b1eSRobert Gordon 	    sizeof (nfs_cb_resop4), (xdrproc_t)xdr_nfs_cb_resop4));
52647c478bd9Sstevel@tonic-gate }
5265