xref: /titanic_51/usr/src/uts/common/fs/nfs/nfs4_xdr.c (revision c93d332c7127fa77fd1d38a46c87a7d24d7a9ef8)
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  */
21bbe876c0SMarcel Telka 
22bbe876c0SMarcel Telka /*
23bbe876c0SMarcel Telka  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
24bbe876c0SMarcel Telka  */
25bbe876c0SMarcel Telka 
267c478bd9Sstevel@tonic-gate /*
27c242f9a0Schunli zhang - Sun Microsystems - Irvine United States  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
280a701b1eSRobert Gordon  * Use is subject to license terms.
297c478bd9Sstevel@tonic-gate  */
30297b4d80SVitaliy Gusev /*
31e36d7b11SSebastien Roy  * Copyright (c) 2013 by Delphix. All rights reserved.
32297b4d80SVitaliy Gusev  */
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate /*
357c478bd9Sstevel@tonic-gate  * A handcoded version based on the original rpcgen code.
367c478bd9Sstevel@tonic-gate  *
377c478bd9Sstevel@tonic-gate  * Note: All future NFS4 protocol changes should be added by hand
387c478bd9Sstevel@tonic-gate  * to this file.
397c478bd9Sstevel@tonic-gate  *
407c478bd9Sstevel@tonic-gate  * CAUTION: All protocol changes must also be propagated to:
417c478bd9Sstevel@tonic-gate  *     usr/src/cmd/cmd-inet/usr.sbin/snoop/nfs4_xdr.c
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #include <sys/types.h>
457c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
467c478bd9Sstevel@tonic-gate #include <sys/dnlc.h>
477c478bd9Sstevel@tonic-gate #include <nfs/nfs.h>
487c478bd9Sstevel@tonic-gate #include <nfs/nfs4_kprot.h>
497c478bd9Sstevel@tonic-gate #include <nfs/rnode4.h>
507c478bd9Sstevel@tonic-gate #include <nfs/nfs4.h>
517c478bd9Sstevel@tonic-gate #include <nfs/nfs4_clnt.h>
527c478bd9Sstevel@tonic-gate #include <sys/sdt.h>
532f172c55SRobert Thurlow #include <sys/mkdev.h>
547c478bd9Sstevel@tonic-gate #include <rpc/rpc_rdma.h>
552f172c55SRobert Thurlow #include <rpc/xdr.h>
562f172c55SRobert Thurlow 
572f172c55SRobert Thurlow #define	xdr_dev_t xdr_u_int
582f172c55SRobert Thurlow 
592f172c55SRobert Thurlow extern bool_t xdr_netbuf(XDR *, struct netbuf *);
602f172c55SRobert Thurlow extern bool_t xdr_vector(XDR *, char *, const uint_t, const uint_t,
612f172c55SRobert Thurlow 	const xdrproc_t);
622f172c55SRobert Thurlow bool_t xdr_knetconfig(XDR *, struct knetconfig *);
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate bool_t
657c478bd9Sstevel@tonic-gate xdr_bitmap4(XDR *xdrs, bitmap4 *objp)
667c478bd9Sstevel@tonic-gate {
677c478bd9Sstevel@tonic-gate 	int32_t len, size;
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
707c478bd9Sstevel@tonic-gate 		return (TRUE);
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 	/*
737c478bd9Sstevel@tonic-gate 	 * Simplified bitmap4 processing, always encode from uint64_t
747c478bd9Sstevel@tonic-gate 	 * to 2 uint32_t's, always decode first 2 uint32_t's into a
757c478bd9Sstevel@tonic-gate 	 * uint64_t and ignore all of the rest.
767c478bd9Sstevel@tonic-gate 	 */
777c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
787c478bd9Sstevel@tonic-gate 		len = 2;
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len))
817c478bd9Sstevel@tonic-gate 			return (FALSE);
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
847c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
857c478bd9Sstevel@tonic-gate 		    BYTES_PER_XDR_UNIT)) == TRUE) {
867c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)objp));
877c478bd9Sstevel@tonic-gate 		}
887c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
897c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int32_t *)objp) == TRUE) {
907c478bd9Sstevel@tonic-gate 			return (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
917c478bd9Sstevel@tonic-gate 			    BYTES_PER_XDR_UNIT)));
927c478bd9Sstevel@tonic-gate 		}
937c478bd9Sstevel@tonic-gate #endif
947c478bd9Sstevel@tonic-gate 		return (FALSE);
957c478bd9Sstevel@tonic-gate 	}
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, &len))
987c478bd9Sstevel@tonic-gate 		return (FALSE);
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 	/*
1017c478bd9Sstevel@tonic-gate 	 * Common fast DECODE cases
1027c478bd9Sstevel@tonic-gate 	 */
1037c478bd9Sstevel@tonic-gate 	if (len == 2) {
1047c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
1057c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
1067c478bd9Sstevel@tonic-gate 		    BYTES_PER_XDR_UNIT)) == TRUE) {
1077c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)objp));
1087c478bd9Sstevel@tonic-gate 		}
1097c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
1107c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int32_t *)objp) == TRUE) {
1117c478bd9Sstevel@tonic-gate 			return (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
1127c478bd9Sstevel@tonic-gate 			    BYTES_PER_XDR_UNIT)));
1137c478bd9Sstevel@tonic-gate 		}
1147c478bd9Sstevel@tonic-gate #endif
1157c478bd9Sstevel@tonic-gate 		return (FALSE);
1167c478bd9Sstevel@tonic-gate 	}
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	*objp = 0;
1197c478bd9Sstevel@tonic-gate 	if (len == 0)
1207c478bd9Sstevel@tonic-gate 		return (TRUE);
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 	/*
1237c478bd9Sstevel@tonic-gate 	 * The not so common DECODE cases, len == 1 || len > 2
1247c478bd9Sstevel@tonic-gate 	 */
1257c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
1267c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
1277c478bd9Sstevel@tonic-gate 		return (FALSE);
1287c478bd9Sstevel@tonic-gate 	if (--len == 0)
1297c478bd9Sstevel@tonic-gate 		return (TRUE);
1307c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
1317c478bd9Sstevel@tonic-gate 		return (FALSE);
1327c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
1337c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
1347c478bd9Sstevel@tonic-gate 		return (FALSE);
1357c478bd9Sstevel@tonic-gate 	if (--len == 0)
1367c478bd9Sstevel@tonic-gate 		return (TRUE);
1377c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
1387c478bd9Sstevel@tonic-gate 		return (FALSE);
1397c478bd9Sstevel@tonic-gate #else
1407c478bd9Sstevel@tonic-gate 	return (FALSE);
1417c478bd9Sstevel@tonic-gate #endif
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	if (--len == 0)
1447c478bd9Sstevel@tonic-gate 		return (TRUE);
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 	size = len * BYTES_PER_XDR_UNIT;
1477c478bd9Sstevel@tonic-gate 	return (XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size));
1487c478bd9Sstevel@tonic-gate }
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate /* Called by xdr_array, nfsid_map_xdr */
1517c478bd9Sstevel@tonic-gate bool_t
1527c478bd9Sstevel@tonic-gate xdr_utf8string(XDR *xdrs, utf8string *objp)
1537c478bd9Sstevel@tonic-gate {
1547c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE)
1557c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->utf8string_val,
1567c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->utf8string_len, NFS4_MAX_UTF8STRING));
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	if (objp->utf8string_val != NULL) {
1597c478bd9Sstevel@tonic-gate 		kmem_free(objp->utf8string_val, objp->utf8string_len);
1607c478bd9Sstevel@tonic-gate 		objp->utf8string_val = NULL;
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 	return (TRUE);
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate /*
1662f172c55SRobert Thurlow  * used by NFSv4 referrals to get info needed for NFSv4 referral mount.
1672f172c55SRobert Thurlow  */
1682f172c55SRobert Thurlow bool_t
1692f172c55SRobert Thurlow xdr_nfs_fsl_info(XDR *xdrs, struct nfs_fsl_info *objp)
1702f172c55SRobert Thurlow {
1712f172c55SRobert Thurlow 
1722f172c55SRobert Thurlow 	if (!xdr_u_int(xdrs, &objp->netbuf_len))
1732f172c55SRobert Thurlow 		return (FALSE);
1742f172c55SRobert Thurlow 	if (!xdr_u_int(xdrs, &objp->netnm_len))
1752f172c55SRobert Thurlow 		return (FALSE);
1762f172c55SRobert Thurlow 	if (!xdr_u_int(xdrs, &objp->knconf_len))
1772f172c55SRobert Thurlow 		return (FALSE);
1782f172c55SRobert Thurlow 
1792f172c55SRobert Thurlow #if defined(_LP64)
1802f172c55SRobert Thurlow 	/*
1812f172c55SRobert Thurlow 	 * The object can come from a 32-bit binary; nfsmapid.
1822f172c55SRobert Thurlow 	 * To be safe we double the size of the knetconfig to
1832f172c55SRobert Thurlow 	 * allow some buffering for decoding.
1842f172c55SRobert Thurlow 	 */
1852f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE)
1862f172c55SRobert Thurlow 		objp->knconf_len += sizeof (struct knetconfig);
1872f172c55SRobert Thurlow #endif
1882f172c55SRobert Thurlow 
1892f172c55SRobert Thurlow 	if (!xdr_string(xdrs, &objp->netname, ~0))
1902f172c55SRobert Thurlow 		return (FALSE);
1912f172c55SRobert Thurlow 	if (!xdr_pointer(xdrs, (char **)&objp->addr, objp->netbuf_len,
1922f172c55SRobert Thurlow 	    (xdrproc_t)xdr_netbuf))
1932f172c55SRobert Thurlow 		return (FALSE);
1942f172c55SRobert Thurlow 	if (!xdr_pointer(xdrs, (char **)&objp->knconf,
1952f172c55SRobert Thurlow 	    objp->knconf_len, (xdrproc_t)xdr_knetconfig))
1962f172c55SRobert Thurlow 		return (FALSE);
1972f172c55SRobert Thurlow 	return (TRUE);
1982f172c55SRobert Thurlow }
1992f172c55SRobert Thurlow 
2002f172c55SRobert Thurlow bool_t
2012f172c55SRobert Thurlow xdr_knetconfig(XDR *xdrs, struct knetconfig *objp)
2022f172c55SRobert Thurlow {
2032f172c55SRobert Thurlow 	rpc_inline_t *buf;
2042f172c55SRobert Thurlow 	u_longlong_t dev64;
2052f172c55SRobert Thurlow #if !defined(_LP64)
2062f172c55SRobert Thurlow 	uint32_t major, minor;
2072f172c55SRobert Thurlow #endif
2082f172c55SRobert Thurlow 	int i;
2092f172c55SRobert Thurlow 
2102f172c55SRobert Thurlow 	if (!xdr_u_int(xdrs, &objp->knc_semantics))
2112f172c55SRobert Thurlow 		return (FALSE);
2122f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
2132f172c55SRobert Thurlow 		objp->knc_protofmly = (((char *)objp) +
2142f172c55SRobert Thurlow 		    sizeof (struct knetconfig));
2152f172c55SRobert Thurlow 		objp->knc_proto = objp->knc_protofmly + KNC_STRSIZE;
2162f172c55SRobert Thurlow 	}
2172f172c55SRobert Thurlow 	if (!xdr_opaque(xdrs, objp->knc_protofmly, KNC_STRSIZE))
2182f172c55SRobert Thurlow 		return (FALSE);
2192f172c55SRobert Thurlow 	if (!xdr_opaque(xdrs, objp->knc_proto, KNC_STRSIZE))
2202f172c55SRobert Thurlow 		return (FALSE);
2212f172c55SRobert Thurlow 
2222f172c55SRobert Thurlow 	/*
2232f172c55SRobert Thurlow 	 * For interoperability between 32-bit daemon and 64-bit kernel,
2242f172c55SRobert Thurlow 	 * we always treat dev_t as 64-bit number and do the expanding
2252f172c55SRobert Thurlow 	 * or compression of dev_t as needed.
2262f172c55SRobert Thurlow 	 * We have to hand craft the conversion since there is no available
2272f172c55SRobert Thurlow 	 * function in ddi.c. Besides ddi.c is available only in the kernel
2282f172c55SRobert Thurlow 	 * and we want to keep both user and kernel of xdr_knetconfig() the
2292f172c55SRobert Thurlow 	 * same for consistency.
2302f172c55SRobert Thurlow 	 */
2312f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_ENCODE) {
2322f172c55SRobert Thurlow #if defined(_LP64)
2332f172c55SRobert Thurlow 		dev64 = objp->knc_rdev;
2342f172c55SRobert Thurlow #else
2352f172c55SRobert Thurlow 		major = (objp->knc_rdev >> NBITSMINOR32) & MAXMAJ32;
2362f172c55SRobert Thurlow 		minor = objp->knc_rdev & MAXMIN32;
2372f172c55SRobert Thurlow 		dev64 = (((unsigned long long)major) << NBITSMINOR64) | minor;
2382f172c55SRobert Thurlow #endif
2392f172c55SRobert Thurlow 		if (!xdr_u_longlong_t(xdrs, &dev64))
2402f172c55SRobert Thurlow 			return (FALSE);
2412f172c55SRobert Thurlow 	}
2422f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
2432f172c55SRobert Thurlow #if defined(_LP64)
2442f172c55SRobert Thurlow 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->knc_rdev))
2452f172c55SRobert Thurlow 			return (FALSE);
2462f172c55SRobert Thurlow #else
2472f172c55SRobert Thurlow 		if (!xdr_u_longlong_t(xdrs, &dev64))
2482f172c55SRobert Thurlow 			return (FALSE);
2492f172c55SRobert Thurlow 
2502f172c55SRobert Thurlow 		major = (dev64 >> NBITSMINOR64) & L_MAXMAJ32;
2512f172c55SRobert Thurlow 		minor = dev64 & L_MAXMIN32;
2522f172c55SRobert Thurlow 		objp->knc_rdev = (major << L_BITSMINOR32) | minor;
2532f172c55SRobert Thurlow #endif
2542f172c55SRobert Thurlow 	}
2552f172c55SRobert Thurlow 
2562f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_ENCODE) {
2572f172c55SRobert Thurlow 		buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT);
2582f172c55SRobert Thurlow 		if (buf == NULL) {
2592f172c55SRobert Thurlow 			if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
2602f172c55SRobert Thurlow 			    sizeof (uint_t), (xdrproc_t)xdr_u_int))
2612f172c55SRobert Thurlow 				return (FALSE);
2622f172c55SRobert Thurlow 		} else {
2632f172c55SRobert Thurlow 			uint_t *genp;
2642f172c55SRobert Thurlow 
2652f172c55SRobert Thurlow 			for (i = 0, genp = objp->knc_unused;
2662f172c55SRobert Thurlow 			    i < 8; i++) {
2672f172c55SRobert Thurlow #if defined(_LP64) || defined(_KERNEL)
2682f172c55SRobert Thurlow 				IXDR_PUT_U_INT32(buf, *genp++);
2692f172c55SRobert Thurlow #else
2702f172c55SRobert Thurlow 				IXDR_PUT_U_LONG(buf, *genp++);
2712f172c55SRobert Thurlow #endif
2722f172c55SRobert Thurlow 			}
2732f172c55SRobert Thurlow 		}
2742f172c55SRobert Thurlow 		return (TRUE);
2752f172c55SRobert Thurlow 	} else if (xdrs->x_op == XDR_DECODE) {
2762f172c55SRobert Thurlow 		buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT);
2772f172c55SRobert Thurlow 		if (buf == NULL) {
2782f172c55SRobert Thurlow 			if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
2792f172c55SRobert Thurlow 			    sizeof (uint_t), (xdrproc_t)xdr_u_int))
2802f172c55SRobert Thurlow 				return (FALSE);
2812f172c55SRobert Thurlow 		} else {
2822f172c55SRobert Thurlow 			uint_t *genp;
2832f172c55SRobert Thurlow 
2842f172c55SRobert Thurlow 			for (i = 0, genp = objp->knc_unused;
2852f172c55SRobert Thurlow 			    i < 8; i++) {
2862f172c55SRobert Thurlow #if defined(_LP64) || defined(_KERNEL)
2872f172c55SRobert Thurlow 					*genp++ = IXDR_GET_U_INT32(buf);
2882f172c55SRobert Thurlow #else
2892f172c55SRobert Thurlow 					*genp++ = IXDR_GET_U_LONG(buf);
2902f172c55SRobert Thurlow #endif
2912f172c55SRobert Thurlow 			}
2922f172c55SRobert Thurlow 		}
2932f172c55SRobert Thurlow 		return (TRUE);
2942f172c55SRobert Thurlow 	}
2952f172c55SRobert Thurlow 
2962f172c55SRobert Thurlow 	if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
2972f172c55SRobert Thurlow 	    sizeof (uint_t), (xdrproc_t)xdr_u_int))
2982f172c55SRobert Thurlow 		return (FALSE);
2992f172c55SRobert Thurlow 	return (TRUE);
3002f172c55SRobert Thurlow }
3012f172c55SRobert Thurlow 
3022f172c55SRobert Thurlow /*
303eac3aab7Srobinson  * XDR_INLINE decode a filehandle.
304eac3aab7Srobinson  */
305eac3aab7Srobinson bool_t
306eac3aab7Srobinson xdr_inline_decode_nfs_fh4(uint32_t *ptr, nfs_fh4_fmt_t *fhp, uint32_t fhsize)
307eac3aab7Srobinson {
308eac3aab7Srobinson 	uchar_t *bp = (uchar_t *)ptr;
309eac3aab7Srobinson 	uchar_t *cp;
310eac3aab7Srobinson 	uint32_t dsize;
311eac3aab7Srobinson 	uintptr_t resid;
312eac3aab7Srobinson 
313eac3aab7Srobinson 	/*
314eac3aab7Srobinson 	 * Check to see if what the client sent us is bigger or smaller
315eac3aab7Srobinson 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
316eac3aab7Srobinson 	 * unfortunately badly named as it is no longer the max and is
317eac3aab7Srobinson 	 * really the min of what is sent over the wire.
318eac3aab7Srobinson 	 */
319eac3aab7Srobinson 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
320eac3aab7Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA +
321eac3aab7Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
322eac3aab7Srobinson 		return (FALSE);
323eac3aab7Srobinson 	}
324eac3aab7Srobinson 
325eac3aab7Srobinson 	/*
326eac3aab7Srobinson 	 * All internal parts of a filehandle are in native byte order.
327eac3aab7Srobinson 	 *
328eac3aab7Srobinson 	 * Decode what should be fh4_fsid, it is aligned.
329eac3aab7Srobinson 	 */
330eac3aab7Srobinson 	fhp->fh4_fsid.val[0] = *(uint32_t *)bp;
331eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
332eac3aab7Srobinson 	fhp->fh4_fsid.val[1] = *(uint32_t *)bp;
333eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
334eac3aab7Srobinson 
335eac3aab7Srobinson 	/*
336eac3aab7Srobinson 	 * Decode what should be fh4_len.  fh4_len is two bytes, so we're
337eac3aab7Srobinson 	 * unaligned now.
338eac3aab7Srobinson 	 */
339eac3aab7Srobinson 	cp = (uchar_t *)&fhp->fh4_len;
340eac3aab7Srobinson 	*cp++ = *bp++;
341eac3aab7Srobinson 	*cp++ = *bp++;
342eac3aab7Srobinson 	fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
343eac3aab7Srobinson 
344eac3aab7Srobinson 	/*
345da6c28aaSamw 	 * For backwards compatibility, the fid length may be less than
346eac3aab7Srobinson 	 * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
347eac3aab7Srobinson 	 */
348eac3aab7Srobinson 	dsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
349eac3aab7Srobinson 
350eac3aab7Srobinson 	/*
351eac3aab7Srobinson 	 * Make sure the client isn't sending us a bogus length for fh4_data.
352eac3aab7Srobinson 	 */
353eac3aab7Srobinson 	if (fhsize < dsize)
354eac3aab7Srobinson 		return (FALSE);
355eac3aab7Srobinson 	bcopy(bp, fhp->fh4_data, dsize);
356eac3aab7Srobinson 	bp += dsize;
357eac3aab7Srobinson 	fhsize -= dsize;
358eac3aab7Srobinson 
359eac3aab7Srobinson 	if (fhsize < sizeof (ushort_t))
360eac3aab7Srobinson 		return (FALSE);
361eac3aab7Srobinson 	cp = (uchar_t *)&fhp->fh4_xlen;
362eac3aab7Srobinson 	*cp++ = *bp++;
363eac3aab7Srobinson 	*cp++ = *bp++;
364eac3aab7Srobinson 	fhsize -= sizeof (ushort_t);
365eac3aab7Srobinson 
366eac3aab7Srobinson 	dsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
367eac3aab7Srobinson 
368eac3aab7Srobinson 	/*
369eac3aab7Srobinson 	 * Make sure the client isn't sending us a bogus length for fh4_xdata.
370eac3aab7Srobinson 	 */
371eac3aab7Srobinson 	if (fhsize < dsize)
372eac3aab7Srobinson 		return (FALSE);
373eac3aab7Srobinson 	bcopy(bp, fhp->fh4_xdata, dsize);
374eac3aab7Srobinson 	fhsize -= dsize;
375eac3aab7Srobinson 	bp += dsize;
376eac3aab7Srobinson 
377eac3aab7Srobinson 	/*
378eac3aab7Srobinson 	 * We realign things on purpose, so skip any padding
379eac3aab7Srobinson 	 */
380eac3aab7Srobinson 	resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
381eac3aab7Srobinson 	if (resid != 0) {
382eac3aab7Srobinson 		if (fhsize < (BYTES_PER_XDR_UNIT - resid))
383eac3aab7Srobinson 			return (FALSE);
384eac3aab7Srobinson 		bp += BYTES_PER_XDR_UNIT - resid;
385eac3aab7Srobinson 		fhsize -= BYTES_PER_XDR_UNIT - resid;
386eac3aab7Srobinson 	}
387eac3aab7Srobinson 
388eac3aab7Srobinson 	if (fhsize < BYTES_PER_XDR_UNIT)
389eac3aab7Srobinson 		return (FALSE);
390eac3aab7Srobinson 	fhp->fh4_flag = *(uint32_t *)bp;
391eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
392eac3aab7Srobinson 	fhsize -= BYTES_PER_XDR_UNIT;
393eac3aab7Srobinson 
394eac3aab7Srobinson #ifdef VOLATILE_FH_TEST
395eac3aab7Srobinson 	if (fhsize < BYTES_PER_XDR_UNIT)
396eac3aab7Srobinson 		return (FALSE);
397eac3aab7Srobinson 	fhp->fh4_volatile_id = *(uint32_t *)bp;
398eac3aab7Srobinson 	bp += BYTES_PER_XDR_UNIT;
399eac3aab7Srobinson 	fhsize -= BYTES_PER_XDR_UNIT;
400eac3aab7Srobinson #endif
401eac3aab7Srobinson 	/*
402eac3aab7Srobinson 	 * Make sure client didn't send extra bytes
403eac3aab7Srobinson 	 */
404eac3aab7Srobinson 	if (fhsize != 0)
405eac3aab7Srobinson 		return (FALSE);
406eac3aab7Srobinson 	return (TRUE);
407eac3aab7Srobinson }
408eac3aab7Srobinson 
409eac3aab7Srobinson static bool_t
410eac3aab7Srobinson xdr_decode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
411eac3aab7Srobinson {
412eac3aab7Srobinson 	uint32_t fhsize;		/* filehandle size */
413eac3aab7Srobinson 	uint32_t bufsize;
414eac3aab7Srobinson 	rpc_inline_t *ptr;
41527242a7cSthurlow 	uchar_t *bp;
416eac3aab7Srobinson 
417eac3aab7Srobinson 	ASSERT(xdrs->x_op == XDR_DECODE);
418eac3aab7Srobinson 
419eac3aab7Srobinson 	/*
420eac3aab7Srobinson 	 * Retrieve the filehandle length.
421eac3aab7Srobinson 	 */
422eac3aab7Srobinson 	if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
423eac3aab7Srobinson 		return (FALSE);
424eac3aab7Srobinson 
425eac3aab7Srobinson 	objp->nfs_fh4_val = NULL;
426eac3aab7Srobinson 	objp->nfs_fh4_len = 0;
427eac3aab7Srobinson 
428eac3aab7Srobinson 	/*
429eac3aab7Srobinson 	 * Check to see if what the client sent us is bigger or smaller
430eac3aab7Srobinson 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
431eac3aab7Srobinson 	 * unfortunately badly named as it is no longer the max and is
432eac3aab7Srobinson 	 * really the min of what is sent over the wire.
433eac3aab7Srobinson 	 */
434eac3aab7Srobinson 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
435eac3aab7Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA +
436eac3aab7Srobinson 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
437eac3aab7Srobinson 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
438eac3aab7Srobinson 			return (FALSE);
439eac3aab7Srobinson 		return (TRUE);
440eac3aab7Srobinson 	}
441eac3aab7Srobinson 
442eac3aab7Srobinson 	/*
443eac3aab7Srobinson 	 * bring in fhsize plus any padding
444eac3aab7Srobinson 	 */
445eac3aab7Srobinson 	bufsize = RNDUP(fhsize);
446eac3aab7Srobinson 	ptr = XDR_INLINE(xdrs, bufsize);
447eac3aab7Srobinson 	bp = (uchar_t *)ptr;
448eac3aab7Srobinson 	if (ptr == NULL) {
44927242a7cSthurlow 		bp = kmem_alloc(bufsize, KM_SLEEP);
45027242a7cSthurlow 		if (!xdr_opaque(xdrs, (char *)bp, bufsize)) {
45127242a7cSthurlow 			kmem_free(bp, bufsize);
452eac3aab7Srobinson 			return (FALSE);
453eac3aab7Srobinson 		}
45427242a7cSthurlow 	}
455eac3aab7Srobinson 
456eac3aab7Srobinson 	objp->nfs_fh4_val = kmem_zalloc(sizeof (nfs_fh4_fmt_t), KM_SLEEP);
457eac3aab7Srobinson 	objp->nfs_fh4_len = sizeof (nfs_fh4_fmt_t);
458eac3aab7Srobinson 
459eac3aab7Srobinson 	if (xdr_inline_decode_nfs_fh4((uint32_t *)bp,
460eac3aab7Srobinson 	    (nfs_fh4_fmt_t *)objp->nfs_fh4_val, fhsize) == FALSE) {
461eac3aab7Srobinson 		/*
462eac3aab7Srobinson 		 * If in the process of decoding we find the file handle
463eac3aab7Srobinson 		 * is not correctly formed, we need to continue decoding
464eac3aab7Srobinson 		 * and trigger an NFS layer error. Set the nfs_fh4_len to
465eac3aab7Srobinson 		 * zero so it gets caught as a bad length.
466eac3aab7Srobinson 		 */
467eac3aab7Srobinson 		kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
468eac3aab7Srobinson 		objp->nfs_fh4_val = NULL;
469eac3aab7Srobinson 		objp->nfs_fh4_len = 0;
470eac3aab7Srobinson 	}
471eac3aab7Srobinson 
472eac3aab7Srobinson 	if (ptr == NULL)
47327242a7cSthurlow 		kmem_free(bp, bufsize);
474eac3aab7Srobinson 	return (TRUE);
475eac3aab7Srobinson }
476eac3aab7Srobinson 
477eac3aab7Srobinson /*
4787c46fb7fSek110237  * XDR_INLINE encode a filehandle.
4797c46fb7fSek110237  */
4807c46fb7fSek110237 bool_t
4817c46fb7fSek110237 xdr_inline_encode_nfs_fh4(uint32_t **ptrp, uint32_t *ptr_redzone,
4827c46fb7fSek110237 	nfs_fh4_fmt_t *fhp)
4837c46fb7fSek110237 {
4847c46fb7fSek110237 	uint32_t *ptr = *ptrp;
4854f85d229Srobinson 	uchar_t *cp;
4864f85d229Srobinson 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
4877c46fb7fSek110237 	uint32_t padword;
4887c46fb7fSek110237 
4894f85d229Srobinson 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
4904f85d229Srobinson 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
4914f85d229Srobinson 
4927c46fb7fSek110237 	/*
4934f85d229Srobinson 	 * First get the initial and variable sized part of the filehandle.
4947c46fb7fSek110237 	 */
4954f85d229Srobinson 	otw_len = sizeof (fhp->fh4_fsid) +
4964f85d229Srobinson 	    sizeof (fhp->fh4_len) + fsize +
4974f85d229Srobinson 	    sizeof (fhp->fh4_xlen) + xsize;
4984f85d229Srobinson 
4997c46fb7fSek110237 	/*
5007c46fb7fSek110237 	 * Round out to a full word.
5017c46fb7fSek110237 	 */
5027c46fb7fSek110237 	otw_len = RNDUP(otw_len);
5034f85d229Srobinson 	padword = (otw_len / BYTES_PER_XDR_UNIT);	/* includes fhlen */
5047c46fb7fSek110237 
5057c46fb7fSek110237 	/*
5067c46fb7fSek110237 	 * Add in the fixed sized pieces.
5077c46fb7fSek110237 	 */
5087c46fb7fSek110237 	otw_len += sizeof (fhp->fh4_flag);
5097c46fb7fSek110237 #ifdef VOLATILE_FH_TEST
5107c46fb7fSek110237 	otw_len += sizeof (fhp->fh4_volatile_id);
5117c46fb7fSek110237 #endif
5127c46fb7fSek110237 
5137c46fb7fSek110237 	/*
5147c46fb7fSek110237 	 * Make sure we don't exceed our buffer.
5157c46fb7fSek110237 	 */
5167c46fb7fSek110237 	if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone)
5177c46fb7fSek110237 		return (FALSE);
5187c46fb7fSek110237 
5197c46fb7fSek110237 	/*
52027242a7cSthurlow 	 * Zero out the padding.
5217c46fb7fSek110237 	 */
5227c46fb7fSek110237 	ptr[padword] = 0;
5237c46fb7fSek110237 
52427242a7cSthurlow 	IXDR_PUT_U_INT32(ptr, otw_len);
52527242a7cSthurlow 
5264f85d229Srobinson 	/*
5274f85d229Srobinson 	 * The rest of the filehandle is in native byteorder
5284f85d229Srobinson 	 */
5297c46fb7fSek110237 	/* fh4_fsid */
5300379dd9dSek110237 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[0];
5310379dd9dSek110237 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[1];
5327c46fb7fSek110237 
5337c46fb7fSek110237 	/*
5347c46fb7fSek110237 	 * Since the next pieces are unaligned, we need to
5357c46fb7fSek110237 	 * do bytewise copies.
5367c46fb7fSek110237 	 */
5374f85d229Srobinson 	cp = (uchar_t *)ptr;
5387c46fb7fSek110237 
5397c46fb7fSek110237 	/* fh4_len + fh4_data */
5404f85d229Srobinson 	bcopy(&fhp->fh4_len, cp, sizeof (fhp->fh4_len) + fsize);
5414f85d229Srobinson 	cp += sizeof (fhp->fh4_len) + fsize;
5427c46fb7fSek110237 
5437c46fb7fSek110237 	/* fh4_xlen + fh4_xdata */
5444f85d229Srobinson 	bcopy(&fhp->fh4_xlen, cp, sizeof (fhp->fh4_xlen) + xsize);
5454f85d229Srobinson 	cp += sizeof (fhp->fh4_xlen) + xsize;
5467c46fb7fSek110237 
5477c46fb7fSek110237 	/* do necessary rounding/padding */
5484f85d229Srobinson 	cp = (uchar_t *)RNDUP((uintptr_t)cp);
5494f85d229Srobinson 	ptr = (uint32_t *)cp;
5507c46fb7fSek110237 
5517c46fb7fSek110237 	/*
5527c46fb7fSek110237 	 * With the above padding, we're word aligned again.
5537c46fb7fSek110237 	 */
5547c46fb7fSek110237 	ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0);
5557c46fb7fSek110237 
5567c46fb7fSek110237 	/* fh4_flag */
5570379dd9dSek110237 	*ptr++ = (uint32_t)fhp->fh4_flag;
5587c46fb7fSek110237 
5597c46fb7fSek110237 #ifdef VOLATILE_FH_TEST
5607c46fb7fSek110237 	/* fh4_volatile_id */
5610379dd9dSek110237 	*ptr++ = (uint32_t)fhp->fh4_volatile_id;
5627c46fb7fSek110237 #endif
5637c46fb7fSek110237 	*ptrp = ptr;
5647c46fb7fSek110237 
5657c46fb7fSek110237 	return (TRUE);
5667c46fb7fSek110237 }
5677c46fb7fSek110237 
5687c46fb7fSek110237 static bool_t
5697c46fb7fSek110237 xdr_encode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
5707c46fb7fSek110237 {
5714f85d229Srobinson 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
5724f85d229Srobinson 	bool_t ret;
5734f85d229Srobinson 	rpc_inline_t *ptr;
5744f85d229Srobinson 	rpc_inline_t *buf = NULL;
5754f85d229Srobinson 	uint32_t *ptr_redzone;
5764f85d229Srobinson 	nfs_fh4_fmt_t *fhp;
5777c46fb7fSek110237 
5787c46fb7fSek110237 	ASSERT(xdrs->x_op == XDR_ENCODE);
5797c46fb7fSek110237 
5804f85d229Srobinson 	fhp = (nfs_fh4_fmt_t *)objp->nfs_fh4_val;
5814f85d229Srobinson 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
5824f85d229Srobinson 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
5837c46fb7fSek110237 
5847c46fb7fSek110237 	/*
5854f85d229Srobinson 	 * First get the over the wire size, it is the 4 bytes
5864f85d229Srobinson 	 * for the length, plus the combined size of the
5874f85d229Srobinson 	 * file handle components.
5887c46fb7fSek110237 	 */
5894f85d229Srobinson 	otw_len = BYTES_PER_XDR_UNIT + sizeof (fhp->fh4_fsid) +
5904f85d229Srobinson 	    sizeof (fhp->fh4_len) + fsize +
5914f85d229Srobinson 	    sizeof (fhp->fh4_xlen) + xsize +
5924f85d229Srobinson 	    sizeof (fhp->fh4_flag);
5934f85d229Srobinson #ifdef VOLATILE_FH_TEST
5944f85d229Srobinson 	otw_len += sizeof (fhp->fh4_volatile_id);
5954f85d229Srobinson #endif
5964f85d229Srobinson 	/*
5974f85d229Srobinson 	 * Round out to a full word.
5984f85d229Srobinson 	 */
5994f85d229Srobinson 	otw_len = RNDUP(otw_len);
6007c46fb7fSek110237 
6017c46fb7fSek110237 	/*
6024f85d229Srobinson 	 * Next try to inline the XDR stream, if that fails (rare)
6034f85d229Srobinson 	 * allocate a buffer to encode the file handle and then
6044f85d229Srobinson 	 * copy it using xdr_opaque and free the buffer.
6057c46fb7fSek110237 	 */
6064f85d229Srobinson 	ptr = XDR_INLINE(xdrs, otw_len);
6074f85d229Srobinson 	if (ptr == NULL)
6084f85d229Srobinson 		ptr = buf = kmem_alloc(otw_len, KM_SLEEP);
6097c46fb7fSek110237 
6104f85d229Srobinson 	ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT));
6114f85d229Srobinson 	ret = xdr_inline_encode_nfs_fh4((uint32_t **)&ptr, ptr_redzone, fhp);
6127c46fb7fSek110237 
6134f85d229Srobinson 	if (buf != NULL) {
6144f85d229Srobinson 		if (ret == TRUE)
6154f85d229Srobinson 			ret = xdr_opaque(xdrs, (char *)buf, otw_len);
6164f85d229Srobinson 		kmem_free(buf, otw_len);
6174f85d229Srobinson 	}
6184f85d229Srobinson 	return (ret);
6197c46fb7fSek110237 }
6207c46fb7fSek110237 
6217c46fb7fSek110237 /*
6227c46fb7fSek110237  * XDR a NFSv4 filehandle.
623eac3aab7Srobinson  * Encoding interprets the contents (server).
624eac3aab7Srobinson  * Decoding the contents are opaque (client).
6257c478bd9Sstevel@tonic-gate  */
6267c478bd9Sstevel@tonic-gate bool_t
6277c478bd9Sstevel@tonic-gate xdr_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
6287c478bd9Sstevel@tonic-gate {
629eac3aab7Srobinson 	switch (xdrs->x_op) {
630eac3aab7Srobinson 	case XDR_ENCODE:
6317c46fb7fSek110237 		return (xdr_encode_nfs_fh4(xdrs, objp));
632eac3aab7Srobinson 	case XDR_DECODE:
633eac3aab7Srobinson 		return (xdr_bytes(xdrs, (char **)&objp->nfs_fh4_val,
634eac3aab7Srobinson 		    (uint_t *)&objp->nfs_fh4_len, NFS4_FHSIZE));
635eac3aab7Srobinson 	case XDR_FREE:
6367c478bd9Sstevel@tonic-gate 		if (objp->nfs_fh4_val != NULL) {
6377c478bd9Sstevel@tonic-gate 			kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
6387c478bd9Sstevel@tonic-gate 			objp->nfs_fh4_val = NULL;
6397c478bd9Sstevel@tonic-gate 		}
6407c478bd9Sstevel@tonic-gate 		return (TRUE);
6417c478bd9Sstevel@tonic-gate 	}
642eac3aab7Srobinson 	return (FALSE);
643eac3aab7Srobinson }
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate /* Called by xdr_array */
6467c478bd9Sstevel@tonic-gate static bool_t
6477c478bd9Sstevel@tonic-gate xdr_fs_location4(XDR *xdrs, fs_location4 *objp)
6487c478bd9Sstevel@tonic-gate {
6492f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
6502f172c55SRobert Thurlow 		objp->server_val = NULL;
6512f172c55SRobert Thurlow 		objp->rootpath.pathname4_val = NULL;
6522f172c55SRobert Thurlow 	}
6537c478bd9Sstevel@tonic-gate 	if (!xdr_array(xdrs, (char **)&objp->server_val,
6542f172c55SRobert Thurlow 	    (uint_t *)&objp->server_len, NFS4_MAX_UTF8STRING,
6557c478bd9Sstevel@tonic-gate 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
6567c478bd9Sstevel@tonic-gate 		return (FALSE);
6577c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->rootpath.pathname4_val,
6587c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->rootpath.pathname4_len,
6597c478bd9Sstevel@tonic-gate 	    NFS4_MAX_PATHNAME4,
6607c478bd9Sstevel@tonic-gate 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string));
6617c478bd9Sstevel@tonic-gate }
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate /* Called by xdr_array */
6647c478bd9Sstevel@tonic-gate static bool_t
6657c478bd9Sstevel@tonic-gate xdr_nfsace4(XDR *xdrs, nfsace4 *objp)
6667c478bd9Sstevel@tonic-gate {
6677c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
6687c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->type))
6697c478bd9Sstevel@tonic-gate 			return (FALSE);
6707c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->flag))
6717c478bd9Sstevel@tonic-gate 			return (FALSE);
6727c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->access_mask))
6737c478bd9Sstevel@tonic-gate 			return (FALSE);
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
6767c478bd9Sstevel@tonic-gate 			objp->who.utf8string_val = NULL;
6777c478bd9Sstevel@tonic-gate 			objp->who.utf8string_len = 0;
6787c478bd9Sstevel@tonic-gate 		}
6797c478bd9Sstevel@tonic-gate 
6807c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->who.utf8string_val,
6817c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->who.utf8string_len,
6827c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
6837c478bd9Sstevel@tonic-gate 	}
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate 	/*
6867c478bd9Sstevel@tonic-gate 	 * Optimized free case
6877c478bd9Sstevel@tonic-gate 	 */
6887c478bd9Sstevel@tonic-gate 	if (objp->who.utf8string_val != NULL) {
6897c478bd9Sstevel@tonic-gate 		kmem_free(objp->who.utf8string_val, objp->who.utf8string_len);
6907c478bd9Sstevel@tonic-gate 		objp->who.utf8string_val = NULL;
6917c478bd9Sstevel@tonic-gate 	}
6927c478bd9Sstevel@tonic-gate 	return (TRUE);
6937c478bd9Sstevel@tonic-gate }
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate /*
6967c478bd9Sstevel@tonic-gate  * These functions are called out of nfs4_attr.c
6977c478bd9Sstevel@tonic-gate  */
6987c478bd9Sstevel@tonic-gate bool_t
6997c478bd9Sstevel@tonic-gate xdr_fattr4_fsid(XDR *xdrs, fattr4_fsid *objp)
7007c478bd9Sstevel@tonic-gate {
7017c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
7027c478bd9Sstevel@tonic-gate 		return (TRUE);
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->major))
7057c478bd9Sstevel@tonic-gate 		return (FALSE);
7067c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->minor));
7077c478bd9Sstevel@tonic-gate }
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate bool_t
7117c478bd9Sstevel@tonic-gate xdr_fattr4_acl(XDR *xdrs, fattr4_acl *objp)
7127c478bd9Sstevel@tonic-gate {
7137c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->fattr4_acl_val,
7147c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->fattr4_acl_len, NFS4_ACL_LIMIT,
7157c478bd9Sstevel@tonic-gate 	    sizeof (nfsace4), (xdrproc_t)xdr_nfsace4));
7167c478bd9Sstevel@tonic-gate }
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate bool_t
7197c478bd9Sstevel@tonic-gate xdr_fattr4_fs_locations(XDR *xdrs, fattr4_fs_locations *objp)
7207c478bd9Sstevel@tonic-gate {
7212f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
7222f172c55SRobert Thurlow 		objp->fs_root.pathname4_len = 0;
7232f172c55SRobert Thurlow 		objp->fs_root.pathname4_val = NULL;
7242f172c55SRobert Thurlow 		objp->locations_val = NULL;
7252f172c55SRobert Thurlow 	}
7267c478bd9Sstevel@tonic-gate 	if (!xdr_array(xdrs, (char **)&objp->fs_root.pathname4_val,
7277c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->fs_root.pathname4_len,
7287c478bd9Sstevel@tonic-gate 	    NFS4_MAX_PATHNAME4,
7297c478bd9Sstevel@tonic-gate 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
7307c478bd9Sstevel@tonic-gate 		return (FALSE);
7317c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->locations_val,
7327c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->locations_len, NFS4_FS_LOCATIONS_LIMIT,
7337c478bd9Sstevel@tonic-gate 	    sizeof (fs_location4), (xdrproc_t)xdr_fs_location4));
7347c478bd9Sstevel@tonic-gate }
7357c478bd9Sstevel@tonic-gate 
7367c478bd9Sstevel@tonic-gate bool_t
7377c478bd9Sstevel@tonic-gate xdr_fattr4_rawdev(XDR *xdrs, fattr4_rawdev *objp)
7387c478bd9Sstevel@tonic-gate {
7397c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
7407c478bd9Sstevel@tonic-gate 		return (TRUE);
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->specdata1))
7437c478bd9Sstevel@tonic-gate 		return (FALSE);
7447c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->specdata2));
7457c478bd9Sstevel@tonic-gate }
7467c478bd9Sstevel@tonic-gate 
7477c478bd9Sstevel@tonic-gate bool_t
7487c478bd9Sstevel@tonic-gate xdr_nfstime4(XDR *xdrs, nfstime4 *objp)
7497c478bd9Sstevel@tonic-gate {
7507c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
7517c478bd9Sstevel@tonic-gate 		return (TRUE);
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->seconds))
7547c478bd9Sstevel@tonic-gate 		return (FALSE);
7557c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->nseconds));
7567c478bd9Sstevel@tonic-gate }
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate /*
7607c478bd9Sstevel@tonic-gate  * structured used for calls into xdr_ga_fattr_res() as a means
7617c478bd9Sstevel@tonic-gate  * to do an immediate/short-term cache of owner/group strings
7627c478bd9Sstevel@tonic-gate  * for callers like the readdir processing.  In the case of readdir,
7637c478bd9Sstevel@tonic-gate  * it is likely that the directory objects will be owned by the same
7647c478bd9Sstevel@tonic-gate  * owner/group and if so there is no need to call into the uid/gid
7657c478bd9Sstevel@tonic-gate  * mapping code.  While the uid/gid interfaces have their own cache
7667c478bd9Sstevel@tonic-gate  * having one here will reduct pathlength further.
7677c478bd9Sstevel@tonic-gate  */
7687c478bd9Sstevel@tonic-gate #define	MAX_OG_NAME 100
7697c478bd9Sstevel@tonic-gate typedef struct ug_cache
7707c478bd9Sstevel@tonic-gate {
7717c478bd9Sstevel@tonic-gate 	uid_t	uid;
7727c478bd9Sstevel@tonic-gate 	gid_t	gid;
7737c478bd9Sstevel@tonic-gate 	utf8string u_curr, u_last;
7747c478bd9Sstevel@tonic-gate 	utf8string g_curr, g_last;
7757c478bd9Sstevel@tonic-gate 	char	u_buf1[MAX_OG_NAME];
7767c478bd9Sstevel@tonic-gate 	char	u_buf2[MAX_OG_NAME];
7777c478bd9Sstevel@tonic-gate 	char	g_buf1[MAX_OG_NAME];
7787c478bd9Sstevel@tonic-gate 	char	g_buf2[MAX_OG_NAME];
7797c478bd9Sstevel@tonic-gate } ug_cache_t;
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate #define	U_SWAP_CURR_LAST(ug) \
7827c478bd9Sstevel@tonic-gate 	(ug)->u_last.utf8string_len = (ug)->u_curr.utf8string_len;	\
7837c478bd9Sstevel@tonic-gate 	if ((ug)->u_last.utf8string_val == (ug)->u_buf1) {		\
7847c478bd9Sstevel@tonic-gate 		(ug)->u_last.utf8string_val = (ug)->u_buf2;		\
7857c478bd9Sstevel@tonic-gate 		(ug)->u_curr.utf8string_val = (ug)->u_buf1;		\
7867c478bd9Sstevel@tonic-gate 	} else {							\
7877c478bd9Sstevel@tonic-gate 		(ug)->u_last.utf8string_val = (ug)->u_buf1;		\
7887c478bd9Sstevel@tonic-gate 		(ug)->u_curr.utf8string_val = (ug)->u_buf2;		\
7897c478bd9Sstevel@tonic-gate 	}
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate #define	G_SWAP_CURR_LAST(ug) \
7927c478bd9Sstevel@tonic-gate 	(ug)->g_last.utf8string_len = (ug)->g_curr.utf8string_len;	\
7937c478bd9Sstevel@tonic-gate 	if ((ug)->g_last.utf8string_val == (ug)->g_buf1) {		\
7947c478bd9Sstevel@tonic-gate 		(ug)->g_last.utf8string_val = (ug)->g_buf2;		\
7957c478bd9Sstevel@tonic-gate 		(ug)->g_curr.utf8string_val = (ug)->g_buf1;		\
7967c478bd9Sstevel@tonic-gate 	} else {							\
7977c478bd9Sstevel@tonic-gate 		(ug)->g_last.utf8string_val = (ug)->g_buf1;		\
7987c478bd9Sstevel@tonic-gate 		(ug)->g_curr.utf8string_val = (ug)->g_buf2;		\
7997c478bd9Sstevel@tonic-gate 	}
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate static ug_cache_t *
8027c478bd9Sstevel@tonic-gate alloc_ugcache()
8037c478bd9Sstevel@tonic-gate {
8047c478bd9Sstevel@tonic-gate 	ug_cache_t *pug = kmem_alloc(sizeof (ug_cache_t), KM_SLEEP);
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 	pug->uid = pug->gid = 0;
8077c478bd9Sstevel@tonic-gate 	pug->u_curr.utf8string_len = 0;
8087c478bd9Sstevel@tonic-gate 	pug->u_last.utf8string_len = 0;
8097c478bd9Sstevel@tonic-gate 	pug->g_curr.utf8string_len = 0;
8107c478bd9Sstevel@tonic-gate 	pug->g_last.utf8string_len = 0;
8117c478bd9Sstevel@tonic-gate 	pug->u_curr.utf8string_val = pug->u_buf1;
8127c478bd9Sstevel@tonic-gate 	pug->u_last.utf8string_val = pug->u_buf2;
8137c478bd9Sstevel@tonic-gate 	pug->g_curr.utf8string_val = pug->g_buf1;
8147c478bd9Sstevel@tonic-gate 	pug->g_last.utf8string_val = pug->g_buf2;
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 	return (pug);
8177c478bd9Sstevel@tonic-gate }
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate static void
8207c478bd9Sstevel@tonic-gate xdr_ga_prefill_vattr(struct nfs4_ga_res *garp, struct mntinfo4 *mi)
8217c478bd9Sstevel@tonic-gate {
8227c478bd9Sstevel@tonic-gate 	static vattr_t s_vattr = {
8237c478bd9Sstevel@tonic-gate 		AT_ALL,		/* va_mask */
8247c478bd9Sstevel@tonic-gate 		VNON,		/* va_type */
8257c478bd9Sstevel@tonic-gate 		0777,		/* va_mode */
8267c478bd9Sstevel@tonic-gate 		UID_NOBODY,	/* va_uid */
8277c478bd9Sstevel@tonic-gate 		GID_NOBODY,	/* va_gid */
8287c478bd9Sstevel@tonic-gate 		0,		/* va_fsid */
8297c478bd9Sstevel@tonic-gate 		0,		/* va_nodeid */
8307c478bd9Sstevel@tonic-gate 		1,		/* va_nlink */
8317c478bd9Sstevel@tonic-gate 		0,		/* va_size */
8327c478bd9Sstevel@tonic-gate 		{0, 0},		/* va_atime */
8337c478bd9Sstevel@tonic-gate 		{0, 0},		/* va_mtime */
8347c478bd9Sstevel@tonic-gate 		{0, 0},		/* va_ctime */
8357c478bd9Sstevel@tonic-gate 		0,		/* va_rdev */
8367c478bd9Sstevel@tonic-gate 		MAXBSIZE,	/* va_blksize */
8377c478bd9Sstevel@tonic-gate 		0,		/* va_nblocks */
8387c478bd9Sstevel@tonic-gate 		0		/* va_seq */
8397c478bd9Sstevel@tonic-gate 	};
8407c478bd9Sstevel@tonic-gate 
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate 	garp->n4g_va = s_vattr;
8437c478bd9Sstevel@tonic-gate 	garp->n4g_va.va_fsid = mi->mi_vfsp->vfs_dev;
8447c478bd9Sstevel@tonic-gate 	hrt2ts(gethrtime(), &garp->n4g_va.va_atime);
8457c478bd9Sstevel@tonic-gate 	garp->n4g_va.va_mtime = garp->n4g_va.va_ctime = garp->n4g_va.va_atime;
8467c478bd9Sstevel@tonic-gate }
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate static void
8497c478bd9Sstevel@tonic-gate xdr_ga_prefill_statvfs(struct nfs4_ga_ext_res *gesp, struct mntinfo4 *mi)
8507c478bd9Sstevel@tonic-gate {
8517c478bd9Sstevel@tonic-gate 	static statvfs64_t s_sb = {
8527c478bd9Sstevel@tonic-gate 		MAXBSIZE,	/* f_bsize */
8537c478bd9Sstevel@tonic-gate 		DEV_BSIZE,	/* f_frsize */
8547c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_blocks */
8557c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_bfree */
8567c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_bavail */
8577c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_files */
8587c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_ffree */
8597c478bd9Sstevel@tonic-gate 		(fsfilcnt64_t)-1, /* f_favail */
8607c478bd9Sstevel@tonic-gate 		0,		/* f_fsid */
8617c478bd9Sstevel@tonic-gate 		"\0",		/* f_basetype */
8627c478bd9Sstevel@tonic-gate 		0,		/* f_flag */
8637c478bd9Sstevel@tonic-gate 		MAXNAMELEN,	/* f_namemax */
8647c478bd9Sstevel@tonic-gate 		"\0",		/* f_fstr */
8657c478bd9Sstevel@tonic-gate 	};
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 	gesp->n4g_sb = s_sb;
8687c478bd9Sstevel@tonic-gate 	gesp->n4g_sb.f_fsid = mi->mi_vfsp->vfs_fsid.val[0];
8697c478bd9Sstevel@tonic-gate }
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate static bool_t
8727c478bd9Sstevel@tonic-gate xdr_ga_fattr_res(XDR *xdrs, struct nfs4_ga_res *garp, bitmap4 resbmap,
8737c478bd9Sstevel@tonic-gate 		bitmap4 argbmap, struct mntinfo4 *mi, ug_cache_t *pug)
8747c478bd9Sstevel@tonic-gate {
8757c478bd9Sstevel@tonic-gate 	int truefalse;
8767c478bd9Sstevel@tonic-gate 	struct nfs4_ga_ext_res ges, *gesp;
8777c478bd9Sstevel@tonic-gate 	vattr_t *vap = &garp->n4g_va;
8787c478bd9Sstevel@tonic-gate 	vsecattr_t *vsap = &garp->n4g_vsa;
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
8817c478bd9Sstevel@tonic-gate 
8827c478bd9Sstevel@tonic-gate 	if (garp->n4g_ext_res)
8837c478bd9Sstevel@tonic-gate 		gesp = garp->n4g_ext_res;
8847c478bd9Sstevel@tonic-gate 	else
8857c478bd9Sstevel@tonic-gate 		gesp = &ges;
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 	vap->va_mask = 0;
8887c478bd9Sstevel@tonic-gate 
8897c478bd9Sstevel@tonic-gate 	/* Check to see if the vattr should be pre-filled */
8907c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_VATTR_MASK)
8917c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_vattr(garp, mi);
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_STATFS_ATTR_MASK)
8947c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_statvfs(gesp, mi);
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate 	if (resbmap &
8977c478bd9Sstevel@tonic-gate 	    (FATTR4_SUPPORTED_ATTRS_MASK |
8987c478bd9Sstevel@tonic-gate 	    FATTR4_TYPE_MASK |
8997c478bd9Sstevel@tonic-gate 	    FATTR4_FH_EXPIRE_TYPE_MASK |
9007c478bd9Sstevel@tonic-gate 	    FATTR4_CHANGE_MASK |
9017c478bd9Sstevel@tonic-gate 	    FATTR4_SIZE_MASK |
9027c478bd9Sstevel@tonic-gate 	    FATTR4_LINK_SUPPORT_MASK |
9037c478bd9Sstevel@tonic-gate 	    FATTR4_SYMLINK_SUPPORT_MASK |
9047c478bd9Sstevel@tonic-gate 	    FATTR4_NAMED_ATTR_MASK)) {
9057c478bd9Sstevel@tonic-gate 
9067c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
9077c478bd9Sstevel@tonic-gate 			if (!xdr_bitmap4(xdrs, &gesp->n4g_suppattrs))
9087c478bd9Sstevel@tonic-gate 				return (FALSE);
9097c478bd9Sstevel@tonic-gate 		}
9107c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TYPE_MASK) {
9117c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_type))
9127c478bd9Sstevel@tonic-gate 				return (FALSE);
9137c478bd9Sstevel@tonic-gate 
9142c2d21e9SRichard Lowe 			if ((nfs_ftype4)vap->va_type < NF4REG ||
9152c2d21e9SRichard Lowe 			    (nfs_ftype4)vap->va_type > NF4NAMEDATTR)
9167c478bd9Sstevel@tonic-gate 				vap->va_type = VBAD;
9177c478bd9Sstevel@tonic-gate 			else
9187c478bd9Sstevel@tonic-gate 				vap->va_type = nf4_to_vt[vap->va_type];
9197c478bd9Sstevel@tonic-gate 			if (vap->va_type == VBLK)
9207c478bd9Sstevel@tonic-gate 				vap->va_blksize = DEV_BSIZE;
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_TYPE;
9237c478bd9Sstevel@tonic-gate 		}
9247c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
9257c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_fet))
9267c478bd9Sstevel@tonic-gate 				return (FALSE);
9277c478bd9Sstevel@tonic-gate 		}
9287c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHANGE_MASK) {
9297c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
9307c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&garp->n4g_change))
9317c478bd9Sstevel@tonic-gate 				return (FALSE);
9327c478bd9Sstevel@tonic-gate 			garp->n4g_change_valid = 1;
9337c478bd9Sstevel@tonic-gate 		}
9347c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SIZE_MASK) {
9357c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
9367c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&vap->va_size))
9377c478bd9Sstevel@tonic-gate 				return (FALSE);
9387c478bd9Sstevel@tonic-gate 			if (!NFS4_SIZE_OK(vap->va_size)) {
9397c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = EFBIG;
9407c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
9417c478bd9Sstevel@tonic-gate 			} else {
9427c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_SIZE;
9437c478bd9Sstevel@tonic-gate 			}
9447c478bd9Sstevel@tonic-gate 		}
9457c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
9467c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9477c478bd9Sstevel@tonic-gate 				return (FALSE);
9487c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_link_support =
9497c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
9507c478bd9Sstevel@tonic-gate 		}
9517c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
9527c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9537c478bd9Sstevel@tonic-gate 				return (FALSE);
9547c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_symlink_support =
9557c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
9567c478bd9Sstevel@tonic-gate 		}
9577c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
9587c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9597c478bd9Sstevel@tonic-gate 				return (FALSE);
9607c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
9617c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists =
9627c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
9637c478bd9Sstevel@tonic-gate 		}
9647c478bd9Sstevel@tonic-gate 	}
9657c478bd9Sstevel@tonic-gate 	if (resbmap &
9667c478bd9Sstevel@tonic-gate 	    (FATTR4_FSID_MASK |
9677c478bd9Sstevel@tonic-gate 	    FATTR4_UNIQUE_HANDLES_MASK |
9687c478bd9Sstevel@tonic-gate 	    FATTR4_LEASE_TIME_MASK |
9697c478bd9Sstevel@tonic-gate 	    FATTR4_RDATTR_ERROR_MASK)) {
9707c478bd9Sstevel@tonic-gate 
9717c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FSID_MASK) {
9727c478bd9Sstevel@tonic-gate 			if ((!xdr_u_longlong_t(xdrs,
9737c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&garp->n4g_fsid.major)) ||
9747c478bd9Sstevel@tonic-gate 			    (!xdr_u_longlong_t(xdrs,
9757c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&garp->n4g_fsid.minor)))
9767c478bd9Sstevel@tonic-gate 				return (FALSE);
9777c478bd9Sstevel@tonic-gate 			garp->n4g_fsid_valid = 1;
9787c478bd9Sstevel@tonic-gate 		}
9797c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
9807c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
9817c478bd9Sstevel@tonic-gate 				return (FALSE);
9827c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_unique_handles =
9837c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
9847c478bd9Sstevel@tonic-gate 		}
9857c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
9867c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_leasetime))
9877c478bd9Sstevel@tonic-gate 				return (FALSE);
9887c478bd9Sstevel@tonic-gate 		}
9897c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
9907c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs,
9917c478bd9Sstevel@tonic-gate 			    (int *)&gesp->n4g_rdattr_error))
9927c478bd9Sstevel@tonic-gate 				return (FALSE);
9937c478bd9Sstevel@tonic-gate 		}
9947c478bd9Sstevel@tonic-gate 	}
9957c478bd9Sstevel@tonic-gate 	if (resbmap &
9967c478bd9Sstevel@tonic-gate 	    (FATTR4_ACL_MASK |
9977c478bd9Sstevel@tonic-gate 	    FATTR4_ACLSUPPORT_MASK |
9987c478bd9Sstevel@tonic-gate 	    FATTR4_ARCHIVE_MASK |
9997c478bd9Sstevel@tonic-gate 	    FATTR4_CANSETTIME_MASK)) {
10007c478bd9Sstevel@tonic-gate 
10017c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACL_MASK) {
10027c478bd9Sstevel@tonic-gate 			fattr4_acl	acl;
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate 			acl.fattr4_acl_val = NULL;
10057c478bd9Sstevel@tonic-gate 			acl.fattr4_acl_len = 0;
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate 			if (!xdr_fattr4_acl(xdrs, &acl))
10087c478bd9Sstevel@tonic-gate 				return (FALSE);
10097c478bd9Sstevel@tonic-gate 
10107c478bd9Sstevel@tonic-gate 			vsap->vsa_aclcnt = acl.fattr4_acl_len;
10117c478bd9Sstevel@tonic-gate 			vsap->vsa_aclentp = acl.fattr4_acl_val;
10127c478bd9Sstevel@tonic-gate 			vsap->vsa_mask = VSA_ACE | VSA_ACECNT;
1013da6c28aaSamw 			vsap->vsa_aclentsz = vsap->vsa_aclcnt * sizeof (ace_t);
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate 		}
10167c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
10177c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_aclsupport))
10187c478bd9Sstevel@tonic-gate 				return (FALSE);
10197c478bd9Sstevel@tonic-gate 		}
10207c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ARCHIVE_MASK) {
10217c478bd9Sstevel@tonic-gate 			ASSERT(0);
10227c478bd9Sstevel@tonic-gate 		}
10237c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CANSETTIME_MASK) {
10247c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
10257c478bd9Sstevel@tonic-gate 				return (FALSE);
10267c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_cansettime =
10277c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
10287c478bd9Sstevel@tonic-gate 		}
10297c478bd9Sstevel@tonic-gate 	}
10307c478bd9Sstevel@tonic-gate 	if (resbmap &
10317c478bd9Sstevel@tonic-gate 	    (FATTR4_CASE_INSENSITIVE_MASK |
10327c478bd9Sstevel@tonic-gate 	    FATTR4_CASE_PRESERVING_MASK |
10337c478bd9Sstevel@tonic-gate 	    FATTR4_CHOWN_RESTRICTED_MASK |
10347c478bd9Sstevel@tonic-gate 	    FATTR4_FILEHANDLE_MASK |
10357c478bd9Sstevel@tonic-gate 	    FATTR4_FILEID_MASK |
10367c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_AVAIL_MASK |
10377c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_FREE_MASK |
10387c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_TOTAL_MASK)) {
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
10417c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
10427c478bd9Sstevel@tonic-gate 				return (FALSE);
10437c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_insensitive =
10447c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
10457c478bd9Sstevel@tonic-gate 		}
10467c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
10477c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
10487c478bd9Sstevel@tonic-gate 				return (FALSE);
10497c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_preserving =
10507c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
10517c478bd9Sstevel@tonic-gate 		}
10527c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
10537c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
10547c478bd9Sstevel@tonic-gate 				return (FALSE);
10557c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_chown_restricted =
10567c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
10577c478bd9Sstevel@tonic-gate 		}
10587c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
10597c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
10607c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.val =
10617c478bd9Sstevel@tonic-gate 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
10627c478bd9Sstevel@tonic-gate 			if (!xdr_bytes(xdrs,
10637c478bd9Sstevel@tonic-gate 			    (char **)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_val,
10647c478bd9Sstevel@tonic-gate 			    (uint_t *)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_len,
10657c478bd9Sstevel@tonic-gate 			    NFS4_FHSIZE))
10667c478bd9Sstevel@tonic-gate 				return (FALSE);
10677c478bd9Sstevel@tonic-gate 		}
10687c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEID_MASK) {
10697c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
10707c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&vap->va_nodeid))
10717c478bd9Sstevel@tonic-gate 				return (FALSE);
10727c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NODEID;
10737c478bd9Sstevel@tonic-gate 		}
10747c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
10757c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
10767c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_sb.f_favail))
10777c478bd9Sstevel@tonic-gate 				return (FALSE);
10787c478bd9Sstevel@tonic-gate 		}
10797c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_FREE_MASK) {
10807c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
10817c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_sb.f_ffree))
10827c478bd9Sstevel@tonic-gate 				return (FALSE);
10837c478bd9Sstevel@tonic-gate 		}
10847c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
10857c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
10867c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_sb.f_files))
10877c478bd9Sstevel@tonic-gate 				return (FALSE);
10887c478bd9Sstevel@tonic-gate 		}
10897c478bd9Sstevel@tonic-gate 	}
10907c478bd9Sstevel@tonic-gate 	if (resbmap &
10917c478bd9Sstevel@tonic-gate 	    (FATTR4_FS_LOCATIONS_MASK |
10927c478bd9Sstevel@tonic-gate 	    FATTR4_HIDDEN_MASK |
10937c478bd9Sstevel@tonic-gate 	    FATTR4_HOMOGENEOUS_MASK)) {
10947c478bd9Sstevel@tonic-gate 
10957c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
10962f172c55SRobert Thurlow 			if (!xdr_fattr4_fs_locations(xdrs,
10972f172c55SRobert Thurlow 			    &gesp->n4g_fslocations))
10982f172c55SRobert Thurlow 				return (FALSE);
10997c478bd9Sstevel@tonic-gate 		}
11007c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HIDDEN_MASK) {
11017c478bd9Sstevel@tonic-gate 			ASSERT(0);
11027c478bd9Sstevel@tonic-gate 		}
11037c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
11047c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
11057c478bd9Sstevel@tonic-gate 				return (FALSE);
11067c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_homogeneous =
11077c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
11087c478bd9Sstevel@tonic-gate 		}
11097c478bd9Sstevel@tonic-gate 	}
11107c478bd9Sstevel@tonic-gate 	if (resbmap &
11117c478bd9Sstevel@tonic-gate 	    (FATTR4_MAXFILESIZE_MASK |
11127c478bd9Sstevel@tonic-gate 	    FATTR4_MAXLINK_MASK |
11137c478bd9Sstevel@tonic-gate 	    FATTR4_MAXNAME_MASK |
11147c478bd9Sstevel@tonic-gate 	    FATTR4_MAXREAD_MASK |
11157c478bd9Sstevel@tonic-gate 	    FATTR4_MAXWRITE_MASK)) {
11167c478bd9Sstevel@tonic-gate 
11177c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
11187c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
11197c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_maxfilesize))
11207c478bd9Sstevel@tonic-gate 				return (FALSE);
11217c478bd9Sstevel@tonic-gate 		}
11227c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXLINK_MASK) {
11237c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs,
11247c478bd9Sstevel@tonic-gate 			    (int *)&gesp->n4g_pc4.pc4_link_max))
11257c478bd9Sstevel@tonic-gate 				return (FALSE);
11267c478bd9Sstevel@tonic-gate 		}
11277c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXNAME_MASK) {
11287c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs,
11297c478bd9Sstevel@tonic-gate 			    (int *)&gesp->n4g_pc4.pc4_name_max))
11307c478bd9Sstevel@tonic-gate 				return (FALSE);
11317c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
11327c478bd9Sstevel@tonic-gate 		}
11337c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXREAD_MASK) {
11347c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
11357c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_maxread))
11367c478bd9Sstevel@tonic-gate 				return (FALSE);
11377c478bd9Sstevel@tonic-gate 		}
11387c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXWRITE_MASK) {
11397c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
11407c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_maxwrite))
11417c478bd9Sstevel@tonic-gate 				return (FALSE);
11427c478bd9Sstevel@tonic-gate 		}
11437c478bd9Sstevel@tonic-gate 	}
11447c478bd9Sstevel@tonic-gate 	if (resbmap &
11457c478bd9Sstevel@tonic-gate 	    (FATTR4_MIMETYPE_MASK |
11467c478bd9Sstevel@tonic-gate 	    FATTR4_MODE_MASK |
11477c478bd9Sstevel@tonic-gate 	    FATTR4_NO_TRUNC_MASK |
11487c478bd9Sstevel@tonic-gate 	    FATTR4_NUMLINKS_MASK)) {
11497c478bd9Sstevel@tonic-gate 
11507c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MIMETYPE_MASK) {
11517c478bd9Sstevel@tonic-gate 			ASSERT(0);
11527c478bd9Sstevel@tonic-gate 		}
11537c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MODE_MASK) {
11547c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_mode))
11557c478bd9Sstevel@tonic-gate 				return (FALSE);
11567c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MODE;
11577c478bd9Sstevel@tonic-gate 		}
11587c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
11597c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
11607c478bd9Sstevel@tonic-gate 				return (FALSE);
11617c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_no_trunc =
11627c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
11637c478bd9Sstevel@tonic-gate 		}
11647c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NUMLINKS_MASK) {
11657c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_nlink))
11667c478bd9Sstevel@tonic-gate 				return (FALSE);
11677c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NLINK;
11687c478bd9Sstevel@tonic-gate 		}
11697c478bd9Sstevel@tonic-gate 	}
11707c478bd9Sstevel@tonic-gate 	if (resbmap &
11717c478bd9Sstevel@tonic-gate 	    (FATTR4_OWNER_MASK |
11727c478bd9Sstevel@tonic-gate 	    FATTR4_OWNER_GROUP_MASK |
11737c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
11747c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
11757c478bd9Sstevel@tonic-gate 
11767c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_MASK) {
11777c478bd9Sstevel@tonic-gate 			uint_t *owner_length, ol;
11787c478bd9Sstevel@tonic-gate 			char *owner_val = NULL;
11797c478bd9Sstevel@tonic-gate 			char *owner_alloc = NULL;
11807c478bd9Sstevel@tonic-gate 			utf8string ov;
11817c478bd9Sstevel@tonic-gate 			int error;
11827c478bd9Sstevel@tonic-gate 
11837c478bd9Sstevel@tonic-gate 			/* get the OWNER_LENGTH */
11847c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &ol))
11857c478bd9Sstevel@tonic-gate 				return (FALSE);
11867c478bd9Sstevel@tonic-gate 
11877c478bd9Sstevel@tonic-gate 			/* Manage the owner length location */
11887c478bd9Sstevel@tonic-gate 			if (pug && ol <= MAX_OG_NAME) {
11897c478bd9Sstevel@tonic-gate 				owner_length = &pug->u_curr.utf8string_len;
11907c478bd9Sstevel@tonic-gate 				*owner_length = ol;
11917c478bd9Sstevel@tonic-gate 			} else {
11927c478bd9Sstevel@tonic-gate 				owner_length = &ol;
11937c478bd9Sstevel@tonic-gate 			}
11947c478bd9Sstevel@tonic-gate 
11957c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
11967c478bd9Sstevel@tonic-gate 			if (*owner_length > MAX_OG_NAME || pug == NULL)
11977c478bd9Sstevel@tonic-gate 				owner_val = owner_alloc =
11987c478bd9Sstevel@tonic-gate 				    kmem_alloc(*owner_length, KM_SLEEP);
11997c478bd9Sstevel@tonic-gate 			else
12007c478bd9Sstevel@tonic-gate 				owner_val = pug->u_curr.utf8string_val;
12017c478bd9Sstevel@tonic-gate 
12027c478bd9Sstevel@tonic-gate 			/* get the OWNER string */
12037c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, owner_val, *owner_length)) {
12047c478bd9Sstevel@tonic-gate 				if (owner_alloc)
12057c478bd9Sstevel@tonic-gate 					kmem_free(owner_alloc, *owner_length);
12067c478bd9Sstevel@tonic-gate 				return (FALSE);
12077c478bd9Sstevel@tonic-gate 			}
12087c478bd9Sstevel@tonic-gate 
12097c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
12107c478bd9Sstevel@tonic-gate 			if (pug &&
12117c478bd9Sstevel@tonic-gate 			    *owner_length == pug->u_last.utf8string_len &&
12127c478bd9Sstevel@tonic-gate 			    bcmp(owner_val, pug->u_last.utf8string_val,
12137c478bd9Sstevel@tonic-gate 			    *owner_length) == 0) {
12147c478bd9Sstevel@tonic-gate 				vap->va_uid = pug->uid;
12157c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_UID;
12167c478bd9Sstevel@tonic-gate 			} else {
12177c478bd9Sstevel@tonic-gate 				uid_t uid;
12187c478bd9Sstevel@tonic-gate 
12197c478bd9Sstevel@tonic-gate 				ov.utf8string_len = *owner_length;
12207c478bd9Sstevel@tonic-gate 				ov.utf8string_val = owner_val;
12217c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
12227c478bd9Sstevel@tonic-gate 				/*
12237c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
12247c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
12257c478bd9Sstevel@tonic-gate 				 * be cached.
12267c478bd9Sstevel@tonic-gate 				 */
12277c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
12287c478bd9Sstevel@tonic-gate 					error = 0;
12297c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
12307c478bd9Sstevel@tonic-gate 					    NFS4_GETATTR_NOCACHE_OK;
12317c478bd9Sstevel@tonic-gate 				}
12327c478bd9Sstevel@tonic-gate 
12337c478bd9Sstevel@tonic-gate 				if (error) {
12347c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
12357c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
12367c478bd9Sstevel@tonic-gate 					    NFS4_GETATTR_ATUID_ERR;
12377c478bd9Sstevel@tonic-gate 				} else {
12387c478bd9Sstevel@tonic-gate 					vap->va_uid = uid;
12397c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_UID;
12407c478bd9Sstevel@tonic-gate 					if (pug && ol <= MAX_OG_NAME) {
12417c478bd9Sstevel@tonic-gate 						pug->uid = uid;
12427c478bd9Sstevel@tonic-gate 						U_SWAP_CURR_LAST(pug);
12437c478bd9Sstevel@tonic-gate 					}
12447c478bd9Sstevel@tonic-gate 				}
12457c478bd9Sstevel@tonic-gate 				if (owner_alloc)
12467c478bd9Sstevel@tonic-gate 					kmem_free(owner_alloc, *owner_length);
12477c478bd9Sstevel@tonic-gate 			}
12487c478bd9Sstevel@tonic-gate 		}
12497c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
12507c478bd9Sstevel@tonic-gate 			uint_t *group_length, gl;
12517c478bd9Sstevel@tonic-gate 			char *group_val = NULL;
12527c478bd9Sstevel@tonic-gate 			char *group_alloc = NULL;
12537c478bd9Sstevel@tonic-gate 			utf8string gv;
12547c478bd9Sstevel@tonic-gate 			int error;
12557c478bd9Sstevel@tonic-gate 
12567c478bd9Sstevel@tonic-gate 			/* get the OWNER_GROUP_LENGTH */
12577c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &gl))
12587c478bd9Sstevel@tonic-gate 				return (FALSE);
12597c478bd9Sstevel@tonic-gate 
12607c478bd9Sstevel@tonic-gate 			/* Manage the group length location */
12617c478bd9Sstevel@tonic-gate 			if (pug && gl <= MAX_OG_NAME) {
12627c478bd9Sstevel@tonic-gate 				group_length = &pug->g_curr.utf8string_len;
12637c478bd9Sstevel@tonic-gate 				*group_length = gl;
12647c478bd9Sstevel@tonic-gate 			} else {
12657c478bd9Sstevel@tonic-gate 				group_length = &gl;
12667c478bd9Sstevel@tonic-gate 			}
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
12697c478bd9Sstevel@tonic-gate 			if (*group_length > MAX_OG_NAME || pug == NULL)
12707c478bd9Sstevel@tonic-gate 				group_val = group_alloc =
12717c478bd9Sstevel@tonic-gate 				    kmem_alloc(*group_length, KM_SLEEP);
12727c478bd9Sstevel@tonic-gate 			else
12737c478bd9Sstevel@tonic-gate 				group_val = pug->g_curr.utf8string_val;
12747c478bd9Sstevel@tonic-gate 
12757c478bd9Sstevel@tonic-gate 			/* get the OWNER_GROUP string */
12767c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, group_val, *group_length)) {
12777c478bd9Sstevel@tonic-gate 				if (group_alloc)
12787c478bd9Sstevel@tonic-gate 					kmem_free(group_alloc, *group_length);
12797c478bd9Sstevel@tonic-gate 				return (FALSE);
12807c478bd9Sstevel@tonic-gate 			}
12817c478bd9Sstevel@tonic-gate 
12827c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
12837c478bd9Sstevel@tonic-gate 			if (pug &&
12847c478bd9Sstevel@tonic-gate 			    *group_length == pug->g_last.utf8string_len &&
12857c478bd9Sstevel@tonic-gate 			    bcmp(group_val, pug->g_last.utf8string_val,
12867c478bd9Sstevel@tonic-gate 			    *group_length) == 0) {
12877c478bd9Sstevel@tonic-gate 				vap->va_gid = pug->gid;
12887c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_GID;
12897c478bd9Sstevel@tonic-gate 			} else {
12907c478bd9Sstevel@tonic-gate 				uid_t gid;
12917c478bd9Sstevel@tonic-gate 
12927c478bd9Sstevel@tonic-gate 				gv.utf8string_len = *group_length;
12937c478bd9Sstevel@tonic-gate 				gv.utf8string_val = group_val;
12947c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
12957c478bd9Sstevel@tonic-gate 				/*
12967c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
12977c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
12987c478bd9Sstevel@tonic-gate 				 * be cached.
12997c478bd9Sstevel@tonic-gate 				 */
13007c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
13017c478bd9Sstevel@tonic-gate 					error = 0;
13027c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
13037c478bd9Sstevel@tonic-gate 					    NFS4_GETATTR_NOCACHE_OK;
13047c478bd9Sstevel@tonic-gate 				}
13057c478bd9Sstevel@tonic-gate 
13067c478bd9Sstevel@tonic-gate 				if (error) {
13077c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
13087c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
13097c478bd9Sstevel@tonic-gate 					    NFS4_GETATTR_ATGID_ERR;
13107c478bd9Sstevel@tonic-gate 				} else {
13117c478bd9Sstevel@tonic-gate 					vap->va_gid = gid;
13127c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_GID;
13137c478bd9Sstevel@tonic-gate 					if (pug && gl <= MAX_OG_NAME) {
13147c478bd9Sstevel@tonic-gate 						pug->gid = gid;
13157c478bd9Sstevel@tonic-gate 						G_SWAP_CURR_LAST(pug);
13167c478bd9Sstevel@tonic-gate 					}
13177c478bd9Sstevel@tonic-gate 				}
13187c478bd9Sstevel@tonic-gate 				if (group_alloc) {
13197c478bd9Sstevel@tonic-gate 					kmem_free(group_alloc, *group_length);
13207c478bd9Sstevel@tonic-gate 				}
13217c478bd9Sstevel@tonic-gate 			}
13227c478bd9Sstevel@tonic-gate 		}
13237c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
13247c478bd9Sstevel@tonic-gate 			ASSERT(0);
13257c478bd9Sstevel@tonic-gate 		}
13267c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
13277c478bd9Sstevel@tonic-gate 			ASSERT(0);
13287c478bd9Sstevel@tonic-gate 		}
13297c478bd9Sstevel@tonic-gate 	}
13307c478bd9Sstevel@tonic-gate 	if (resbmap &
13317c478bd9Sstevel@tonic-gate 	    (FATTR4_QUOTA_USED_MASK |
13327c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_AVAIL_MASK |
13337c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_FREE_MASK |
13347c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_TOTAL_MASK |
13357c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_USED_MASK |
13367c478bd9Sstevel@tonic-gate 	    FATTR4_SYSTEM_MASK)) {
13377c478bd9Sstevel@tonic-gate 
13387c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
13397c478bd9Sstevel@tonic-gate 			ASSERT(0);
13407c478bd9Sstevel@tonic-gate 		}
13417c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RAWDEV_MASK) {
13427c478bd9Sstevel@tonic-gate 			fattr4_rawdev rawdev;
13437c478bd9Sstevel@tonic-gate 			if (!xdr_fattr4_rawdev(xdrs, &rawdev))
13447c478bd9Sstevel@tonic-gate 				return (FALSE);
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
13477c478bd9Sstevel@tonic-gate 				vap->va_rdev = makedevice(rawdev.specdata1,
13487c478bd9Sstevel@tonic-gate 				    rawdev.specdata2);
13497c478bd9Sstevel@tonic-gate 			} else {
13507c478bd9Sstevel@tonic-gate 				vap->va_rdev = 0;
13517c478bd9Sstevel@tonic-gate 			}
13527c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_RDEV;
13537c478bd9Sstevel@tonic-gate 		}
13547c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
13557c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
13567c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_sb.f_bavail))
13577c478bd9Sstevel@tonic-gate 				return (FALSE);
13587c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
13597c478bd9Sstevel@tonic-gate 		}
13607c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
13617c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
13627c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_sb.f_bfree))
13637c478bd9Sstevel@tonic-gate 				return (FALSE);
13647c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
13657c478bd9Sstevel@tonic-gate 		}
13667c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
13677c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
13687c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_sb.f_blocks))
13697c478bd9Sstevel@tonic-gate 				return (FALSE);
13707c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
13717c478bd9Sstevel@tonic-gate 		}
13727c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_USED_MASK) {
13737c478bd9Sstevel@tonic-gate 			uint64_t space_used;
13747c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
13757c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&space_used))
13767c478bd9Sstevel@tonic-gate 				return (FALSE);
13777c478bd9Sstevel@tonic-gate 
13787c478bd9Sstevel@tonic-gate 			/* Compute space depending on device type */
13797c478bd9Sstevel@tonic-gate 			ASSERT((vap->va_mask & AT_TYPE));
13807c478bd9Sstevel@tonic-gate 			if (vap->va_type == VREG || vap->va_type == VDIR ||
13817c478bd9Sstevel@tonic-gate 			    vap->va_type == VLNK) {
13827c478bd9Sstevel@tonic-gate 				vap->va_nblocks = (u_longlong_t)
13837c478bd9Sstevel@tonic-gate 				    ((space_used + (offset4)DEV_BSIZE -
13847c478bd9Sstevel@tonic-gate 				    (offset4)1) / (offset4)DEV_BSIZE);
13857c478bd9Sstevel@tonic-gate 			} else {
13867c478bd9Sstevel@tonic-gate 				vap->va_nblocks = 0;
13877c478bd9Sstevel@tonic-gate 			}
13887c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NBLOCKS;
13897c478bd9Sstevel@tonic-gate 		}
13907c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYSTEM_MASK) {
13917c478bd9Sstevel@tonic-gate 			ASSERT(0);
13927c478bd9Sstevel@tonic-gate 		}
13937c478bd9Sstevel@tonic-gate 	}
13947c478bd9Sstevel@tonic-gate 	if (resbmap &
13957c478bd9Sstevel@tonic-gate 	    (FATTR4_TIME_ACCESS_MASK |
13967c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_ACCESS_SET_MASK |
13977c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_BACKUP_MASK |
13987c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_CREATE_MASK |
13997c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_DELTA_MASK |
14007c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_METADATA_MASK |
14017c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_MASK |
14027c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_SET_MASK |
14037c478bd9Sstevel@tonic-gate 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
14047c478bd9Sstevel@tonic-gate 
14057c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
14067c478bd9Sstevel@tonic-gate 			nfstime4 atime;
14077c478bd9Sstevel@tonic-gate 			int error;
14087c478bd9Sstevel@tonic-gate 
14097c478bd9Sstevel@tonic-gate 			if (!xdr_longlong_t(xdrs,
14107c478bd9Sstevel@tonic-gate 			    (longlong_t *)&atime.seconds))
14117c478bd9Sstevel@tonic-gate 				return (FALSE);
14127c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int *)&atime.nseconds))
14137c478bd9Sstevel@tonic-gate 				return (FALSE);
14147c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&atime, &vap->va_atime);
14157c478bd9Sstevel@tonic-gate 			if (error) {
14167c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
14177c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
14187c478bd9Sstevel@tonic-gate 			}
14197c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_ATIME;
14207c478bd9Sstevel@tonic-gate 		}
14217c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
14227c478bd9Sstevel@tonic-gate 			ASSERT(0);
14237c478bd9Sstevel@tonic-gate 		}
14247c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
14257c478bd9Sstevel@tonic-gate 			ASSERT(0);
14267c478bd9Sstevel@tonic-gate 		}
14277c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
14287c478bd9Sstevel@tonic-gate 			ASSERT(0);
14297c478bd9Sstevel@tonic-gate 		}
14307c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
14317c478bd9Sstevel@tonic-gate 			if ((!xdr_u_longlong_t(xdrs,
14327c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&gesp->n4g_delta.seconds)) ||
14337c478bd9Sstevel@tonic-gate 			    (!xdr_u_int(xdrs, &gesp->n4g_delta.nseconds)))
14347c478bd9Sstevel@tonic-gate 				return (FALSE);
14357c478bd9Sstevel@tonic-gate 		}
14367c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
14377c478bd9Sstevel@tonic-gate 			nfstime4 mdt;
14387c478bd9Sstevel@tonic-gate 			int error;
14397c478bd9Sstevel@tonic-gate 
14407c478bd9Sstevel@tonic-gate 			if (!xdr_longlong_t(xdrs, (longlong_t *)&mdt.seconds))
14417c478bd9Sstevel@tonic-gate 				return (FALSE);
14427c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&mdt.nseconds))
14437c478bd9Sstevel@tonic-gate 				return (FALSE);
14447c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
14457c478bd9Sstevel@tonic-gate 			if (error) {
14467c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
14477c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
14487c478bd9Sstevel@tonic-gate 			}
14497c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_CTIME;
14507c478bd9Sstevel@tonic-gate 		}
14517c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
14527c478bd9Sstevel@tonic-gate 			nfstime4 mtime;
14537c478bd9Sstevel@tonic-gate 			int error;
14547c478bd9Sstevel@tonic-gate 
14557c478bd9Sstevel@tonic-gate 			if (!xdr_longlong_t(xdrs,
14567c478bd9Sstevel@tonic-gate 			    (longlong_t *)&mtime.seconds))
14577c478bd9Sstevel@tonic-gate 				return (FALSE);
14587c478bd9Sstevel@tonic-gate 			if (!XDR_GETINT32(xdrs, (int32_t *)&mtime.nseconds))
14597c478bd9Sstevel@tonic-gate 				return (FALSE);
14607c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
14617c478bd9Sstevel@tonic-gate 			if (error) {
14627c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
14637c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
14647c478bd9Sstevel@tonic-gate 			}
14657c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MTIME;
14667c478bd9Sstevel@tonic-gate 		}
14677c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
14687c478bd9Sstevel@tonic-gate 			ASSERT(0);
14697c478bd9Sstevel@tonic-gate 		}
14707c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
14717c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
14727c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&garp->n4g_mon_fid))
14737c478bd9Sstevel@tonic-gate 				return (FALSE);
14747c478bd9Sstevel@tonic-gate 			garp->n4g_mon_fid_valid = 1;
14757c478bd9Sstevel@tonic-gate 		}
14767c478bd9Sstevel@tonic-gate 	}
14777c478bd9Sstevel@tonic-gate 
14787c478bd9Sstevel@tonic-gate 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
14797c478bd9Sstevel@tonic-gate 		/* copy only if not provided */
14807c478bd9Sstevel@tonic-gate 		if (garp->n4g_ext_res == NULL) {
14817c478bd9Sstevel@tonic-gate 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
14827c478bd9Sstevel@tonic-gate 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
14837c478bd9Sstevel@tonic-gate 		}
14847c478bd9Sstevel@tonic-gate 	}
14857c478bd9Sstevel@tonic-gate 
14867c478bd9Sstevel@tonic-gate 	return (TRUE);
14877c478bd9Sstevel@tonic-gate }
14887c478bd9Sstevel@tonic-gate 
14897c478bd9Sstevel@tonic-gate /*
14907c478bd9Sstevel@tonic-gate  * Inlined version of get_bitmap4 processing
14917c478bd9Sstevel@tonic-gate  */
14927c478bd9Sstevel@tonic-gate bitmap4
14937c478bd9Sstevel@tonic-gate xdr_get_bitmap4_inline(uint32_t **iptr)
14947c478bd9Sstevel@tonic-gate {
14957c478bd9Sstevel@tonic-gate 	uint32_t resbmaplen;
14967c478bd9Sstevel@tonic-gate 	bitmap4 bm;
14977c478bd9Sstevel@tonic-gate 	uint32_t *ptr = *iptr;
14987c478bd9Sstevel@tonic-gate 
14997c478bd9Sstevel@tonic-gate 	/* bitmap LENGTH */
15007c478bd9Sstevel@tonic-gate 	resbmaplen = IXDR_GET_U_INT32(ptr);
15017c478bd9Sstevel@tonic-gate 
15027c478bd9Sstevel@tonic-gate 	/* Inline the bitmap and attrlen for common case of two word map */
15037c478bd9Sstevel@tonic-gate 	if (resbmaplen == 2) {
15047c478bd9Sstevel@tonic-gate 		IXDR_GET_HYPER(ptr, bm);
15057c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15067c478bd9Sstevel@tonic-gate 		return (bm);
15077c478bd9Sstevel@tonic-gate 	}
15087c478bd9Sstevel@tonic-gate 
15097c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
15107c478bd9Sstevel@tonic-gate 	bm = IXDR_GET_U_INT32(ptr);
15117c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
15127c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15137c478bd9Sstevel@tonic-gate 		return (bm);
15147c478bd9Sstevel@tonic-gate 	}
15157c478bd9Sstevel@tonic-gate 	*((uint32_t *)&bm) |= IXDR_GET_U_INT32(ptr);
15167c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
15177c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15187c478bd9Sstevel@tonic-gate 		return (bm);
15197c478bd9Sstevel@tonic-gate 	}
15207c478bd9Sstevel@tonic-gate 	ptr += resbmaplen;
15217c478bd9Sstevel@tonic-gate 	*iptr = ptr;
15227c478bd9Sstevel@tonic-gate 	return (bm);
15237c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN)
15247c478bd9Sstevel@tonic-gate 	*((uint32_t *)&bm) = IXDR_GET_U_INT32(ptr);
15257c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
15267c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15277c478bd9Sstevel@tonic-gate 		return (bm);
15287c478bd9Sstevel@tonic-gate 	}
15297c478bd9Sstevel@tonic-gate 	bm |= IXDR_GET_U_INT32(ptr);
15307c478bd9Sstevel@tonic-gate 	if (--resbmaplen == 0) {
15317c478bd9Sstevel@tonic-gate 		*iptr = ptr;
15327c478bd9Sstevel@tonic-gate 		return (bm);
15337c478bd9Sstevel@tonic-gate 	}
15347c478bd9Sstevel@tonic-gate 	ptr += resbmaplen;
15357c478bd9Sstevel@tonic-gate 	*iptr = ptr;
15367c478bd9Sstevel@tonic-gate 	return (bm);
15377c478bd9Sstevel@tonic-gate #else
15387c478bd9Sstevel@tonic-gate 	ASSERT(0);
15397c478bd9Sstevel@tonic-gate 	ptr += resbmaplen;
15407c478bd9Sstevel@tonic-gate 	*iptr = ptr;
15417c478bd9Sstevel@tonic-gate 	return (0);
15427c478bd9Sstevel@tonic-gate #endif
15437c478bd9Sstevel@tonic-gate }
15447c478bd9Sstevel@tonic-gate 
15457c478bd9Sstevel@tonic-gate static bool_t
15467c478bd9Sstevel@tonic-gate xdr_ga_fattr_res_inline(uint32_t *ptr, struct nfs4_ga_res *garp,
15477c478bd9Sstevel@tonic-gate 			bitmap4 resbmap, bitmap4 argbmap, struct mntinfo4 *mi,
15487c478bd9Sstevel@tonic-gate 			ug_cache_t *pug)
15497c478bd9Sstevel@tonic-gate {
15507c478bd9Sstevel@tonic-gate 	int truefalse;
15517c478bd9Sstevel@tonic-gate 	struct nfs4_ga_ext_res ges, *gesp;
15527c478bd9Sstevel@tonic-gate 	vattr_t *vap = &garp->n4g_va;
15537c478bd9Sstevel@tonic-gate 
15547c478bd9Sstevel@tonic-gate 	if (garp->n4g_ext_res)
15557c478bd9Sstevel@tonic-gate 		gesp = garp->n4g_ext_res;
15567c478bd9Sstevel@tonic-gate 	else
15577c478bd9Sstevel@tonic-gate 		gesp = &ges;
15587c478bd9Sstevel@tonic-gate 
15597c478bd9Sstevel@tonic-gate 	vap->va_mask = 0;
15607c478bd9Sstevel@tonic-gate 
15617c478bd9Sstevel@tonic-gate 	/* Check to see if the vattr should be pre-filled */
15627c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_VATTR_MASK)
15637c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_vattr(garp, mi);
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate 	if (argbmap & NFS4_STATFS_ATTR_MASK)
15667c478bd9Sstevel@tonic-gate 		xdr_ga_prefill_statvfs(gesp, mi);
15677c478bd9Sstevel@tonic-gate 
15687c478bd9Sstevel@tonic-gate 	if (resbmap &
15697c478bd9Sstevel@tonic-gate 	    (FATTR4_SUPPORTED_ATTRS_MASK |
15707c478bd9Sstevel@tonic-gate 	    FATTR4_TYPE_MASK |
15717c478bd9Sstevel@tonic-gate 	    FATTR4_FH_EXPIRE_TYPE_MASK |
15727c478bd9Sstevel@tonic-gate 	    FATTR4_CHANGE_MASK |
15737c478bd9Sstevel@tonic-gate 	    FATTR4_SIZE_MASK |
15747c478bd9Sstevel@tonic-gate 	    FATTR4_LINK_SUPPORT_MASK |
15757c478bd9Sstevel@tonic-gate 	    FATTR4_SYMLINK_SUPPORT_MASK |
15767c478bd9Sstevel@tonic-gate 	    FATTR4_NAMED_ATTR_MASK)) {
15777c478bd9Sstevel@tonic-gate 
15787c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
15797c478bd9Sstevel@tonic-gate 			gesp->n4g_suppattrs = xdr_get_bitmap4_inline(&ptr);
15807c478bd9Sstevel@tonic-gate 		}
15817c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TYPE_MASK) {
15827c478bd9Sstevel@tonic-gate 			vap->va_type = IXDR_GET_U_INT32(ptr);
15837c478bd9Sstevel@tonic-gate 
15842c2d21e9SRichard Lowe 			if ((nfs_ftype4)vap->va_type < NF4REG ||
15852c2d21e9SRichard Lowe 			    (nfs_ftype4)vap->va_type > NF4NAMEDATTR)
15867c478bd9Sstevel@tonic-gate 				vap->va_type = VBAD;
15877c478bd9Sstevel@tonic-gate 			else
15887c478bd9Sstevel@tonic-gate 				vap->va_type = nf4_to_vt[vap->va_type];
15897c478bd9Sstevel@tonic-gate 			if (vap->va_type == VBLK)
15907c478bd9Sstevel@tonic-gate 				vap->va_blksize = DEV_BSIZE;
15917c478bd9Sstevel@tonic-gate 
15927c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_TYPE;
15937c478bd9Sstevel@tonic-gate 		}
15947c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
15957c478bd9Sstevel@tonic-gate 			gesp->n4g_fet = IXDR_GET_U_INT32(ptr);
15967c478bd9Sstevel@tonic-gate 		}
15977c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHANGE_MASK) {
15987c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_change);
15997c478bd9Sstevel@tonic-gate 			garp->n4g_change_valid = 1;
16007c478bd9Sstevel@tonic-gate 		}
16017c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SIZE_MASK) {
16027c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, vap->va_size);
16037c478bd9Sstevel@tonic-gate 
16047c478bd9Sstevel@tonic-gate 			if (!NFS4_SIZE_OK(vap->va_size)) {
16057c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = EFBIG;
16067c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
16077c478bd9Sstevel@tonic-gate 			} else {
16087c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_SIZE;
16097c478bd9Sstevel@tonic-gate 			}
16107c478bd9Sstevel@tonic-gate 		}
16117c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
16127c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16137c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_link_support =
16147c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
16157c478bd9Sstevel@tonic-gate 		}
16167c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
16177c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16187c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_symlink_support =
16197c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
16207c478bd9Sstevel@tonic-gate 		}
16217c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
16227c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16237c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
16247c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_xattr_exists =
16257c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
16267c478bd9Sstevel@tonic-gate 		}
16277c478bd9Sstevel@tonic-gate 	}
16287c478bd9Sstevel@tonic-gate 	if (resbmap &
16297c478bd9Sstevel@tonic-gate 	    (FATTR4_FSID_MASK |
16307c478bd9Sstevel@tonic-gate 	    FATTR4_UNIQUE_HANDLES_MASK |
16317c478bd9Sstevel@tonic-gate 	    FATTR4_LEASE_TIME_MASK |
16327c478bd9Sstevel@tonic-gate 	    FATTR4_RDATTR_ERROR_MASK)) {
16337c478bd9Sstevel@tonic-gate 
16347c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FSID_MASK) {
16357c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.major);
16367c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.minor);
16377c478bd9Sstevel@tonic-gate 			garp->n4g_fsid_valid = 1;
16387c478bd9Sstevel@tonic-gate 		}
16397c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
16407c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16417c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_unique_handles =
16427c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
16437c478bd9Sstevel@tonic-gate 		}
16447c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
16457c478bd9Sstevel@tonic-gate 			gesp->n4g_leasetime = IXDR_GET_U_INT32(ptr);
16467c478bd9Sstevel@tonic-gate 		}
16477c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
16487c478bd9Sstevel@tonic-gate 			gesp->n4g_rdattr_error = IXDR_GET_U_INT32(ptr);
16497c478bd9Sstevel@tonic-gate 		}
16507c478bd9Sstevel@tonic-gate 	}
16517c478bd9Sstevel@tonic-gate 	if (resbmap &
16527c478bd9Sstevel@tonic-gate 	    (FATTR4_ACL_MASK |
16537c478bd9Sstevel@tonic-gate 	    FATTR4_ACLSUPPORT_MASK |
16547c478bd9Sstevel@tonic-gate 	    FATTR4_ARCHIVE_MASK |
16557c478bd9Sstevel@tonic-gate 	    FATTR4_CANSETTIME_MASK)) {
16567c478bd9Sstevel@tonic-gate 
16577c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACL_MASK) {
16587c478bd9Sstevel@tonic-gate 			ASSERT(0);
16597c478bd9Sstevel@tonic-gate 		}
16607c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
16617c478bd9Sstevel@tonic-gate 			gesp->n4g_aclsupport = IXDR_GET_U_INT32(ptr);
16627c478bd9Sstevel@tonic-gate 		}
16637c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_ARCHIVE_MASK) {
16647c478bd9Sstevel@tonic-gate 			ASSERT(0);
16657c478bd9Sstevel@tonic-gate 		}
16667c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CANSETTIME_MASK) {
16677c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16687c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_cansettime =
16697c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
16707c478bd9Sstevel@tonic-gate 		}
16717c478bd9Sstevel@tonic-gate 	}
16727c478bd9Sstevel@tonic-gate 	if (resbmap &
16737c478bd9Sstevel@tonic-gate 	    (FATTR4_CASE_INSENSITIVE_MASK |
16747c478bd9Sstevel@tonic-gate 	    FATTR4_CASE_PRESERVING_MASK |
16757c478bd9Sstevel@tonic-gate 	    FATTR4_CHOWN_RESTRICTED_MASK |
16767c478bd9Sstevel@tonic-gate 	    FATTR4_FILEHANDLE_MASK |
16777c478bd9Sstevel@tonic-gate 	    FATTR4_FILEID_MASK |
16787c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_AVAIL_MASK |
16797c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_FREE_MASK |
16807c478bd9Sstevel@tonic-gate 	    FATTR4_FILES_TOTAL_MASK)) {
16817c478bd9Sstevel@tonic-gate 
16827c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
16837c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16847c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_insensitive =
16857c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
16867c478bd9Sstevel@tonic-gate 		}
16877c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
16887c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16897c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_case_preserving =
16907c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
16917c478bd9Sstevel@tonic-gate 		}
16927c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
16937c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
16947c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_chown_restricted =
16957c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
16967c478bd9Sstevel@tonic-gate 		}
16977c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
16987c478bd9Sstevel@tonic-gate 			int len = IXDR_GET_U_INT32(ptr);
16997c478bd9Sstevel@tonic-gate 
17007c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
17017c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.nfs_fh4_alt.val =
17027c478bd9Sstevel@tonic-gate 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
17037c478bd9Sstevel@tonic-gate 			gesp->n4g_fh_u.n4g_fh.nfs_fh4_len = len;
17047c478bd9Sstevel@tonic-gate 
17057c478bd9Sstevel@tonic-gate 			bcopy(ptr, gesp->n4g_fh_u.n4g_fh.nfs_fh4_val, len);
17067c478bd9Sstevel@tonic-gate 
17077c478bd9Sstevel@tonic-gate 			ptr += RNDUP(len) / BYTES_PER_XDR_UNIT;
17087c478bd9Sstevel@tonic-gate 		}
17097c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILEID_MASK) {
17107c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
17117c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NODEID;
17127c478bd9Sstevel@tonic-gate 		}
17137c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
17147c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_favail);
17157c478bd9Sstevel@tonic-gate 		}
17167c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_FREE_MASK) {
17177c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_ffree);
17187c478bd9Sstevel@tonic-gate 		}
17197c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
17207c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_files);
17217c478bd9Sstevel@tonic-gate 		}
17227c478bd9Sstevel@tonic-gate 	}
17237c478bd9Sstevel@tonic-gate 	if (resbmap &
17247c478bd9Sstevel@tonic-gate 	    (FATTR4_FS_LOCATIONS_MASK |
17257c478bd9Sstevel@tonic-gate 	    FATTR4_HIDDEN_MASK |
17267c478bd9Sstevel@tonic-gate 	    FATTR4_HOMOGENEOUS_MASK)) {
17277c478bd9Sstevel@tonic-gate 
17287c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
17297c478bd9Sstevel@tonic-gate 			ASSERT(0);
17307c478bd9Sstevel@tonic-gate 		}
17317c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HIDDEN_MASK) {
17327c478bd9Sstevel@tonic-gate 			ASSERT(0);
17337c478bd9Sstevel@tonic-gate 		}
17347c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
17357c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
17367c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_homogeneous =
17377c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
17387c478bd9Sstevel@tonic-gate 		}
17397c478bd9Sstevel@tonic-gate 	}
17407c478bd9Sstevel@tonic-gate 	if (resbmap &
17417c478bd9Sstevel@tonic-gate 	    (FATTR4_MAXFILESIZE_MASK |
17427c478bd9Sstevel@tonic-gate 	    FATTR4_MAXLINK_MASK |
17437c478bd9Sstevel@tonic-gate 	    FATTR4_MAXNAME_MASK |
17447c478bd9Sstevel@tonic-gate 	    FATTR4_MAXREAD_MASK |
17457c478bd9Sstevel@tonic-gate 	    FATTR4_MAXWRITE_MASK)) {
17467c478bd9Sstevel@tonic-gate 
17477c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
17487c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxfilesize);
17497c478bd9Sstevel@tonic-gate 		}
17507c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXLINK_MASK) {
17517c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_link_max = IXDR_GET_U_INT32(ptr);
17527c478bd9Sstevel@tonic-gate 		}
17537c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXNAME_MASK) {
17547c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_name_max = IXDR_GET_U_INT32(ptr);
17557c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
17567c478bd9Sstevel@tonic-gate 		}
17577c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXREAD_MASK) {
17587c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxread);
17597c478bd9Sstevel@tonic-gate 		}
17607c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MAXWRITE_MASK) {
17617c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxwrite);
17627c478bd9Sstevel@tonic-gate 		}
17637c478bd9Sstevel@tonic-gate 	}
17647c478bd9Sstevel@tonic-gate 	if (resbmap &
17657c478bd9Sstevel@tonic-gate 	    (FATTR4_MIMETYPE_MASK |
17667c478bd9Sstevel@tonic-gate 	    FATTR4_MODE_MASK |
17677c478bd9Sstevel@tonic-gate 	    FATTR4_NO_TRUNC_MASK |
17687c478bd9Sstevel@tonic-gate 	    FATTR4_NUMLINKS_MASK)) {
17697c478bd9Sstevel@tonic-gate 
17707c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MIMETYPE_MASK) {
17717c478bd9Sstevel@tonic-gate 			ASSERT(0);
17727c478bd9Sstevel@tonic-gate 		}
17737c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MODE_MASK) {
17747c478bd9Sstevel@tonic-gate 			vap->va_mode = IXDR_GET_U_INT32(ptr);
17757c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MODE;
17767c478bd9Sstevel@tonic-gate 		}
17777c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
17787c478bd9Sstevel@tonic-gate 			truefalse = IXDR_GET_U_INT32(ptr);
17797c478bd9Sstevel@tonic-gate 			gesp->n4g_pc4.pc4_no_trunc =
17807c478bd9Sstevel@tonic-gate 			    (truefalse ? TRUE : FALSE);
17817c478bd9Sstevel@tonic-gate 		}
17827c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_NUMLINKS_MASK) {
17837c478bd9Sstevel@tonic-gate 			vap->va_nlink = IXDR_GET_U_INT32(ptr);
17847c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NLINK;
17857c478bd9Sstevel@tonic-gate 		}
17867c478bd9Sstevel@tonic-gate 	}
17877c478bd9Sstevel@tonic-gate 	if (resbmap &
17887c478bd9Sstevel@tonic-gate 	    (FATTR4_OWNER_MASK |
17897c478bd9Sstevel@tonic-gate 	    FATTR4_OWNER_GROUP_MASK |
17907c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
17917c478bd9Sstevel@tonic-gate 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
17927c478bd9Sstevel@tonic-gate 
17937c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_MASK) {
17947c478bd9Sstevel@tonic-gate 			uint_t *owner_length, ol;
17957c478bd9Sstevel@tonic-gate 			char *owner_val = NULL;
17967c478bd9Sstevel@tonic-gate 			utf8string ov;
17977c478bd9Sstevel@tonic-gate 			int error;
17987c478bd9Sstevel@tonic-gate 
17997c478bd9Sstevel@tonic-gate 			/* get the OWNER_LENGTH */
18007c478bd9Sstevel@tonic-gate 			ol = IXDR_GET_U_INT32(ptr);
18017c478bd9Sstevel@tonic-gate 
18027c478bd9Sstevel@tonic-gate 			/* Manage the owner length location */
18037c478bd9Sstevel@tonic-gate 			if (pug && ol <= MAX_OG_NAME) {
18047c478bd9Sstevel@tonic-gate 				owner_length = &pug->u_curr.utf8string_len;
18057c478bd9Sstevel@tonic-gate 				*owner_length = ol;
18067c478bd9Sstevel@tonic-gate 			} else {
18077c478bd9Sstevel@tonic-gate 				owner_length = &ol;
18087c478bd9Sstevel@tonic-gate 			}
18097c478bd9Sstevel@tonic-gate 
18107c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
18117c478bd9Sstevel@tonic-gate 			if (*owner_length > MAX_OG_NAME || pug == NULL)
18127c478bd9Sstevel@tonic-gate 				owner_val = (char *)ptr;
18137c478bd9Sstevel@tonic-gate 			else
18147c478bd9Sstevel@tonic-gate 				owner_val = (char *)ptr;
18157c478bd9Sstevel@tonic-gate 
18167c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
18177c478bd9Sstevel@tonic-gate 			if (pug &&
18187c478bd9Sstevel@tonic-gate 			    *owner_length == pug->u_last.utf8string_len &&
18197c478bd9Sstevel@tonic-gate 			    bcmp(owner_val, pug->u_last.utf8string_val,
18207c478bd9Sstevel@tonic-gate 			    *owner_length) == 0) {
18217c478bd9Sstevel@tonic-gate 				vap->va_uid = pug->uid;
18227c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_UID;
18237c478bd9Sstevel@tonic-gate 			} else {
18247c478bd9Sstevel@tonic-gate 				uid_t uid;
18257c478bd9Sstevel@tonic-gate 
18267c478bd9Sstevel@tonic-gate 				ov.utf8string_len = *owner_length;
18277c478bd9Sstevel@tonic-gate 				ov.utf8string_val = owner_val;
18287c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
18297c478bd9Sstevel@tonic-gate 				/*
18307c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
18317c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
18327c478bd9Sstevel@tonic-gate 				 * be cached.
18337c478bd9Sstevel@tonic-gate 				 */
18347c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
18357c478bd9Sstevel@tonic-gate 					error = 0;
18367c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
18377c478bd9Sstevel@tonic-gate 					    NFS4_GETATTR_NOCACHE_OK;
18387c478bd9Sstevel@tonic-gate 				}
18397c478bd9Sstevel@tonic-gate 
18407c478bd9Sstevel@tonic-gate 				if (error) {
18417c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
18427c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
18437c478bd9Sstevel@tonic-gate 					    NFS4_GETATTR_ATUID_ERR;
18447c478bd9Sstevel@tonic-gate 				} else {
18457c478bd9Sstevel@tonic-gate 					vap->va_uid = uid;
18467c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_UID;
18477c478bd9Sstevel@tonic-gate 					/* save the results for next time */
18487c478bd9Sstevel@tonic-gate 					if (pug && ol <= MAX_OG_NAME) {
18497c478bd9Sstevel@tonic-gate 						pug->uid = uid;
18507c478bd9Sstevel@tonic-gate 						pug->u_curr.utf8string_len =
18517c478bd9Sstevel@tonic-gate 						    ov.utf8string_len;
18527c478bd9Sstevel@tonic-gate 						bcopy(owner_val,
18530a701b1eSRobert Gordon 						    pug->u_curr.utf8string_val,
18540a701b1eSRobert Gordon 						    ol);
18557c478bd9Sstevel@tonic-gate 						U_SWAP_CURR_LAST(pug);
18567c478bd9Sstevel@tonic-gate 					}
18577c478bd9Sstevel@tonic-gate 				}
18587c478bd9Sstevel@tonic-gate 			}
18597c478bd9Sstevel@tonic-gate 			ptr += RNDUP(ol) / BYTES_PER_XDR_UNIT;
18607c478bd9Sstevel@tonic-gate 		}
18617c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
18627c478bd9Sstevel@tonic-gate 			uint_t *group_length, gl;
18637c478bd9Sstevel@tonic-gate 			char *group_val = NULL;
18647c478bd9Sstevel@tonic-gate 			utf8string gv;
18657c478bd9Sstevel@tonic-gate 			int error;
18667c478bd9Sstevel@tonic-gate 
18677c478bd9Sstevel@tonic-gate 			/* get the OWNER_GROUP_LENGTH */
18687c478bd9Sstevel@tonic-gate 			gl = IXDR_GET_U_INT32(ptr);
18697c478bd9Sstevel@tonic-gate 
18707c478bd9Sstevel@tonic-gate 			/* Manage the group length location */
18717c478bd9Sstevel@tonic-gate 			if (pug && gl <= MAX_OG_NAME) {
18727c478bd9Sstevel@tonic-gate 				group_length = &pug->g_curr.utf8string_len;
18737c478bd9Sstevel@tonic-gate 				*group_length = gl;
18747c478bd9Sstevel@tonic-gate 			} else {
18757c478bd9Sstevel@tonic-gate 				group_length = &gl;
18767c478bd9Sstevel@tonic-gate 			}
18777c478bd9Sstevel@tonic-gate 
18787c478bd9Sstevel@tonic-gate 			/* find memory to store the decode */
18797c478bd9Sstevel@tonic-gate 			if (*group_length > MAX_OG_NAME || pug == NULL)
18807c478bd9Sstevel@tonic-gate 				group_val = (char *)ptr;
18817c478bd9Sstevel@tonic-gate 			else
18827c478bd9Sstevel@tonic-gate 				group_val = (char *)ptr;
18837c478bd9Sstevel@tonic-gate 
18847c478bd9Sstevel@tonic-gate 			/* Optimize for matching if called for */
18857c478bd9Sstevel@tonic-gate 			if (pug &&
18867c478bd9Sstevel@tonic-gate 			    *group_length == pug->g_last.utf8string_len &&
18877c478bd9Sstevel@tonic-gate 			    bcmp(group_val, pug->g_last.utf8string_val,
18887c478bd9Sstevel@tonic-gate 			    *group_length) == 0) {
18897c478bd9Sstevel@tonic-gate 				vap->va_gid = pug->gid;
18907c478bd9Sstevel@tonic-gate 				vap->va_mask |= AT_GID;
18917c478bd9Sstevel@tonic-gate 			} else {
18927c478bd9Sstevel@tonic-gate 				uid_t gid;
18937c478bd9Sstevel@tonic-gate 
18947c478bd9Sstevel@tonic-gate 				gv.utf8string_len = *group_length;
18957c478bd9Sstevel@tonic-gate 				gv.utf8string_val = group_val;
18967c478bd9Sstevel@tonic-gate 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
18977c478bd9Sstevel@tonic-gate 				/*
18987c478bd9Sstevel@tonic-gate 				 * String was mapped, but to nobody because
18997c478bd9Sstevel@tonic-gate 				 * we are nfsmapid, indicate it should not
19007c478bd9Sstevel@tonic-gate 				 * be cached.
19017c478bd9Sstevel@tonic-gate 				 */
19027c478bd9Sstevel@tonic-gate 				if (error == ENOTSUP) {
19037c478bd9Sstevel@tonic-gate 					error = 0;
19047c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
19057c478bd9Sstevel@tonic-gate 					    NFS4_GETATTR_NOCACHE_OK;
19067c478bd9Sstevel@tonic-gate 				}
19077c478bd9Sstevel@tonic-gate 
19087c478bd9Sstevel@tonic-gate 				if (error) {
19097c478bd9Sstevel@tonic-gate 					garp->n4g_attrerr = error;
19107c478bd9Sstevel@tonic-gate 					garp->n4g_attrwhy =
19117c478bd9Sstevel@tonic-gate 					    NFS4_GETATTR_ATGID_ERR;
19127c478bd9Sstevel@tonic-gate 				} else {
19137c478bd9Sstevel@tonic-gate 					vap->va_gid = gid;
19147c478bd9Sstevel@tonic-gate 					vap->va_mask |= AT_GID;
19157c478bd9Sstevel@tonic-gate 					if (pug && gl <= MAX_OG_NAME) {
19167c478bd9Sstevel@tonic-gate 						pug->gid = gid;
19177c478bd9Sstevel@tonic-gate 						pug->g_curr.utf8string_len =
19187c478bd9Sstevel@tonic-gate 						    gv.utf8string_len;
19197c478bd9Sstevel@tonic-gate 						bcopy(group_val,
19207c478bd9Sstevel@tonic-gate 						    pug->g_curr.utf8string_val,
19217c478bd9Sstevel@tonic-gate 						    gl);
19227c478bd9Sstevel@tonic-gate 						G_SWAP_CURR_LAST(pug);
19237c478bd9Sstevel@tonic-gate 					}
19247c478bd9Sstevel@tonic-gate 				}
19257c478bd9Sstevel@tonic-gate 			}
19267c478bd9Sstevel@tonic-gate 			ptr += RNDUP(gl) / BYTES_PER_XDR_UNIT;
19277c478bd9Sstevel@tonic-gate 		}
19287c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
19297c478bd9Sstevel@tonic-gate 			ASSERT(0);
19307c478bd9Sstevel@tonic-gate 		}
19317c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
19327c478bd9Sstevel@tonic-gate 			ASSERT(0);
19337c478bd9Sstevel@tonic-gate 		}
19347c478bd9Sstevel@tonic-gate 	}
19357c478bd9Sstevel@tonic-gate 	if (resbmap &
19367c478bd9Sstevel@tonic-gate 	    (FATTR4_QUOTA_USED_MASK |
19377c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_AVAIL_MASK |
19387c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_FREE_MASK |
19397c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_TOTAL_MASK |
19407c478bd9Sstevel@tonic-gate 	    FATTR4_SPACE_USED_MASK |
19417c478bd9Sstevel@tonic-gate 	    FATTR4_SYSTEM_MASK)) {
19427c478bd9Sstevel@tonic-gate 
19437c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
19447c478bd9Sstevel@tonic-gate 			ASSERT(0);
19457c478bd9Sstevel@tonic-gate 		}
19467c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_RAWDEV_MASK) {
19477c478bd9Sstevel@tonic-gate 			fattr4_rawdev rawdev;
19487c478bd9Sstevel@tonic-gate 
19497c478bd9Sstevel@tonic-gate 			rawdev.specdata1 = IXDR_GET_U_INT32(ptr);
19507c478bd9Sstevel@tonic-gate 			rawdev.specdata2 = IXDR_GET_U_INT32(ptr);
19517c478bd9Sstevel@tonic-gate 
19527c478bd9Sstevel@tonic-gate 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
19537c478bd9Sstevel@tonic-gate 				vap->va_rdev = makedevice(rawdev.specdata1,
19547c478bd9Sstevel@tonic-gate 				    rawdev.specdata2);
19557c478bd9Sstevel@tonic-gate 			} else {
19567c478bd9Sstevel@tonic-gate 				vap->va_rdev = 0;
19577c478bd9Sstevel@tonic-gate 			}
19587c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_RDEV;
19597c478bd9Sstevel@tonic-gate 		}
19607c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
19617c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bavail);
19627c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
19637c478bd9Sstevel@tonic-gate 		}
19647c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
19657c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bfree);
19667c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
19677c478bd9Sstevel@tonic-gate 		}
19687c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
19697c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_blocks);
19707c478bd9Sstevel@tonic-gate 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
19717c478bd9Sstevel@tonic-gate 		}
19727c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SPACE_USED_MASK) {
19737c478bd9Sstevel@tonic-gate 			uint64_t space_used;
19747c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, space_used);
19757c478bd9Sstevel@tonic-gate 
19767c478bd9Sstevel@tonic-gate 			/* Compute space depending on device type */
19777c478bd9Sstevel@tonic-gate 			ASSERT((vap->va_mask & AT_TYPE));
19787c478bd9Sstevel@tonic-gate 			if (vap->va_type == VREG || vap->va_type == VDIR ||
19797c478bd9Sstevel@tonic-gate 			    vap->va_type == VLNK) {
19807c478bd9Sstevel@tonic-gate 				vap->va_nblocks = (u_longlong_t)
19817c478bd9Sstevel@tonic-gate 				    ((space_used + (offset4)DEV_BSIZE -
19827c478bd9Sstevel@tonic-gate 				    (offset4)1) / (offset4)DEV_BSIZE);
19837c478bd9Sstevel@tonic-gate 			} else {
19847c478bd9Sstevel@tonic-gate 				vap->va_nblocks = 0;
19857c478bd9Sstevel@tonic-gate 			}
19867c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_NBLOCKS;
19877c478bd9Sstevel@tonic-gate 		}
19887c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_SYSTEM_MASK) {
19897c478bd9Sstevel@tonic-gate 			ASSERT(0);
19907c478bd9Sstevel@tonic-gate 		}
19917c478bd9Sstevel@tonic-gate 	}
19927c478bd9Sstevel@tonic-gate 	if (resbmap &
19937c478bd9Sstevel@tonic-gate 	    (FATTR4_TIME_ACCESS_MASK |
19947c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_ACCESS_SET_MASK |
19957c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_BACKUP_MASK |
19967c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_CREATE_MASK |
19977c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_DELTA_MASK |
19987c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_METADATA_MASK |
19997c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_MASK |
20007c478bd9Sstevel@tonic-gate 	    FATTR4_TIME_MODIFY_SET_MASK |
20017c478bd9Sstevel@tonic-gate 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
20027c478bd9Sstevel@tonic-gate 
20037c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
20047c478bd9Sstevel@tonic-gate 			nfstime4 atime;
20057c478bd9Sstevel@tonic-gate 			int error;
20067c478bd9Sstevel@tonic-gate 
20077c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, atime.seconds);
20087c478bd9Sstevel@tonic-gate 			atime.nseconds = IXDR_GET_U_INT32(ptr);
20097c478bd9Sstevel@tonic-gate 
20107c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&atime, &vap->va_atime);
20117c478bd9Sstevel@tonic-gate 			if (error) {
20127c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
20137c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
20147c478bd9Sstevel@tonic-gate 			}
20157c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_ATIME;
20167c478bd9Sstevel@tonic-gate 		}
20177c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
20187c478bd9Sstevel@tonic-gate 			ASSERT(0);
20197c478bd9Sstevel@tonic-gate 		}
20207c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
20217c478bd9Sstevel@tonic-gate 			ASSERT(0);
20227c478bd9Sstevel@tonic-gate 		}
20237c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
20247c478bd9Sstevel@tonic-gate 			ASSERT(0);
20257c478bd9Sstevel@tonic-gate 		}
20267c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
20277c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, gesp->n4g_delta.seconds);
20287c478bd9Sstevel@tonic-gate 			gesp->n4g_delta.nseconds = IXDR_GET_U_INT32(ptr);
20297c478bd9Sstevel@tonic-gate 		}
20307c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
20317c478bd9Sstevel@tonic-gate 			nfstime4 mdt;
20327c478bd9Sstevel@tonic-gate 			int error;
20337c478bd9Sstevel@tonic-gate 
20347c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, mdt.seconds);
20357c478bd9Sstevel@tonic-gate 			mdt.nseconds = IXDR_GET_U_INT32(ptr);
20367c478bd9Sstevel@tonic-gate 
20377c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
20387c478bd9Sstevel@tonic-gate 			if (error) {
20397c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
20407c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
20417c478bd9Sstevel@tonic-gate 			}
20427c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_CTIME;
20437c478bd9Sstevel@tonic-gate 		}
20447c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
20457c478bd9Sstevel@tonic-gate 			nfstime4 mtime;
20467c478bd9Sstevel@tonic-gate 			int error;
20477c478bd9Sstevel@tonic-gate 
20487c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, mtime.seconds);
20497c478bd9Sstevel@tonic-gate 			mtime.nseconds = IXDR_GET_U_INT32(ptr);
20507c478bd9Sstevel@tonic-gate 
20517c478bd9Sstevel@tonic-gate 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
20527c478bd9Sstevel@tonic-gate 			if (error) {
20537c478bd9Sstevel@tonic-gate 				garp->n4g_attrerr = error;
20547c478bd9Sstevel@tonic-gate 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
20557c478bd9Sstevel@tonic-gate 			}
20567c478bd9Sstevel@tonic-gate 			vap->va_mask |= AT_MTIME;
20577c478bd9Sstevel@tonic-gate 		}
20587c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
20597c478bd9Sstevel@tonic-gate 			ASSERT(0);
20607c478bd9Sstevel@tonic-gate 		}
20617c478bd9Sstevel@tonic-gate 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
20627c478bd9Sstevel@tonic-gate 			IXDR_GET_U_HYPER(ptr, garp->n4g_mon_fid);
20637c478bd9Sstevel@tonic-gate 			garp->n4g_mon_fid_valid = 1;
20647c478bd9Sstevel@tonic-gate 		}
20657c478bd9Sstevel@tonic-gate 	}
20667c478bd9Sstevel@tonic-gate 
20677c478bd9Sstevel@tonic-gate 	/*
20687c478bd9Sstevel@tonic-gate 	 * FATTR4_ACL_MASK is not yet supported by this function, but
20697c478bd9Sstevel@tonic-gate 	 * we check against it anyway, in case it ever is.
20707c478bd9Sstevel@tonic-gate 	 */
20717c478bd9Sstevel@tonic-gate 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
20727c478bd9Sstevel@tonic-gate 		/* copy only if not provided */
20737c478bd9Sstevel@tonic-gate 		if (garp->n4g_ext_res == NULL) {
20747c478bd9Sstevel@tonic-gate 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
20757c478bd9Sstevel@tonic-gate 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
20767c478bd9Sstevel@tonic-gate 		}
20777c478bd9Sstevel@tonic-gate 	}
20787c478bd9Sstevel@tonic-gate 
20797c478bd9Sstevel@tonic-gate 	return (TRUE);
20807c478bd9Sstevel@tonic-gate }
20817c478bd9Sstevel@tonic-gate 
20827c478bd9Sstevel@tonic-gate 
20837c478bd9Sstevel@tonic-gate /*
20847c478bd9Sstevel@tonic-gate  * "." and ".." buffers for filling in on read and readdir
20857c478bd9Sstevel@tonic-gate  * calls. Intialize the first time and fill in on every
20867c478bd9Sstevel@tonic-gate  * call to to readdir.
20877c478bd9Sstevel@tonic-gate  */
20887c478bd9Sstevel@tonic-gate char	*nfs4_dot_entries;
20897c478bd9Sstevel@tonic-gate char	*nfs4_dot_dot_entry;
20907c478bd9Sstevel@tonic-gate 
20917c478bd9Sstevel@tonic-gate /*
20927c478bd9Sstevel@tonic-gate  * Create the "." or ".." and pad the buffer once so they are
20937c478bd9Sstevel@tonic-gate  * copied out as required into the user supplied buffer everytime.
20947c478bd9Sstevel@tonic-gate  * DIRENT64_RECLEN(sizeof (".") - 1) = DIRENT64_RECLEN(1)
20957c478bd9Sstevel@tonic-gate  * DIRENT64_RECLEN(sizeof ("..") - 1) = DIRENT64_RECLEN(2)
20967c478bd9Sstevel@tonic-gate  */
20977c478bd9Sstevel@tonic-gate void
20987c478bd9Sstevel@tonic-gate nfs4_init_dot_entries()
20997c478bd9Sstevel@tonic-gate {
21007c478bd9Sstevel@tonic-gate 	struct dirent64 *odp;
21017c478bd9Sstevel@tonic-gate 
21027c478bd9Sstevel@tonic-gate 	/*
21037c478bd9Sstevel@tonic-gate 	 * zalloc it so it zeros the buffer out. Need
21047c478bd9Sstevel@tonic-gate 	 * to just do it once.
21057c478bd9Sstevel@tonic-gate 	 */
21067c478bd9Sstevel@tonic-gate 	nfs4_dot_entries = kmem_zalloc(DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2),
21077c478bd9Sstevel@tonic-gate 	    KM_SLEEP);
21087c478bd9Sstevel@tonic-gate 
21097c478bd9Sstevel@tonic-gate 	odp = (struct dirent64 *)nfs4_dot_entries;
21107c478bd9Sstevel@tonic-gate 	odp->d_off = 1; /* magic cookie for "." entry */
21117c478bd9Sstevel@tonic-gate 	odp->d_reclen = DIRENT64_RECLEN(1);
21127c478bd9Sstevel@tonic-gate 	odp->d_name[0] = '.';
21137c478bd9Sstevel@tonic-gate 	odp->d_name[1] = '\0';
21147c478bd9Sstevel@tonic-gate 
21157c478bd9Sstevel@tonic-gate 	nfs4_dot_dot_entry = nfs4_dot_entries + DIRENT64_RECLEN(1);
21167c478bd9Sstevel@tonic-gate 	odp = (struct dirent64 *)nfs4_dot_dot_entry;
21177c478bd9Sstevel@tonic-gate 
21187c478bd9Sstevel@tonic-gate 	odp->d_off = 2;
21197c478bd9Sstevel@tonic-gate 	odp->d_reclen = DIRENT64_RECLEN(2);
21207c478bd9Sstevel@tonic-gate 	odp->d_name[0] = '.';
21217c478bd9Sstevel@tonic-gate 	odp->d_name[1] = '.';
21227c478bd9Sstevel@tonic-gate 	odp->d_name[2] = '\0';
21237c478bd9Sstevel@tonic-gate }
21247c478bd9Sstevel@tonic-gate 
21257c478bd9Sstevel@tonic-gate void
21267c478bd9Sstevel@tonic-gate nfs4_destroy_dot_entries()
21277c478bd9Sstevel@tonic-gate {
21287c478bd9Sstevel@tonic-gate 	if (nfs4_dot_entries)
21297c478bd9Sstevel@tonic-gate 		kmem_free(nfs4_dot_entries, DIRENT64_RECLEN(1) +
21307c478bd9Sstevel@tonic-gate 		    DIRENT64_RECLEN(2));
21317c478bd9Sstevel@tonic-gate 
21327c478bd9Sstevel@tonic-gate 	nfs4_dot_entries = nfs4_dot_dot_entry = NULL;
21337c478bd9Sstevel@tonic-gate }
21347c478bd9Sstevel@tonic-gate 
21357c478bd9Sstevel@tonic-gate bool_t
21367c478bd9Sstevel@tonic-gate xdr_READDIR4res_clnt(XDR *xdrs, READDIR4res_clnt *objp, READDIR4args *aobjp)
21377c478bd9Sstevel@tonic-gate {
21387c478bd9Sstevel@tonic-gate 	bool_t more_data;
21397c478bd9Sstevel@tonic-gate 	rddir4_cache *rdc = aobjp->rdc;
21407c478bd9Sstevel@tonic-gate 	dirent64_t *dp = NULL;
21417c478bd9Sstevel@tonic-gate 	int entry_length = 0;
21427c478bd9Sstevel@tonic-gate 	int space_left = 0;
21437c478bd9Sstevel@tonic-gate 	bitmap4 resbmap;
21447c478bd9Sstevel@tonic-gate 	uint32_t attrlen;
21457c478bd9Sstevel@tonic-gate 	nfs4_ga_res_t gar;
21467c478bd9Sstevel@tonic-gate 	struct nfs4_ga_ext_res ges;
21477c478bd9Sstevel@tonic-gate 	uint64_t last_cookie = 0;
21487c478bd9Sstevel@tonic-gate 	int skip_to_end;
21497c478bd9Sstevel@tonic-gate 	ug_cache_t *pug = NULL;
21507c478bd9Sstevel@tonic-gate 
21517c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
21527c478bd9Sstevel@tonic-gate 	ASSERT(rdc->entries == NULL);
21537c478bd9Sstevel@tonic-gate 	ASSERT(aobjp->dircount > 0);
21547c478bd9Sstevel@tonic-gate 
21557c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
21567c478bd9Sstevel@tonic-gate 		return (FALSE);
21577c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
21587c478bd9Sstevel@tonic-gate 		return (TRUE);
21597c478bd9Sstevel@tonic-gate 
21607c478bd9Sstevel@tonic-gate 	gar.n4g_va.va_mask = 0;
21617c478bd9Sstevel@tonic-gate 	gar.n4g_change_valid = 0;
21627c478bd9Sstevel@tonic-gate 	gar.n4g_mon_fid_valid = 0;
21637c478bd9Sstevel@tonic-gate 	gar.n4g_fsid_valid = 0;
21647c478bd9Sstevel@tonic-gate 	gar.n4g_vsa.vsa_mask = 0;
21657c478bd9Sstevel@tonic-gate 	gar.n4g_attrwhy = NFS4_GETATTR_OP_OK;
21667c478bd9Sstevel@tonic-gate 	ges.n4g_pc4.pc4_cache_valid = 0;
21677c478bd9Sstevel@tonic-gate 	ges.n4g_pc4.pc4_xattr_valid = 0;
21687c478bd9Sstevel@tonic-gate 	gar.n4g_ext_res = &ges;
21697c478bd9Sstevel@tonic-gate 
21707c478bd9Sstevel@tonic-gate 	/* READDIR4res_clnt_free needs to kmem_free this buffer */
21717c478bd9Sstevel@tonic-gate 	rdc->entries = kmem_alloc(aobjp->dircount, KM_SLEEP);
21727c478bd9Sstevel@tonic-gate 
21737c478bd9Sstevel@tonic-gate 	dp = (dirent64_t *)rdc->entries;
21747c478bd9Sstevel@tonic-gate 	rdc->entlen = rdc->buflen = space_left = aobjp->dircount;
21757c478bd9Sstevel@tonic-gate 
21767c478bd9Sstevel@tonic-gate 	/* Fill in dot and dot-dot if needed */
21777c478bd9Sstevel@tonic-gate 	if (rdc->nfs4_cookie == (nfs_cookie4) 0 ||
21787c478bd9Sstevel@tonic-gate 	    rdc->nfs4_cookie == (nfs_cookie4) 1) {
21797c478bd9Sstevel@tonic-gate 
21807c478bd9Sstevel@tonic-gate 		if (rdc->nfs4_cookie == (nfs_cookie4)0) {
21817c478bd9Sstevel@tonic-gate 			bcopy(nfs4_dot_entries, rdc->entries,
21827c478bd9Sstevel@tonic-gate 			    DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2));
21837c478bd9Sstevel@tonic-gate 			objp->dotp = dp;
21847c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((char *)dp) +
21857c478bd9Sstevel@tonic-gate 			    DIRENT64_RECLEN(1));
21867c478bd9Sstevel@tonic-gate 			objp->dotdotp = dp;
21877c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((char *)dp) +
21887c478bd9Sstevel@tonic-gate 			    DIRENT64_RECLEN(2));
21897c478bd9Sstevel@tonic-gate 			space_left -= DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2);
21907c478bd9Sstevel@tonic-gate 
21917c478bd9Sstevel@tonic-gate 		} else	{	/* for ".." entry */
21927c478bd9Sstevel@tonic-gate 			bcopy(nfs4_dot_dot_entry, rdc->entries,
21937c478bd9Sstevel@tonic-gate 			    DIRENT64_RECLEN(2));
21947c478bd9Sstevel@tonic-gate 			objp->dotp = NULL;
21957c478bd9Sstevel@tonic-gate 			objp->dotdotp = dp;
21967c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((char *)dp) +
21977c478bd9Sstevel@tonic-gate 			    DIRENT64_RECLEN(2));
21987c478bd9Sstevel@tonic-gate 			space_left -= DIRENT64_RECLEN(2);
21997c478bd9Sstevel@tonic-gate 		}
22007c478bd9Sstevel@tonic-gate 		/* Magic NFSv4 number for entry after start */
22017c478bd9Sstevel@tonic-gate 		last_cookie = 2;
22027c478bd9Sstevel@tonic-gate 	}
22037c478bd9Sstevel@tonic-gate 
22047c478bd9Sstevel@tonic-gate 	/* Get the cookie VERIFIER */
22057c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
22067c478bd9Sstevel@tonic-gate 		goto noentries;
22077c478bd9Sstevel@tonic-gate 
22087c478bd9Sstevel@tonic-gate 	/* Get the do-we-have-a-next-entry BOOL */
22097c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &more_data))
22107c478bd9Sstevel@tonic-gate 		goto noentries;
22117c478bd9Sstevel@tonic-gate 
22127c478bd9Sstevel@tonic-gate 	if (aobjp->attr_request & (FATTR4_OWNER_MASK | FATTR4_OWNER_GROUP_MASK))
22137c478bd9Sstevel@tonic-gate 		pug = alloc_ugcache();
22147c478bd9Sstevel@tonic-gate 
22157c478bd9Sstevel@tonic-gate 	skip_to_end = 0;
22167c478bd9Sstevel@tonic-gate 	while (more_data) {
22177c478bd9Sstevel@tonic-gate 		uint_t namelen;
22187c478bd9Sstevel@tonic-gate 		uint64_t cookie;
22197c478bd9Sstevel@tonic-gate 
22207c478bd9Sstevel@tonic-gate 		/* Get the COOKIE */
22217c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&cookie))
22227c478bd9Sstevel@tonic-gate 			goto noentries;
22237c478bd9Sstevel@tonic-gate 
22247c478bd9Sstevel@tonic-gate 		/* Get the LENGTH of the entry name */
22257c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &namelen))
22267c478bd9Sstevel@tonic-gate 			goto noentries;
22277c478bd9Sstevel@tonic-gate 
22287c478bd9Sstevel@tonic-gate 		if (!skip_to_end) {
22297c478bd9Sstevel@tonic-gate 			/*
22307c478bd9Sstevel@tonic-gate 			 * With the length of the directory entry name
22317c478bd9Sstevel@tonic-gate 			 * in hand, figure out if there is room left
22327c478bd9Sstevel@tonic-gate 			 * to encode it for the requestor.  If not,
22337c478bd9Sstevel@tonic-gate 			 * that is okay, but the rest of the readdir
22347c478bd9Sstevel@tonic-gate 			 * operation result must be decoded in the
22357c478bd9Sstevel@tonic-gate 			 * case there are following operations
22367c478bd9Sstevel@tonic-gate 			 * in the compound request.  Therefore, mark
22377c478bd9Sstevel@tonic-gate 			 * the rest of the response as "skip" and
22387c478bd9Sstevel@tonic-gate 			 * decode or skip the remaining data
22397c478bd9Sstevel@tonic-gate 			 */
22407c478bd9Sstevel@tonic-gate 			entry_length = DIRENT64_RECLEN(namelen);
22417c478bd9Sstevel@tonic-gate 			if (space_left < entry_length)
22427c478bd9Sstevel@tonic-gate 				skip_to_end = 1;
22437c478bd9Sstevel@tonic-gate 		}
22447c478bd9Sstevel@tonic-gate 
22457c478bd9Sstevel@tonic-gate 		/* Get the NAME of the entry */
22467c478bd9Sstevel@tonic-gate 		if (!skip_to_end) {
22477c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, dp->d_name, namelen))
22487c478bd9Sstevel@tonic-gate 				goto noentries;
22497c478bd9Sstevel@tonic-gate 			bzero(&dp->d_name[namelen],
22507c478bd9Sstevel@tonic-gate 			    DIRENT64_NAMELEN(entry_length) - namelen);
22517c478bd9Sstevel@tonic-gate 			dp->d_off = last_cookie = cookie;
22527c478bd9Sstevel@tonic-gate 			dp->d_reclen = entry_length;
22537c478bd9Sstevel@tonic-gate 		} else {
22547c478bd9Sstevel@tonic-gate 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &namelen))
22557c478bd9Sstevel@tonic-gate 				goto noentries;
22567c478bd9Sstevel@tonic-gate 		}
22577c478bd9Sstevel@tonic-gate 
22587c478bd9Sstevel@tonic-gate 		/* Get the attribute BITMAP */
22597c478bd9Sstevel@tonic-gate 		if (!xdr_bitmap4(xdrs, &resbmap))
22607c478bd9Sstevel@tonic-gate 			goto noentries;
22617c478bd9Sstevel@tonic-gate 		/* Get the LENGTH of the attributes */
22627c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, (uint_t *)&attrlen))
22637c478bd9Sstevel@tonic-gate 			goto noentries;
22647c478bd9Sstevel@tonic-gate 
22657c478bd9Sstevel@tonic-gate 		/* Get the ATTRIBUTES */
22667c478bd9Sstevel@tonic-gate 		if (!skip_to_end) {
22677c478bd9Sstevel@tonic-gate 			uint32_t *ptr;
22687c478bd9Sstevel@tonic-gate 
22697c478bd9Sstevel@tonic-gate 			if (!(resbmap & FATTR4_ACL_MASK) &&
22707c478bd9Sstevel@tonic-gate 			    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen))
22717c478bd9Sstevel@tonic-gate 			    != NULL) {
22727c478bd9Sstevel@tonic-gate 				if (!xdr_ga_fattr_res_inline(ptr, &gar, resbmap,
22730a701b1eSRobert Gordon 				    aobjp->attr_request, aobjp->mi, pug))
22747c478bd9Sstevel@tonic-gate 					goto noentries;
22757c478bd9Sstevel@tonic-gate 			} else {
22767c478bd9Sstevel@tonic-gate 				if (!xdr_ga_fattr_res(xdrs, &gar, resbmap,
22770a701b1eSRobert Gordon 				    aobjp->attr_request, aobjp->mi, pug))
22787c478bd9Sstevel@tonic-gate 					goto noentries;
22797c478bd9Sstevel@tonic-gate 			}
22807c478bd9Sstevel@tonic-gate 
22817c478bd9Sstevel@tonic-gate 			/* Fill in the d_ino per the server's fid values */
22827c478bd9Sstevel@tonic-gate 			/*
22837c478bd9Sstevel@tonic-gate 			 * Important to note that the mounted on fileid
22847c478bd9Sstevel@tonic-gate 			 * is returned in d_ino if supported.  This is
22857c478bd9Sstevel@tonic-gate 			 * expected, readdir returns the mounted on fileid
22867c478bd9Sstevel@tonic-gate 			 * while stat() returns the fileid of the object
22877c478bd9Sstevel@tonic-gate 			 * on "top" of the mount.
22887c478bd9Sstevel@tonic-gate 			 */
22897c478bd9Sstevel@tonic-gate 			if (gar.n4g_mon_fid_valid)
22907c478bd9Sstevel@tonic-gate 				dp->d_ino = gar.n4g_mon_fid;
22917c478bd9Sstevel@tonic-gate 			else if (gar.n4g_va.va_mask & AT_NODEID)
22927c478bd9Sstevel@tonic-gate 				dp->d_ino = gar.n4g_va.va_nodeid;
22937c478bd9Sstevel@tonic-gate 			else
22947c478bd9Sstevel@tonic-gate 				dp->d_ino = 0;
22957c478bd9Sstevel@tonic-gate 
22967c478bd9Sstevel@tonic-gate 			/* See about creating an rnode for this entry */
22977c478bd9Sstevel@tonic-gate 			if ((resbmap &
22987c478bd9Sstevel@tonic-gate 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) ==
22997c478bd9Sstevel@tonic-gate 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) {
23007c478bd9Sstevel@tonic-gate 				nfs4_sharedfh_t *sfhp;
23017c478bd9Sstevel@tonic-gate 				vnode_t *vp;
23027c478bd9Sstevel@tonic-gate 
23037c478bd9Sstevel@tonic-gate 				sfhp = sfh4_put(&ges.n4g_fh_u.n4g_fh,
23047c478bd9Sstevel@tonic-gate 				    aobjp->mi, NULL);
23057c478bd9Sstevel@tonic-gate 				vp = makenfs4node(sfhp, &gar,
23067c478bd9Sstevel@tonic-gate 				    aobjp->dvp->v_vfsp,
23077c478bd9Sstevel@tonic-gate 				    aobjp->t,
23087c478bd9Sstevel@tonic-gate 				    aobjp->cr,
23097c478bd9Sstevel@tonic-gate 				    aobjp->dvp,
23107c478bd9Sstevel@tonic-gate 				    fn_get(VTOSV(aobjp->dvp)->sv_name,
2311bbf2a467SNagakiran Rajashekar 				    dp->d_name, sfhp));
23127c478bd9Sstevel@tonic-gate 				sfh4_rele(&sfhp);
23137c478bd9Sstevel@tonic-gate 				dnlc_update(aobjp->dvp, dp->d_name, vp);
23147c478bd9Sstevel@tonic-gate 				VN_RELE(vp);
23157c478bd9Sstevel@tonic-gate 			}
23167c478bd9Sstevel@tonic-gate 
23177c478bd9Sstevel@tonic-gate 			dp = (struct dirent64 *)(((caddr_t)dp) + dp->d_reclen);
23187c478bd9Sstevel@tonic-gate 
23197c478bd9Sstevel@tonic-gate 			space_left -= entry_length;
23207c478bd9Sstevel@tonic-gate 
23217c478bd9Sstevel@tonic-gate 		} else {
23227c478bd9Sstevel@tonic-gate 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &attrlen))
23237c478bd9Sstevel@tonic-gate 				goto noentries;
23247c478bd9Sstevel@tonic-gate 		}
23257c478bd9Sstevel@tonic-gate 
23267c478bd9Sstevel@tonic-gate 		/* Get the do-we-have-a-next-entry BOOL */
23277c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &more_data))
23287c478bd9Sstevel@tonic-gate 			goto noentries;
23297c478bd9Sstevel@tonic-gate 	}
23307c478bd9Sstevel@tonic-gate 
23317c478bd9Sstevel@tonic-gate 	if (pug) {
23327c478bd9Sstevel@tonic-gate 		kmem_free(pug, sizeof (ug_cache_t));
23337c478bd9Sstevel@tonic-gate 		pug = NULL;
23347c478bd9Sstevel@tonic-gate 	}
23357c478bd9Sstevel@tonic-gate 
23367c478bd9Sstevel@tonic-gate 	/*
23377c478bd9Sstevel@tonic-gate 	 * Finish up the rddir cache
23387c478bd9Sstevel@tonic-gate 	 * If no entries were returned, free up buffer &
23397c478bd9Sstevel@tonic-gate 	 * set ncookie to the starting cookie for this
23407c478bd9Sstevel@tonic-gate 	 * readdir request so that the direof caching
23417c478bd9Sstevel@tonic-gate 	 * will work properly.
23427c478bd9Sstevel@tonic-gate 	 */
23437c478bd9Sstevel@tonic-gate 	ASSERT(rdc->entries);
23447c478bd9Sstevel@tonic-gate 	if (last_cookie == 0) {
23457c478bd9Sstevel@tonic-gate 		kmem_free(rdc->entries, rdc->entlen);
23467c478bd9Sstevel@tonic-gate 		rdc->entries = NULL;
23477c478bd9Sstevel@tonic-gate 		last_cookie = rdc->nfs4_cookie;
23487c478bd9Sstevel@tonic-gate 	}
23497c478bd9Sstevel@tonic-gate 
23507c478bd9Sstevel@tonic-gate 	rdc->actlen = rdc->entlen - space_left;
23517c478bd9Sstevel@tonic-gate 	rdc->nfs4_ncookie = last_cookie;
23527c478bd9Sstevel@tonic-gate 
23537c478bd9Sstevel@tonic-gate 	/* Get the EOF marker */
23547c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->eof))
23557c478bd9Sstevel@tonic-gate 		goto noentries;
23567c478bd9Sstevel@tonic-gate 
23577c478bd9Sstevel@tonic-gate 	/*
23587c478bd9Sstevel@tonic-gate 	 * If the server returns eof and there were no
23597c478bd9Sstevel@tonic-gate 	 * skipped entries, set eof
23607c478bd9Sstevel@tonic-gate 	 */
23617c478bd9Sstevel@tonic-gate 	rdc->eof = (objp->eof && !skip_to_end) ? TRUE : FALSE;
23627c478bd9Sstevel@tonic-gate 
23637c478bd9Sstevel@tonic-gate 	/*
23647c478bd9Sstevel@tonic-gate 	 * If we encoded entries we are done
23657c478bd9Sstevel@tonic-gate 	 */
23667c478bd9Sstevel@tonic-gate 	if (rdc->entries) {
23677c478bd9Sstevel@tonic-gate 		rdc->error = 0;
23687c478bd9Sstevel@tonic-gate 		return (TRUE);
23697c478bd9Sstevel@tonic-gate 	}
23707c478bd9Sstevel@tonic-gate 
23717c478bd9Sstevel@tonic-gate 	/*
23727c478bd9Sstevel@tonic-gate 	 * If there were no entries and we skipped because
23737c478bd9Sstevel@tonic-gate 	 * there was not enough space, return EINVAL
23747c478bd9Sstevel@tonic-gate 	 */
23757c478bd9Sstevel@tonic-gate 	if (skip_to_end) {
23767c478bd9Sstevel@tonic-gate 		rdc->error = EINVAL;
23777c478bd9Sstevel@tonic-gate 		return (TRUE);
23787c478bd9Sstevel@tonic-gate 	}
23797c478bd9Sstevel@tonic-gate 
23807c478bd9Sstevel@tonic-gate 	/*
23817c478bd9Sstevel@tonic-gate 	 * No entries, nothing skipped, and EOF, return OK.
23827c478bd9Sstevel@tonic-gate 	 */
23837c478bd9Sstevel@tonic-gate 	if (objp->eof == TRUE) {
23847c478bd9Sstevel@tonic-gate 		rdc->error = 0;
23857c478bd9Sstevel@tonic-gate 		return (TRUE);
23867c478bd9Sstevel@tonic-gate 	}
23877c478bd9Sstevel@tonic-gate 
23887c478bd9Sstevel@tonic-gate 	/*
23897c478bd9Sstevel@tonic-gate 	 * No entries, nothing skipped, and not EOF
23907c478bd9Sstevel@tonic-gate 	 * probably a bad cookie, return ENOENT.
23917c478bd9Sstevel@tonic-gate 	 */
23927c478bd9Sstevel@tonic-gate 	rdc->error = ENOENT;
23937c478bd9Sstevel@tonic-gate 	return (TRUE);
23947c478bd9Sstevel@tonic-gate 
23957c478bd9Sstevel@tonic-gate noentries:
23967c478bd9Sstevel@tonic-gate 	if (rdc->entries) {
23977c478bd9Sstevel@tonic-gate 		kmem_free(rdc->entries, rdc->entlen);
23987c478bd9Sstevel@tonic-gate 		rdc->entries = NULL;
23997c478bd9Sstevel@tonic-gate 	}
24007c478bd9Sstevel@tonic-gate 	if (pug)
24017c478bd9Sstevel@tonic-gate 		kmem_free(pug, sizeof (ug_cache_t));
24027c478bd9Sstevel@tonic-gate 	rdc->error = EIO;
24037c478bd9Sstevel@tonic-gate 	return (FALSE);
24047c478bd9Sstevel@tonic-gate }
24057c478bd9Sstevel@tonic-gate 
24067c478bd9Sstevel@tonic-gate /*
24077c478bd9Sstevel@tonic-gate  * xdr_ga_res
24087c478bd9Sstevel@tonic-gate  *
24097c478bd9Sstevel@tonic-gate  * Returns: FALSE on raw data processing errors, TRUE otherwise.
24107c478bd9Sstevel@tonic-gate  *
24117c478bd9Sstevel@tonic-gate  * This function pre-processes the OP_GETATTR response, and then
24127c478bd9Sstevel@tonic-gate  * calls common routines to process the GETATTR fattr4 results into
24137c478bd9Sstevel@tonic-gate  * vnode attributes and other components that the client is interested
24147c478bd9Sstevel@tonic-gate  * in. If an error other than an RPC error is encountered, the details
24157c478bd9Sstevel@tonic-gate  * of the error are filled into objp, although the result of the
24167c478bd9Sstevel@tonic-gate  * processing is set to TRUE.
24177c478bd9Sstevel@tonic-gate  */
24187c478bd9Sstevel@tonic-gate static bool_t
24197c478bd9Sstevel@tonic-gate xdr_ga_res(XDR *xdrs, GETATTR4res *objp, GETATTR4args *aobjp)
24207c478bd9Sstevel@tonic-gate {
24212f172c55SRobert Thurlow #ifdef INLINE
24227c478bd9Sstevel@tonic-gate 	uint32_t *ptr;
24232f172c55SRobert Thurlow #endif
24247c478bd9Sstevel@tonic-gate 	bitmap4 resbmap;
24257c478bd9Sstevel@tonic-gate 	uint32_t attrlen;
24267c478bd9Sstevel@tonic-gate 
24277c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_DECODE);
24287c478bd9Sstevel@tonic-gate 
24297c478bd9Sstevel@tonic-gate 	/* Initialize objp attribute error values */
24307c478bd9Sstevel@tonic-gate 	objp->ga_res.n4g_attrerr =
24317c478bd9Sstevel@tonic-gate 	    objp->ga_res.n4g_attrwhy = NFS4_GETATTR_OP_OK;
24327c478bd9Sstevel@tonic-gate 
24337c478bd9Sstevel@tonic-gate 	if (!xdr_bitmap4(xdrs, &resbmap))
24347c478bd9Sstevel@tonic-gate 		return (FALSE);
24357c478bd9Sstevel@tonic-gate 
24367c478bd9Sstevel@tonic-gate 	/* save the response bitmap for the caller */
24377c478bd9Sstevel@tonic-gate 	objp->ga_res.n4g_resbmap = resbmap;
24387c478bd9Sstevel@tonic-gate 
24397c478bd9Sstevel@tonic-gate 	/* attrlen */
24407c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&attrlen))
24417c478bd9Sstevel@tonic-gate 		return (FALSE);
24427c478bd9Sstevel@tonic-gate 
24437c478bd9Sstevel@tonic-gate 	/*
24447c478bd9Sstevel@tonic-gate 	 * Handle case where request and response bitmaps don't match.
24457c478bd9Sstevel@tonic-gate 	 */
24467c478bd9Sstevel@tonic-gate 	if (aobjp->attr_request && aobjp->attr_request != resbmap) {
24477c478bd9Sstevel@tonic-gate 		bitmap4 deltabmap;
24487c478bd9Sstevel@tonic-gate 
24497c478bd9Sstevel@tonic-gate 		/*
24507c478bd9Sstevel@tonic-gate 		 * Return error for case where server sent extra attributes
24517c478bd9Sstevel@tonic-gate 		 * because the "unknown" attributes may be anywhere in the
24527c478bd9Sstevel@tonic-gate 		 * xdr stream and can't be properly processed.
24537c478bd9Sstevel@tonic-gate 		 */
24547c478bd9Sstevel@tonic-gate 		deltabmap = ((aobjp->attr_request ^ resbmap) & resbmap);
24557c478bd9Sstevel@tonic-gate 		if (deltabmap) {
24567c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrerr = EINVAL;
24577c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_BITMAP_ERR;
24587c478bd9Sstevel@tonic-gate 			return (TRUE);
24597c478bd9Sstevel@tonic-gate 		}
24607c478bd9Sstevel@tonic-gate 
24617c478bd9Sstevel@tonic-gate 		/*
24627c478bd9Sstevel@tonic-gate 		 * Return error for case where there is a mandatory
24637c478bd9Sstevel@tonic-gate 		 * attribute missing in the server response. Note that
24647c478bd9Sstevel@tonic-gate 		 * missing recommended attributes are evaluated in the
24657c478bd9Sstevel@tonic-gate 		 * specific routines that decode the server response.
24667c478bd9Sstevel@tonic-gate 		 */
24677c478bd9Sstevel@tonic-gate 		deltabmap = ((aobjp->attr_request ^ resbmap)
24687c478bd9Sstevel@tonic-gate 		    & aobjp->attr_request);
24697c478bd9Sstevel@tonic-gate 		if ((deltabmap & FATTR4_MANDATTR_MASK)) {
24707c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrerr = EINVAL;
24717c478bd9Sstevel@tonic-gate 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_MANDATTR_ERR;
24727c478bd9Sstevel@tonic-gate 			return (TRUE);
24737c478bd9Sstevel@tonic-gate 		}
24747c478bd9Sstevel@tonic-gate 	}
24757c478bd9Sstevel@tonic-gate 
24767c478bd9Sstevel@tonic-gate 	/* Check to see if the attrs can be inlined and go for it if so */
24772f172c55SRobert Thurlow #ifdef INLINE
24787c478bd9Sstevel@tonic-gate 	if (!(resbmap & FATTR4_ACL_MASK) &&
24797c478bd9Sstevel@tonic-gate 	    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen)) != NULL)
24807c478bd9Sstevel@tonic-gate 		return (xdr_ga_fattr_res_inline(ptr, &objp->ga_res,
24810a701b1eSRobert Gordon 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
24827c478bd9Sstevel@tonic-gate 	else
24832f172c55SRobert Thurlow #endif
24847c478bd9Sstevel@tonic-gate 		return (xdr_ga_fattr_res(xdrs, &objp->ga_res,
24850a701b1eSRobert Gordon 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
24867c478bd9Sstevel@tonic-gate }
24877c478bd9Sstevel@tonic-gate 
24887c478bd9Sstevel@tonic-gate #if defined(DEBUG) && !defined(lint)
24897c478bd9Sstevel@tonic-gate /*
24907c478bd9Sstevel@tonic-gate  * We assume that an enum is a 32-bit value, check it once
24917c478bd9Sstevel@tonic-gate  */
24927c478bd9Sstevel@tonic-gate static enum szchk { SZVAL } szchkvar;
24937c478bd9Sstevel@tonic-gate #endif
24947c478bd9Sstevel@tonic-gate 
24957c478bd9Sstevel@tonic-gate bool_t
24967c478bd9Sstevel@tonic-gate xdr_settime4(XDR *xdrs, settime4 *objp)
24977c478bd9Sstevel@tonic-gate {
24987c478bd9Sstevel@tonic-gate #if defined(DEBUG) && !defined(lint)
24997c478bd9Sstevel@tonic-gate 	ASSERT(sizeof (szchkvar) == sizeof (int32_t));
25007c478bd9Sstevel@tonic-gate #endif
25017c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
25027c478bd9Sstevel@tonic-gate 		return (TRUE);
25037c478bd9Sstevel@tonic-gate 
25047c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->set_it))
25057c478bd9Sstevel@tonic-gate 		return (FALSE);
25067c478bd9Sstevel@tonic-gate 	if (objp->set_it != SET_TO_CLIENT_TIME4)
25077c478bd9Sstevel@tonic-gate 		return (TRUE);
25087c478bd9Sstevel@tonic-gate 	/* xdr_nfstime4 */
25097c478bd9Sstevel@tonic-gate 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->time.seconds))
25107c478bd9Sstevel@tonic-gate 		return (FALSE);
25117c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->time.nseconds));
25127c478bd9Sstevel@tonic-gate }
25137c478bd9Sstevel@tonic-gate 
25147c478bd9Sstevel@tonic-gate static bool_t
25157c478bd9Sstevel@tonic-gate xdr_fattr4(XDR *xdrs, fattr4 *objp)
25167c478bd9Sstevel@tonic-gate {
25177c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
25187c478bd9Sstevel@tonic-gate 		if (!xdr_bitmap4(xdrs, &objp->attrmask))
25197c478bd9Sstevel@tonic-gate 			return (FALSE);
25207c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->attrlist4,
25217c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->attrlist4_len, NFS4_FATTR4_LIMIT));
25227c478bd9Sstevel@tonic-gate 	}
25237c478bd9Sstevel@tonic-gate 
25247c478bd9Sstevel@tonic-gate 	/*
25257c478bd9Sstevel@tonic-gate 	 * Optimized free case
25267c478bd9Sstevel@tonic-gate 	 */
25277c478bd9Sstevel@tonic-gate 	if (objp->attrlist4 != NULL)
25287c478bd9Sstevel@tonic-gate 		kmem_free(objp->attrlist4, objp->attrlist4_len);
25297c478bd9Sstevel@tonic-gate 	return (TRUE);
25307c478bd9Sstevel@tonic-gate }
25317c478bd9Sstevel@tonic-gate 
25327c478bd9Sstevel@tonic-gate static bool_t
25337c478bd9Sstevel@tonic-gate xdr_ACCESS4res(XDR *xdrs, ACCESS4res *objp)
25347c478bd9Sstevel@tonic-gate {
25357c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
25367c478bd9Sstevel@tonic-gate 		return (FALSE);
25377c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
25387c478bd9Sstevel@tonic-gate 		return (TRUE);
25397c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->supported))
25407c478bd9Sstevel@tonic-gate 		return (FALSE);
25417c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->access));
25427c478bd9Sstevel@tonic-gate }
25437c478bd9Sstevel@tonic-gate 
25447c478bd9Sstevel@tonic-gate static bool_t
25457c478bd9Sstevel@tonic-gate xdr_CLOSE4args(XDR *xdrs, CLOSE4args *objp)
25467c478bd9Sstevel@tonic-gate {
25477c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->seqid))
25487c478bd9Sstevel@tonic-gate 		return (FALSE);
25497c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
25507c478bd9Sstevel@tonic-gate 		return (FALSE);
2551bbe876c0SMarcel Telka 	return (xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE));
25527c478bd9Sstevel@tonic-gate }
25537c478bd9Sstevel@tonic-gate 
25547c478bd9Sstevel@tonic-gate static bool_t
25557c478bd9Sstevel@tonic-gate xdr_CLOSE4res(XDR *xdrs, CLOSE4res *objp)
25567c478bd9Sstevel@tonic-gate {
25577c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
25587c478bd9Sstevel@tonic-gate 		return (FALSE);
25597c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
25607c478bd9Sstevel@tonic-gate 		return (TRUE);
25617c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
25627c478bd9Sstevel@tonic-gate 		return (FALSE);
2563bbe876c0SMarcel Telka 	return (xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE));
25647c478bd9Sstevel@tonic-gate }
25657c478bd9Sstevel@tonic-gate 
25667c478bd9Sstevel@tonic-gate static bool_t
25677c478bd9Sstevel@tonic-gate xdr_CREATE4args(XDR *xdrs, CREATE4args *objp)
25687c478bd9Sstevel@tonic-gate {
25697c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
25707c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->type))
25717c478bd9Sstevel@tonic-gate 			return (FALSE);
25727c478bd9Sstevel@tonic-gate 		switch (objp->type) {
25737c478bd9Sstevel@tonic-gate 		case NF4LNK:
25747c478bd9Sstevel@tonic-gate 			if (!xdr_bytes(xdrs,
2575bbe876c0SMarcel Telka 			    (char **)&objp->ftype4_u.linkdata.linktext4_val,
2576bbe876c0SMarcel Telka 			    (uint_t *)&objp->ftype4_u.linkdata.linktext4_len,
25777c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING))
25787c478bd9Sstevel@tonic-gate 				return (FALSE);
25797c478bd9Sstevel@tonic-gate 			break;
25807c478bd9Sstevel@tonic-gate 		case NF4BLK:
25817c478bd9Sstevel@tonic-gate 		case NF4CHR:
25827c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata1))
25837c478bd9Sstevel@tonic-gate 				return (FALSE);
25847c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata2))
25857c478bd9Sstevel@tonic-gate 				return (FALSE);
25867c478bd9Sstevel@tonic-gate 			break;
25877c478bd9Sstevel@tonic-gate 		case NF4SOCK:
25887c478bd9Sstevel@tonic-gate 		case NF4FIFO:
25897c478bd9Sstevel@tonic-gate 		case NF4DIR:
25907c478bd9Sstevel@tonic-gate 		default:
25917c478bd9Sstevel@tonic-gate 			break;	/* server should return NFS4ERR_BADTYPE */
25927c478bd9Sstevel@tonic-gate 		}
25937c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->objname.utf8string_val,
25947c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->objname.utf8string_len,
25957c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING))
25967c478bd9Sstevel@tonic-gate 			return (FALSE);
25977c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs, &objp->createattrs));
25987c478bd9Sstevel@tonic-gate 	}
25997c478bd9Sstevel@tonic-gate 
26007c478bd9Sstevel@tonic-gate 	/*
26017c478bd9Sstevel@tonic-gate 	 * Optimized free case
26027c478bd9Sstevel@tonic-gate 	 */
26037c478bd9Sstevel@tonic-gate 	if (objp->type == NF4LNK) {
2604bbe876c0SMarcel Telka 		if (objp->ftype4_u.linkdata.linktext4_val != NULL)
2605bbe876c0SMarcel Telka 			kmem_free(objp->ftype4_u.linkdata.linktext4_val,
2606bbe876c0SMarcel Telka 			    objp->ftype4_u.linkdata.linktext4_len);
26077c478bd9Sstevel@tonic-gate 	}
26087c478bd9Sstevel@tonic-gate 	if (objp->objname.utf8string_val != NULL)
26097c478bd9Sstevel@tonic-gate 		kmem_free(objp->objname.utf8string_val,
26107c478bd9Sstevel@tonic-gate 		    objp->objname.utf8string_len);
26117c478bd9Sstevel@tonic-gate 	return (xdr_fattr4(xdrs, &objp->createattrs));
26127c478bd9Sstevel@tonic-gate }
26137c478bd9Sstevel@tonic-gate 
26147c478bd9Sstevel@tonic-gate static bool_t
26157c478bd9Sstevel@tonic-gate xdr_CREATE4cargs(XDR *xdrs, CREATE4cargs *objp)
26167c478bd9Sstevel@tonic-gate {
26177c478bd9Sstevel@tonic-gate 	int len;
26187c478bd9Sstevel@tonic-gate 
26197c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
26207c478bd9Sstevel@tonic-gate 
26217c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->type))
26227c478bd9Sstevel@tonic-gate 		return (FALSE);
26237c478bd9Sstevel@tonic-gate 	switch (objp->type) {
26247c478bd9Sstevel@tonic-gate 	case NF4LNK:
26257c478bd9Sstevel@tonic-gate 		len = strlen(objp->ftype4_u.clinkdata);
26267c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
26277c478bd9Sstevel@tonic-gate 			return (FALSE);
26287c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len))
26297c478bd9Sstevel@tonic-gate 			return (FALSE);
26307c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->ftype4_u.clinkdata, len))
26317c478bd9Sstevel@tonic-gate 			return (FALSE);
26327c478bd9Sstevel@tonic-gate 		break;
26337c478bd9Sstevel@tonic-gate 	case NF4BLK:
26347c478bd9Sstevel@tonic-gate 	case NF4CHR:
26357c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs,
26367c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->ftype4_u.devdata.specdata1))
26377c478bd9Sstevel@tonic-gate 			return (FALSE);
26387c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs,
26397c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->ftype4_u.devdata.specdata2))
26407c478bd9Sstevel@tonic-gate 			return (FALSE);
26417c478bd9Sstevel@tonic-gate 		break;
26427c478bd9Sstevel@tonic-gate 	case NF4SOCK:
26437c478bd9Sstevel@tonic-gate 	case NF4FIFO:
26447c478bd9Sstevel@tonic-gate 	case NF4DIR:
26457c478bd9Sstevel@tonic-gate 	default:
26467c478bd9Sstevel@tonic-gate 		break;	/* server should return NFS4ERR_BADTYPE */
26477c478bd9Sstevel@tonic-gate 	}
26487c478bd9Sstevel@tonic-gate 
26497c478bd9Sstevel@tonic-gate 	len = strlen(objp->cname);
26507c478bd9Sstevel@tonic-gate 	if (len > NFS4_MAX_UTF8STRING)
26517c478bd9Sstevel@tonic-gate 		return (FALSE);
26527c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, &len))
26537c478bd9Sstevel@tonic-gate 		return (FALSE);
26547c478bd9Sstevel@tonic-gate 	if (!xdr_opaque(xdrs, objp->cname, len))
26557c478bd9Sstevel@tonic-gate 		return (FALSE);
26567c478bd9Sstevel@tonic-gate 
26577c478bd9Sstevel@tonic-gate 	return (xdr_fattr4(xdrs, &objp->createattrs));
26587c478bd9Sstevel@tonic-gate }
26597c478bd9Sstevel@tonic-gate 
26607c478bd9Sstevel@tonic-gate static bool_t
26617c478bd9Sstevel@tonic-gate xdr_CREATE4res(XDR *xdrs, CREATE4res *objp)
26627c478bd9Sstevel@tonic-gate {
26637c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
26647c478bd9Sstevel@tonic-gate 		return (FALSE);
26657c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
26667c478bd9Sstevel@tonic-gate 		return (TRUE);
26677c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
26687c478bd9Sstevel@tonic-gate 		return (FALSE);
26697c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
26707c478bd9Sstevel@tonic-gate 		return (FALSE);
26717c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
26727c478bd9Sstevel@tonic-gate 		return (FALSE);
26737c478bd9Sstevel@tonic-gate 	return (xdr_bitmap4(xdrs, &objp->attrset));
26747c478bd9Sstevel@tonic-gate }
26757c478bd9Sstevel@tonic-gate 
26767c478bd9Sstevel@tonic-gate static bool_t
26777c478bd9Sstevel@tonic-gate xdr_LINK4res(XDR *xdrs, LINK4res *objp)
26787c478bd9Sstevel@tonic-gate {
26797c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
26807c478bd9Sstevel@tonic-gate 		return (FALSE);
26817c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
26827c478bd9Sstevel@tonic-gate 		return (TRUE);
26837c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
26847c478bd9Sstevel@tonic-gate 		return (FALSE);
26857c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
26867c478bd9Sstevel@tonic-gate 		return (FALSE);
26877c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after));
26887c478bd9Sstevel@tonic-gate }
26897c478bd9Sstevel@tonic-gate 
26907c478bd9Sstevel@tonic-gate static bool_t
26917c478bd9Sstevel@tonic-gate xdr_LOCK4args(XDR *xdrs, LOCK4args *objp)
26927c478bd9Sstevel@tonic-gate {
26937c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
26947c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->locktype))
26957c478bd9Sstevel@tonic-gate 			return (FALSE);
26967c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->reclaim))
26977c478bd9Sstevel@tonic-gate 			return (FALSE);
26987c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
26997c478bd9Sstevel@tonic-gate 			return (FALSE);
27007c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
27017c478bd9Sstevel@tonic-gate 			return (FALSE);
27027c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->locker.new_lock_owner))
27037c478bd9Sstevel@tonic-gate 			return (FALSE);
27047c478bd9Sstevel@tonic-gate 		if (objp->locker.new_lock_owner == TRUE) {
27057c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
27067c478bd9Sstevel@tonic-gate 			    open_seqid))
27077c478bd9Sstevel@tonic-gate 				return (FALSE);
27087c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
27097c478bd9Sstevel@tonic-gate 			    open_stateid.seqid))
27107c478bd9Sstevel@tonic-gate 				return (FALSE);
27117c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->locker.locker4_u.open_owner.
2712bbe876c0SMarcel Telka 			    open_stateid.other, NFS4_OTHER_SIZE))
27137c478bd9Sstevel@tonic-gate 				return (FALSE);
27147c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
27157c478bd9Sstevel@tonic-gate 			    lock_seqid))
27167c478bd9Sstevel@tonic-gate 				return (FALSE);
27177c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
27187c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->locker.locker4_u.
27197c478bd9Sstevel@tonic-gate 			    open_owner.lock_owner.clientid))
27207c478bd9Sstevel@tonic-gate 				return (FALSE);
27217c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs,
27227c478bd9Sstevel@tonic-gate 			    (char **)&objp->locker.locker4_u.open_owner.
27237c478bd9Sstevel@tonic-gate 			    lock_owner.owner_val,
27247c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->locker.locker4_u.open_owner.
27257c478bd9Sstevel@tonic-gate 			    lock_owner.owner_len,
27267c478bd9Sstevel@tonic-gate 			    NFS4_OPAQUE_LIMIT));
27277c478bd9Sstevel@tonic-gate 		}
27287c478bd9Sstevel@tonic-gate 
27297c478bd9Sstevel@tonic-gate 		if (objp->locker.new_lock_owner != FALSE)
27307c478bd9Sstevel@tonic-gate 			return (FALSE);
27317c478bd9Sstevel@tonic-gate 
27327c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
27337c478bd9Sstevel@tonic-gate 		    lock_stateid.seqid))
27347c478bd9Sstevel@tonic-gate 			return (FALSE);
27357c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->locker.locker4_u.lock_owner.
2736bbe876c0SMarcel Telka 		    lock_stateid.other, NFS4_OTHER_SIZE))
27377c478bd9Sstevel@tonic-gate 			return (FALSE);
27387c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
27397c478bd9Sstevel@tonic-gate 		    lock_seqid));
27407c478bd9Sstevel@tonic-gate 	}
27417c478bd9Sstevel@tonic-gate 
27427c478bd9Sstevel@tonic-gate 	/*
27437c478bd9Sstevel@tonic-gate 	 * Optimized free case
27447c478bd9Sstevel@tonic-gate 	 */
27457c478bd9Sstevel@tonic-gate 	if (objp->locker.new_lock_owner == TRUE) {
27467c478bd9Sstevel@tonic-gate 		if (objp->locker.locker4_u.open_owner.lock_owner.owner_val !=
27477c478bd9Sstevel@tonic-gate 		    NULL) {
27487c478bd9Sstevel@tonic-gate 			kmem_free(objp->locker.locker4_u.open_owner.lock_owner.
27497c478bd9Sstevel@tonic-gate 			    owner_val,
27507c478bd9Sstevel@tonic-gate 			    objp->locker.locker4_u.open_owner.lock_owner.
27517c478bd9Sstevel@tonic-gate 			    owner_len);
27527c478bd9Sstevel@tonic-gate 		}
27537c478bd9Sstevel@tonic-gate 	}
27547c478bd9Sstevel@tonic-gate 
27557c478bd9Sstevel@tonic-gate 	return (TRUE);
27567c478bd9Sstevel@tonic-gate }
27577c478bd9Sstevel@tonic-gate 
27587c478bd9Sstevel@tonic-gate static bool_t
27597c478bd9Sstevel@tonic-gate xdr_LOCK4res(XDR *xdrs, LOCK4res *objp)
27607c478bd9Sstevel@tonic-gate {
27617c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
27627c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
27637c478bd9Sstevel@tonic-gate 			return (FALSE);
27647c478bd9Sstevel@tonic-gate 		if (objp->status == NFS4_OK) {
27657c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs,
27667c478bd9Sstevel@tonic-gate 			    &objp->LOCK4res_u.lock_stateid.seqid))
27677c478bd9Sstevel@tonic-gate 				return (FALSE);
27687c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
2769bbe876c0SMarcel Telka 			    objp->LOCK4res_u.lock_stateid.other,
2770bbe876c0SMarcel Telka 			    NFS4_OTHER_SIZE));
27717c478bd9Sstevel@tonic-gate 		}
27727c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4ERR_DENIED)
27737c478bd9Sstevel@tonic-gate 			return (TRUE);
27747c478bd9Sstevel@tonic-gate 
27757c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
27767c478bd9Sstevel@tonic-gate 		    denied.offset))
27777c478bd9Sstevel@tonic-gate 			return (FALSE);
27787c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
27797c478bd9Sstevel@tonic-gate 		    denied.length))
27807c478bd9Sstevel@tonic-gate 			return (FALSE);
27817c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->LOCK4res_u.denied.locktype))
27827c478bd9Sstevel@tonic-gate 			return (FALSE);
27837c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
27847c478bd9Sstevel@tonic-gate 		    denied.owner.clientid))
27857c478bd9Sstevel@tonic-gate 			return (FALSE);
27867c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
27877c478bd9Sstevel@tonic-gate 		    (char **)&objp->LOCK4res_u.denied.owner.owner_val,
27887c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->LOCK4res_u.denied.owner.owner_len,
27897c478bd9Sstevel@tonic-gate 		    NFS4_OPAQUE_LIMIT));
27907c478bd9Sstevel@tonic-gate 	}
27917c478bd9Sstevel@tonic-gate 
27927c478bd9Sstevel@tonic-gate 	/*
27937c478bd9Sstevel@tonic-gate 	 * Optimized free case
27947c478bd9Sstevel@tonic-gate 	 */
27957c478bd9Sstevel@tonic-gate 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
27967c478bd9Sstevel@tonic-gate 		return (TRUE);
27977c478bd9Sstevel@tonic-gate 
27987c478bd9Sstevel@tonic-gate 	if (objp->LOCK4res_u.denied.owner.owner_val != NULL)
27997c478bd9Sstevel@tonic-gate 		kmem_free(objp->LOCK4res_u.denied.owner.owner_val,
28007c478bd9Sstevel@tonic-gate 		    objp->LOCK4res_u.denied.owner.owner_len);
28017c478bd9Sstevel@tonic-gate 	return (TRUE);
28027c478bd9Sstevel@tonic-gate }
28037c478bd9Sstevel@tonic-gate 
28047c478bd9Sstevel@tonic-gate static bool_t
28057c478bd9Sstevel@tonic-gate xdr_LOCKT4args(XDR *xdrs, LOCKT4args *objp)
28067c478bd9Sstevel@tonic-gate {
28077c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
28087c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->locktype))
28097c478bd9Sstevel@tonic-gate 			return (FALSE);
28107c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
28117c478bd9Sstevel@tonic-gate 			return (FALSE);
28127c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
28137c478bd9Sstevel@tonic-gate 			return (FALSE);
28147c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28157c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->owner.clientid))
28167c478bd9Sstevel@tonic-gate 			return (FALSE);
28177c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
28187c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->owner.owner_len,
28197c478bd9Sstevel@tonic-gate 		    NFS4_OPAQUE_LIMIT));
28207c478bd9Sstevel@tonic-gate 	}
28217c478bd9Sstevel@tonic-gate 
28227c478bd9Sstevel@tonic-gate 	/*
28237c478bd9Sstevel@tonic-gate 	 * Optimized free case
28247c478bd9Sstevel@tonic-gate 	 */
28257c478bd9Sstevel@tonic-gate 	if (objp->owner.owner_val != NULL)
28267c478bd9Sstevel@tonic-gate 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
28277c478bd9Sstevel@tonic-gate 	return (TRUE);
28287c478bd9Sstevel@tonic-gate }
28297c478bd9Sstevel@tonic-gate 
28307c478bd9Sstevel@tonic-gate static bool_t
28317c478bd9Sstevel@tonic-gate xdr_LOCKT4res(XDR *xdrs, LOCKT4res *objp)
28327c478bd9Sstevel@tonic-gate {
28337c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
28347c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
28357c478bd9Sstevel@tonic-gate 			return (FALSE);
28367c478bd9Sstevel@tonic-gate 		if (objp->status == NFS4_OK)
28377c478bd9Sstevel@tonic-gate 			return (TRUE);
28387c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4ERR_DENIED)
28397c478bd9Sstevel@tonic-gate 			return (TRUE);
28407c478bd9Sstevel@tonic-gate 		/* xdr_LOCK4denied */
28417c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28427c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->denied.offset))
28437c478bd9Sstevel@tonic-gate 			return (FALSE);
28447c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28457c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->denied.length))
28467c478bd9Sstevel@tonic-gate 			return (FALSE);
28477c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->denied.locktype))
28487c478bd9Sstevel@tonic-gate 			return (FALSE);
28497c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28507c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->denied.owner.clientid))
28517c478bd9Sstevel@tonic-gate 			return (FALSE);
28527c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
28537c478bd9Sstevel@tonic-gate 		    (char **)&objp->denied.owner.owner_val,
28547c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->denied.owner.owner_len,
28557c478bd9Sstevel@tonic-gate 		    NFS4_OPAQUE_LIMIT));
28567c478bd9Sstevel@tonic-gate 	}
28577c478bd9Sstevel@tonic-gate 
28587c478bd9Sstevel@tonic-gate 	/*
28597c478bd9Sstevel@tonic-gate 	 * Optimized free case
28607c478bd9Sstevel@tonic-gate 	 */
28617c478bd9Sstevel@tonic-gate 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
28627c478bd9Sstevel@tonic-gate 		return (TRUE);
28637c478bd9Sstevel@tonic-gate 	if (objp->denied.owner.owner_val != NULL)
28647c478bd9Sstevel@tonic-gate 		kmem_free(objp->denied.owner.owner_val,
28657c478bd9Sstevel@tonic-gate 		    objp->denied.owner.owner_len);
28667c478bd9Sstevel@tonic-gate 	return (TRUE);
28677c478bd9Sstevel@tonic-gate }
28687c478bd9Sstevel@tonic-gate 
28697c478bd9Sstevel@tonic-gate static bool_t
28707c478bd9Sstevel@tonic-gate xdr_LOCKU4args(XDR *xdrs, LOCKU4args *objp)
28717c478bd9Sstevel@tonic-gate {
28727c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->locktype))
28737c478bd9Sstevel@tonic-gate 		return (FALSE);
28747c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->seqid))
28757c478bd9Sstevel@tonic-gate 		return (FALSE);
28767c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->lock_stateid.seqid))
28777c478bd9Sstevel@tonic-gate 		return (FALSE);
2878bbe876c0SMarcel Telka 	if (!xdr_opaque(xdrs, objp->lock_stateid.other, NFS4_OTHER_SIZE))
28797c478bd9Sstevel@tonic-gate 		return (FALSE);
28807c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
28817c478bd9Sstevel@tonic-gate 		return (FALSE);
28827c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length));
28837c478bd9Sstevel@tonic-gate }
28847c478bd9Sstevel@tonic-gate 
28857c478bd9Sstevel@tonic-gate static bool_t
28867c478bd9Sstevel@tonic-gate xdr_OPEN4args(XDR *xdrs, OPEN4args *objp)
28877c478bd9Sstevel@tonic-gate {
28887c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
28897c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->seqid))
28907c478bd9Sstevel@tonic-gate 			return (FALSE);
28917c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->share_access))
28927c478bd9Sstevel@tonic-gate 			return (FALSE);
28937c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->share_deny))
28947c478bd9Sstevel@tonic-gate 			return (FALSE);
28957c478bd9Sstevel@tonic-gate 
28967c478bd9Sstevel@tonic-gate 		/* xdr_open_owner4 */
28977c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
28987c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->owner.clientid))
28997c478bd9Sstevel@tonic-gate 			return (FALSE);
29007c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
29017c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->owner.owner_len,
29027c478bd9Sstevel@tonic-gate 		    NFS4_OPAQUE_LIMIT))
29037c478bd9Sstevel@tonic-gate 			return (FALSE);
29047c478bd9Sstevel@tonic-gate 
29057c478bd9Sstevel@tonic-gate 		/* xdr_openflag4 */
29067c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->opentype))
29077c478bd9Sstevel@tonic-gate 			return (FALSE);
29087c478bd9Sstevel@tonic-gate 		if (objp->opentype == OPEN4_CREATE) {
29097c478bd9Sstevel@tonic-gate 
29107c478bd9Sstevel@tonic-gate 			/* xdr_createhow4 */
29117c478bd9Sstevel@tonic-gate 			if (!xdr_int(xdrs, (int *)&objp->mode))
29127c478bd9Sstevel@tonic-gate 				return (FALSE);
29137c478bd9Sstevel@tonic-gate 			switch (objp->mode) {
29147c478bd9Sstevel@tonic-gate 			case UNCHECKED4:
29157c478bd9Sstevel@tonic-gate 			case GUARDED4:
29167c478bd9Sstevel@tonic-gate 				if (!xdr_fattr4(xdrs,
29177c478bd9Sstevel@tonic-gate 				    &objp->createhow4_u.createattrs))
29187c478bd9Sstevel@tonic-gate 					return (FALSE);
29197c478bd9Sstevel@tonic-gate 				break;
29207c478bd9Sstevel@tonic-gate 			case EXCLUSIVE4:
29217c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs,
29227c478bd9Sstevel@tonic-gate 				    (u_longlong_t *)&objp->createhow4_u.
29237c478bd9Sstevel@tonic-gate 				    createverf))
29247c478bd9Sstevel@tonic-gate 					return (FALSE);
29257c478bd9Sstevel@tonic-gate 				break;
29267c478bd9Sstevel@tonic-gate 			default:
29277c478bd9Sstevel@tonic-gate 				return (FALSE);
29287c478bd9Sstevel@tonic-gate 			}
29297c478bd9Sstevel@tonic-gate 		}
29307c478bd9Sstevel@tonic-gate 
29317c478bd9Sstevel@tonic-gate 		/* xdr_open_claim4 */
29327c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->claim))
29337c478bd9Sstevel@tonic-gate 			return (FALSE);
29347c478bd9Sstevel@tonic-gate 
29357c478bd9Sstevel@tonic-gate 		switch (objp->claim) {
29367c478bd9Sstevel@tonic-gate 		case CLAIM_NULL:
29377c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
29387c478bd9Sstevel@tonic-gate 			    file.utf8string_val,
29397c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->open_claim4_u.file.
29407c478bd9Sstevel@tonic-gate 			    utf8string_len,
29417c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING));
29427c478bd9Sstevel@tonic-gate 		case CLAIM_PREVIOUS:
29437c478bd9Sstevel@tonic-gate 			return (xdr_int(xdrs,
29447c478bd9Sstevel@tonic-gate 			    (int *)&objp->open_claim4_u.delegate_type));
29457c478bd9Sstevel@tonic-gate 		case CLAIM_DELEGATE_CUR:
29467c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (uint_t *)&objp->open_claim4_u.
29477c478bd9Sstevel@tonic-gate 			    delegate_cur_info.delegate_stateid.seqid))
29487c478bd9Sstevel@tonic-gate 				return (FALSE);
29497c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->open_claim4_u.
29507c478bd9Sstevel@tonic-gate 			    delegate_cur_info.delegate_stateid.other,
2951bbe876c0SMarcel Telka 			    NFS4_OTHER_SIZE))
29527c478bd9Sstevel@tonic-gate 				return (FALSE);
29537c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
29547c478bd9Sstevel@tonic-gate 			    delegate_cur_info.file.utf8string_val,
29557c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->open_claim4_u.
29567c478bd9Sstevel@tonic-gate 			    delegate_cur_info.file.utf8string_len,
29577c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING));
29587c478bd9Sstevel@tonic-gate 		case CLAIM_DELEGATE_PREV:
29597c478bd9Sstevel@tonic-gate 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
29607c478bd9Sstevel@tonic-gate 			    file_delegate_prev.utf8string_val,
29617c478bd9Sstevel@tonic-gate 			    (uint_t *)&objp->open_claim4_u.
29627c478bd9Sstevel@tonic-gate 			    file_delegate_prev.utf8string_len,
29637c478bd9Sstevel@tonic-gate 			    NFS4_MAX_UTF8STRING));
29647c478bd9Sstevel@tonic-gate 		default:
29657c478bd9Sstevel@tonic-gate 			return (FALSE);
29667c478bd9Sstevel@tonic-gate 		}
29677c478bd9Sstevel@tonic-gate 	}
29687c478bd9Sstevel@tonic-gate 
29697c478bd9Sstevel@tonic-gate 	/*
29707c478bd9Sstevel@tonic-gate 	 * Optimized free case
29717c478bd9Sstevel@tonic-gate 	 */
29727c478bd9Sstevel@tonic-gate 	if (objp->owner.owner_val != NULL)
29737c478bd9Sstevel@tonic-gate 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
29747c478bd9Sstevel@tonic-gate 
29757c478bd9Sstevel@tonic-gate 	if (objp->opentype == OPEN4_CREATE) {
29767c478bd9Sstevel@tonic-gate 		switch (objp->mode) {
29777c478bd9Sstevel@tonic-gate 		case UNCHECKED4:
29787c478bd9Sstevel@tonic-gate 		case GUARDED4:
29797c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
29807c478bd9Sstevel@tonic-gate 			    &objp->createhow4_u.createattrs);
29817c478bd9Sstevel@tonic-gate 			break;
29827c478bd9Sstevel@tonic-gate 		case EXCLUSIVE4:
29837c478bd9Sstevel@tonic-gate 		default:
29847c478bd9Sstevel@tonic-gate 			break;
29857c478bd9Sstevel@tonic-gate 		}
29867c478bd9Sstevel@tonic-gate 	}
29877c478bd9Sstevel@tonic-gate 
29887c478bd9Sstevel@tonic-gate 	switch (objp->claim) {
29897c478bd9Sstevel@tonic-gate 	case CLAIM_NULL:
29907c478bd9Sstevel@tonic-gate 		if (objp->open_claim4_u.file.utf8string_val != NULL)
29917c478bd9Sstevel@tonic-gate 			kmem_free(objp->open_claim4_u.file.utf8string_val,
29927c478bd9Sstevel@tonic-gate 			    objp->open_claim4_u.file.utf8string_len);
29937c478bd9Sstevel@tonic-gate 		return (TRUE);
29947c478bd9Sstevel@tonic-gate 	case CLAIM_PREVIOUS:
29957c478bd9Sstevel@tonic-gate 		return (TRUE);
29967c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_CUR:
29977c478bd9Sstevel@tonic-gate 		if (objp->open_claim4_u.delegate_cur_info.file.utf8string_val !=
29987c478bd9Sstevel@tonic-gate 		    NULL) {
29997c478bd9Sstevel@tonic-gate 			kmem_free(objp->open_claim4_u.delegate_cur_info.file.
30007c478bd9Sstevel@tonic-gate 			    utf8string_val,
30017c478bd9Sstevel@tonic-gate 			    objp->open_claim4_u.delegate_cur_info.file.
30027c478bd9Sstevel@tonic-gate 			    utf8string_len);
30037c478bd9Sstevel@tonic-gate 		}
30047c478bd9Sstevel@tonic-gate 		return (TRUE);
30057c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_PREV:
30067c478bd9Sstevel@tonic-gate 		if (objp->open_claim4_u.file_delegate_prev.utf8string_val !=
30077c478bd9Sstevel@tonic-gate 		    NULL) {
30087c478bd9Sstevel@tonic-gate 			kmem_free(objp->open_claim4_u.file_delegate_prev.
30097c478bd9Sstevel@tonic-gate 			    utf8string_val,
30107c478bd9Sstevel@tonic-gate 			    objp->open_claim4_u.file_delegate_prev.
30117c478bd9Sstevel@tonic-gate 			    utf8string_len);
30127c478bd9Sstevel@tonic-gate 		}
30137c478bd9Sstevel@tonic-gate 		return (TRUE);
30147c478bd9Sstevel@tonic-gate 	default:
30157c478bd9Sstevel@tonic-gate 		return (TRUE);
30167c478bd9Sstevel@tonic-gate 	}
30177c478bd9Sstevel@tonic-gate }
30187c478bd9Sstevel@tonic-gate 
30197c478bd9Sstevel@tonic-gate static bool_t
30207c478bd9Sstevel@tonic-gate xdr_OPEN4cargs(XDR *xdrs, OPEN4cargs *objp)
30217c478bd9Sstevel@tonic-gate {
30227c478bd9Sstevel@tonic-gate 	int op;
30237c478bd9Sstevel@tonic-gate 	int len;
30247c478bd9Sstevel@tonic-gate 	rpc_inline_t *ptr;
30257c478bd9Sstevel@tonic-gate 
30267c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
30277c478bd9Sstevel@tonic-gate 
30287c478bd9Sstevel@tonic-gate 	/*
30297c478bd9Sstevel@tonic-gate 	 * We must always define the client's open_owner to be
30307c478bd9Sstevel@tonic-gate 	 * 4 byte aligned and sized.
30317c478bd9Sstevel@tonic-gate 	 */
30327c478bd9Sstevel@tonic-gate 	ASSERT(objp->owner.owner_len <= NFS4_OPAQUE_LIMIT);
30337c478bd9Sstevel@tonic-gate 	ASSERT(!(objp->owner.owner_len % BYTES_PER_XDR_UNIT));
30347c478bd9Sstevel@tonic-gate 
30357c478bd9Sstevel@tonic-gate 	len = objp->owner.owner_len;
30367c478bd9Sstevel@tonic-gate 	if ((ptr = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + len)) != NULL) {
30377c478bd9Sstevel@tonic-gate 		int i;
30387c478bd9Sstevel@tonic-gate 		int32_t *ip;
30397c478bd9Sstevel@tonic-gate 
30407c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, OP_OPEN);
30417c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->seqid);
30427c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->share_access);
30437c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->share_deny);
30447c478bd9Sstevel@tonic-gate 
30457c478bd9Sstevel@tonic-gate 		/* xdr_open_owner4 */
30467c478bd9Sstevel@tonic-gate 		IXDR_PUT_HYPER(ptr, objp->owner.clientid);
30477c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->owner.owner_len);
30487c478bd9Sstevel@tonic-gate 		/* We know this is very short so don't bcopy */
30497c478bd9Sstevel@tonic-gate 		ip = (int32_t *)objp->owner.owner_val;
30507c478bd9Sstevel@tonic-gate 		len /= BYTES_PER_XDR_UNIT;
30517c478bd9Sstevel@tonic-gate 		for (i = 0; i < len; i++)
30527c478bd9Sstevel@tonic-gate 			*ptr++ = *ip++;
30537c478bd9Sstevel@tonic-gate 
30547c478bd9Sstevel@tonic-gate 		/* xdr_openflag4 */
30557c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, objp->opentype);
30567c478bd9Sstevel@tonic-gate 	} else {
30577c478bd9Sstevel@tonic-gate 		op = OP_OPEN;
30587c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&op))
30597c478bd9Sstevel@tonic-gate 			return (FALSE);
30607c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->seqid))
30617c478bd9Sstevel@tonic-gate 			return (FALSE);
30627c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_access))
30637c478bd9Sstevel@tonic-gate 			return (FALSE);
30647c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_deny))
30657c478bd9Sstevel@tonic-gate 			return (FALSE);
30667c478bd9Sstevel@tonic-gate 
30677c478bd9Sstevel@tonic-gate 		/* xdr_open_owner4 */
30687c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
30697c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->owner.clientid))
30707c478bd9Sstevel@tonic-gate 			return (FALSE);
30717c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->owner.owner_len))
30727c478bd9Sstevel@tonic-gate 			return (FALSE);
30737c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->owner.owner_val,
30747c478bd9Sstevel@tonic-gate 		    objp->owner.owner_len))
30757c478bd9Sstevel@tonic-gate 			return (FALSE);
30767c478bd9Sstevel@tonic-gate 
30777c478bd9Sstevel@tonic-gate 		/* xdr_openflag4 */
30787c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->opentype))
30797c478bd9Sstevel@tonic-gate 			return (FALSE);
30807c478bd9Sstevel@tonic-gate 	}
30817c478bd9Sstevel@tonic-gate 
30827c478bd9Sstevel@tonic-gate 	if (objp->opentype == OPEN4_CREATE) {
30837c478bd9Sstevel@tonic-gate 		/* xdr_createhow4 */
30847c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->mode))
30857c478bd9Sstevel@tonic-gate 			return (FALSE);
30867c478bd9Sstevel@tonic-gate 		switch (objp->mode) {
30877c478bd9Sstevel@tonic-gate 		case UNCHECKED4:
30887c478bd9Sstevel@tonic-gate 		case GUARDED4:
30897c478bd9Sstevel@tonic-gate 			if (!xdr_fattr4(xdrs,
30907c478bd9Sstevel@tonic-gate 			    &objp->createhow4_u.createattrs))
30917c478bd9Sstevel@tonic-gate 				return (FALSE);
30927c478bd9Sstevel@tonic-gate 			break;
30937c478bd9Sstevel@tonic-gate 		case EXCLUSIVE4:
30947c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
30957c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->createhow4_u.
30967c478bd9Sstevel@tonic-gate 			    createverf))
30977c478bd9Sstevel@tonic-gate 				return (FALSE);
30987c478bd9Sstevel@tonic-gate 			break;
30997c478bd9Sstevel@tonic-gate 		default:
31007c478bd9Sstevel@tonic-gate 			return (FALSE);
31017c478bd9Sstevel@tonic-gate 		}
31027c478bd9Sstevel@tonic-gate 	}
31037c478bd9Sstevel@tonic-gate 
31047c478bd9Sstevel@tonic-gate 	/* xdr_open_claim4 */
31057c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->claim))
31067c478bd9Sstevel@tonic-gate 		return (FALSE);
31077c478bd9Sstevel@tonic-gate 
31087c478bd9Sstevel@tonic-gate 	switch (objp->claim) {
31097c478bd9Sstevel@tonic-gate 	case CLAIM_NULL:
31107c478bd9Sstevel@tonic-gate 		len = strlen(objp->open_claim4_u.cfile);
31117c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
31127c478bd9Sstevel@tonic-gate 			return (FALSE);
31137c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
31147c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
31157c478bd9Sstevel@tonic-gate 			    objp->open_claim4_u.cfile, len));
31167c478bd9Sstevel@tonic-gate 		}
31177c478bd9Sstevel@tonic-gate 		return (FALSE);
31187c478bd9Sstevel@tonic-gate 	case CLAIM_PREVIOUS:
31197c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs,
31207c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->open_claim4_u.delegate_type));
31217c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_CUR:
31227c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->open_claim4_u.
31237c478bd9Sstevel@tonic-gate 		    delegate_cur_info.delegate_stateid.seqid))
31247c478bd9Sstevel@tonic-gate 			return (FALSE);
31257c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->open_claim4_u.
31267c478bd9Sstevel@tonic-gate 		    delegate_cur_info.delegate_stateid.other,
3127bbe876c0SMarcel Telka 		    NFS4_OTHER_SIZE))
31287c478bd9Sstevel@tonic-gate 			return (FALSE);
31297c478bd9Sstevel@tonic-gate 		len = strlen(objp->open_claim4_u.delegate_cur_info.cfile);
31307c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
31317c478bd9Sstevel@tonic-gate 			return (FALSE);
31327c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
31337c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
31347c478bd9Sstevel@tonic-gate 			    objp->open_claim4_u.delegate_cur_info.cfile,
31357c478bd9Sstevel@tonic-gate 			    len));
31367c478bd9Sstevel@tonic-gate 		}
31377c478bd9Sstevel@tonic-gate 		return (FALSE);
31387c478bd9Sstevel@tonic-gate 	case CLAIM_DELEGATE_PREV:
31397c478bd9Sstevel@tonic-gate 		len = strlen(objp->open_claim4_u.cfile_delegate_prev);
31407c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
31417c478bd9Sstevel@tonic-gate 			return (FALSE);
31427c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
31437c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
31447c478bd9Sstevel@tonic-gate 			    objp->open_claim4_u.cfile_delegate_prev, len));
31457c478bd9Sstevel@tonic-gate 		}
31467c478bd9Sstevel@tonic-gate 		return (FALSE);
31477c478bd9Sstevel@tonic-gate 	default:
31487c478bd9Sstevel@tonic-gate 		return (FALSE);
31497c478bd9Sstevel@tonic-gate 	}
31507c478bd9Sstevel@tonic-gate }
31517c478bd9Sstevel@tonic-gate 
31527c478bd9Sstevel@tonic-gate static bool_t
31537c478bd9Sstevel@tonic-gate xdr_OPEN4res(XDR *xdrs, OPEN4res *objp)
31547c478bd9Sstevel@tonic-gate {
31557c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
31567c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
31577c478bd9Sstevel@tonic-gate 			return (FALSE);
31587c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
31597c478bd9Sstevel@tonic-gate 			return (TRUE);
31607c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
31617c478bd9Sstevel@tonic-gate 			return (FALSE);
3162bbe876c0SMarcel Telka 		if (!xdr_opaque(xdrs, objp->stateid.other, NFS4_OTHER_SIZE))
31637c478bd9Sstevel@tonic-gate 			return (FALSE);
31647c478bd9Sstevel@tonic-gate 		if (!xdr_bool(xdrs, &objp->cinfo.atomic))
31657c478bd9Sstevel@tonic-gate 			return (FALSE);
31667c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
31677c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->cinfo.before))
31687c478bd9Sstevel@tonic-gate 			return (FALSE);
31697c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
31707c478bd9Sstevel@tonic-gate 			return (FALSE);
31717c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->rflags))
31727c478bd9Sstevel@tonic-gate 			return (FALSE);
31737c478bd9Sstevel@tonic-gate 		if (!xdr_bitmap4(xdrs, &objp->attrset))
31747c478bd9Sstevel@tonic-gate 			return (FALSE);
31757c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
31767c478bd9Sstevel@tonic-gate 		    (int *)&objp->delegation.delegation_type))
31777c478bd9Sstevel@tonic-gate 			return (FALSE);
31787c478bd9Sstevel@tonic-gate 		switch (objp->delegation.delegation_type) {
31797c478bd9Sstevel@tonic-gate 		case OPEN_DELEGATE_NONE:
31807c478bd9Sstevel@tonic-gate 			return (TRUE);
31817c478bd9Sstevel@tonic-gate 		case OPEN_DELEGATE_READ:
31827c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->delegation.
31837c478bd9Sstevel@tonic-gate 			    open_delegation4_u.read.stateid.seqid))
31847c478bd9Sstevel@tonic-gate 				return (FALSE);
31857c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->delegation.
31867c478bd9Sstevel@tonic-gate 			    open_delegation4_u.read.stateid.other,
3187bbe876c0SMarcel Telka 			    NFS4_OTHER_SIZE))
31887c478bd9Sstevel@tonic-gate 				return (FALSE);
31897c478bd9Sstevel@tonic-gate 			if (!xdr_bool(xdrs, &objp->delegation.
31907c478bd9Sstevel@tonic-gate 			    open_delegation4_u.read.recall))
31917c478bd9Sstevel@tonic-gate 				return (FALSE);
31927c478bd9Sstevel@tonic-gate 			return (xdr_nfsace4(xdrs, &objp->delegation.
31937c478bd9Sstevel@tonic-gate 			    open_delegation4_u.read.permissions));
31947c478bd9Sstevel@tonic-gate 		case OPEN_DELEGATE_WRITE:
31957c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, &objp->delegation.
31967c478bd9Sstevel@tonic-gate 			    open_delegation4_u.write.stateid.seqid))
31977c478bd9Sstevel@tonic-gate 				return (FALSE);
31987c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, objp->delegation.
31997c478bd9Sstevel@tonic-gate 			    open_delegation4_u.write.stateid.other,
3200bbe876c0SMarcel Telka 			    NFS4_OTHER_SIZE))
32017c478bd9Sstevel@tonic-gate 				return (FALSE);
32027c478bd9Sstevel@tonic-gate 			if (!xdr_bool(xdrs, &objp->delegation.
32037c478bd9Sstevel@tonic-gate 			    open_delegation4_u.write.recall))
32047c478bd9Sstevel@tonic-gate 				return (FALSE);
32057c478bd9Sstevel@tonic-gate 			if (!xdr_int(xdrs, (int *)&objp->delegation.
32067c478bd9Sstevel@tonic-gate 			    open_delegation4_u.write.space_limit.
32077c478bd9Sstevel@tonic-gate 			    limitby))
32087c478bd9Sstevel@tonic-gate 				return (FALSE);
32097c478bd9Sstevel@tonic-gate 			switch (objp->delegation.
32107c478bd9Sstevel@tonic-gate 			    open_delegation4_u.write.space_limit.
32117c478bd9Sstevel@tonic-gate 			    limitby) {
32127c478bd9Sstevel@tonic-gate 			case NFS_LIMIT_SIZE:
32137c478bd9Sstevel@tonic-gate 				if (!xdr_u_longlong_t(xdrs,
32147c478bd9Sstevel@tonic-gate 				    (u_longlong_t *)&objp->delegation.
32157c478bd9Sstevel@tonic-gate 				    open_delegation4_u.write.space_limit.
32167c478bd9Sstevel@tonic-gate 				    nfs_space_limit4_u.filesize))
32177c478bd9Sstevel@tonic-gate 					return (FALSE);
32187c478bd9Sstevel@tonic-gate 				break;
32197c478bd9Sstevel@tonic-gate 			case NFS_LIMIT_BLOCKS:
32207c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs,
32217c478bd9Sstevel@tonic-gate 				    &objp->delegation.open_delegation4_u.write.
32227c478bd9Sstevel@tonic-gate 				    space_limit.nfs_space_limit4_u.
32237c478bd9Sstevel@tonic-gate 				    mod_blocks.num_blocks))
32247c478bd9Sstevel@tonic-gate 					return (FALSE);
32257c478bd9Sstevel@tonic-gate 				if (!xdr_u_int(xdrs, &objp->delegation.
32267c478bd9Sstevel@tonic-gate 				    open_delegation4_u.write.space_limit.
32277c478bd9Sstevel@tonic-gate 				    nfs_space_limit4_u.mod_blocks.
32287c478bd9Sstevel@tonic-gate 				    bytes_per_block))
32297c478bd9Sstevel@tonic-gate 					return (FALSE);
32307c478bd9Sstevel@tonic-gate 				break;
32317c478bd9Sstevel@tonic-gate 			default:
32327c478bd9Sstevel@tonic-gate 				return (FALSE);
32337c478bd9Sstevel@tonic-gate 			}
32347c478bd9Sstevel@tonic-gate 			return (xdr_nfsace4(xdrs, &objp->delegation.
32357c478bd9Sstevel@tonic-gate 			    open_delegation4_u.write.permissions));
32367c478bd9Sstevel@tonic-gate 		}
32377c478bd9Sstevel@tonic-gate 		return (FALSE);
32387c478bd9Sstevel@tonic-gate 	}
32397c478bd9Sstevel@tonic-gate 
32407c478bd9Sstevel@tonic-gate 	/*
32417c478bd9Sstevel@tonic-gate 	 * Optimized free case
32427c478bd9Sstevel@tonic-gate 	 */
32437c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
32447c478bd9Sstevel@tonic-gate 		return (TRUE);
32457c478bd9Sstevel@tonic-gate 
32467c478bd9Sstevel@tonic-gate 	switch (objp->delegation.delegation_type) {
32477c478bd9Sstevel@tonic-gate 	case OPEN_DELEGATE_NONE:
32487c478bd9Sstevel@tonic-gate 		return (TRUE);
32497c478bd9Sstevel@tonic-gate 	case OPEN_DELEGATE_READ:
32507c478bd9Sstevel@tonic-gate 		return (xdr_nfsace4(xdrs, &objp->delegation.
32517c478bd9Sstevel@tonic-gate 		    open_delegation4_u.read.permissions));
32527c478bd9Sstevel@tonic-gate 	case OPEN_DELEGATE_WRITE:
32537c478bd9Sstevel@tonic-gate 		switch (objp->delegation.
32547c478bd9Sstevel@tonic-gate 		    open_delegation4_u.write.space_limit.limitby) {
32557c478bd9Sstevel@tonic-gate 		case NFS_LIMIT_SIZE:
32567c478bd9Sstevel@tonic-gate 		case NFS_LIMIT_BLOCKS:
32577c478bd9Sstevel@tonic-gate 			break;
32587c478bd9Sstevel@tonic-gate 		default:
32597c478bd9Sstevel@tonic-gate 			return (FALSE);
32607c478bd9Sstevel@tonic-gate 		}
32617c478bd9Sstevel@tonic-gate 		return (xdr_nfsace4(xdrs, &objp->delegation.
32627c478bd9Sstevel@tonic-gate 		    open_delegation4_u.write.permissions));
32637c478bd9Sstevel@tonic-gate 	}
32647c478bd9Sstevel@tonic-gate 	return (FALSE);
32657c478bd9Sstevel@tonic-gate }
32667c478bd9Sstevel@tonic-gate 
32677c478bd9Sstevel@tonic-gate static bool_t
32687c478bd9Sstevel@tonic-gate xdr_OPEN_CONFIRM4res(XDR *xdrs, OPEN_CONFIRM4res *objp)
32697c478bd9Sstevel@tonic-gate {
32707c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
32717c478bd9Sstevel@tonic-gate 		return (FALSE);
32727c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
32737c478bd9Sstevel@tonic-gate 		return (TRUE);
32747c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
32757c478bd9Sstevel@tonic-gate 		return (FALSE);
3276bbe876c0SMarcel Telka 	return (xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE));
32777c478bd9Sstevel@tonic-gate }
32787c478bd9Sstevel@tonic-gate 
32797c478bd9Sstevel@tonic-gate static bool_t
32807c478bd9Sstevel@tonic-gate xdr_OPEN_DOWNGRADE4args(XDR *xdrs, OPEN_DOWNGRADE4args *objp)
32817c478bd9Sstevel@tonic-gate {
32827c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
32837c478bd9Sstevel@tonic-gate 		return (FALSE);
3284bbe876c0SMarcel Telka 	if (!xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE))
32857c478bd9Sstevel@tonic-gate 		return (FALSE);
32867c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->seqid))
32877c478bd9Sstevel@tonic-gate 		return (FALSE);
32887c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->share_access))
32897c478bd9Sstevel@tonic-gate 		return (FALSE);
32907c478bd9Sstevel@tonic-gate 	return (xdr_u_int(xdrs, &objp->share_deny));
32917c478bd9Sstevel@tonic-gate }
32927c478bd9Sstevel@tonic-gate 
32937c478bd9Sstevel@tonic-gate static bool_t
32947c478bd9Sstevel@tonic-gate xdr_OPEN_DOWNGRADE4res(XDR *xdrs, OPEN_DOWNGRADE4res *objp)
32957c478bd9Sstevel@tonic-gate {
32967c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
32977c478bd9Sstevel@tonic-gate 		return (FALSE);
32987c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
32997c478bd9Sstevel@tonic-gate 		return (TRUE);
33007c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
33017c478bd9Sstevel@tonic-gate 		return (FALSE);
3302bbe876c0SMarcel Telka 	return (xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE));
33037c478bd9Sstevel@tonic-gate }
33047c478bd9Sstevel@tonic-gate 
33057c478bd9Sstevel@tonic-gate static bool_t
33067c478bd9Sstevel@tonic-gate xdr_READ4args(XDR *xdrs, READ4args *objp)
33077c478bd9Sstevel@tonic-gate {
33080a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
33090a701b1eSRobert Gordon 	rdma_wlist_conn_info_t rwci;
33100a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
33110a701b1eSRobert Gordon 
33127c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->stateid.seqid))
33137c478bd9Sstevel@tonic-gate 		return (FALSE);
3314bbe876c0SMarcel Telka 	if (!xdr_opaque(xdrs, objp->stateid.other, NFS4_OTHER_SIZE))
33157c478bd9Sstevel@tonic-gate 		return (FALSE);
33167c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
33177c478bd9Sstevel@tonic-gate 		return (FALSE);
33180a701b1eSRobert Gordon 	if (!xdr_u_int(xdrs, &objp->count))
33190a701b1eSRobert Gordon 		return (FALSE);
33200a701b1eSRobert Gordon 
33210a701b1eSRobert Gordon 	DTRACE_PROBE1(xdr__i__read4args_buf_len,
33220a701b1eSRobert Gordon 	    int, objp->count);
33230a701b1eSRobert Gordon 
33240a701b1eSRobert Gordon 	objp->wlist = NULL;
33250a701b1eSRobert Gordon 
33260a701b1eSRobert Gordon 	if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
33270a701b1eSRobert Gordon 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
33280a701b1eSRobert Gordon 		rci.rci_len = objp->count;
33290a701b1eSRobert Gordon 		(void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
33300a701b1eSRobert Gordon 	}
33310a701b1eSRobert Gordon 
33320a701b1eSRobert Gordon 	if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
33330a701b1eSRobert Gordon 		return (TRUE);
33340a701b1eSRobert Gordon 
33350a701b1eSRobert Gordon 	if (xdrs->x_op == XDR_ENCODE) {
33360a701b1eSRobert Gordon 		if (objp->res_uiop != NULL) {
33370a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_UIO_CHUNK;
33380a701b1eSRobert Gordon 			rci.rci_a.rci_uiop = objp->res_uiop;
33390a701b1eSRobert Gordon 			rci.rci_len = objp->count;
33400a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
33410a701b1eSRobert Gordon 		} else {
33420a701b1eSRobert Gordon 			rci.rci_type = RCI_WRITE_ADDR_CHUNK;
33430a701b1eSRobert Gordon 			rci.rci_a.rci_addr = objp->res_data_val_alt;
33440a701b1eSRobert Gordon 			rci.rci_len = objp->count;
33450a701b1eSRobert Gordon 			rci.rci_clpp = &objp->wlist;
33460a701b1eSRobert Gordon 		}
33470a701b1eSRobert Gordon 
33480a701b1eSRobert Gordon 		return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
33490a701b1eSRobert Gordon 	}
33500a701b1eSRobert Gordon 
33510a701b1eSRobert Gordon 	/* XDR_DECODE case */
33520a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
33530a701b1eSRobert Gordon 	objp->wlist = rwci.rwci_wlist;
33540a701b1eSRobert Gordon 	objp->conn = rwci.rwci_conn;
33550a701b1eSRobert Gordon 
33560a701b1eSRobert Gordon 	return (TRUE);
33577c478bd9Sstevel@tonic-gate }
33587c478bd9Sstevel@tonic-gate 
33597c478bd9Sstevel@tonic-gate static bool_t
33607c478bd9Sstevel@tonic-gate xdr_READ4res(XDR *xdrs, READ4res *objp)
33617c478bd9Sstevel@tonic-gate {
33627c478bd9Sstevel@tonic-gate 	mblk_t *mp;
33637c478bd9Sstevel@tonic-gate 
33647c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
33657c478bd9Sstevel@tonic-gate 		return (FALSE);
33667c478bd9Sstevel@tonic-gate 
33677c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE) {
33687c478bd9Sstevel@tonic-gate 		/*
33697c478bd9Sstevel@tonic-gate 		 * Optimized free case
33707c478bd9Sstevel@tonic-gate 		 */
33717c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
33727c478bd9Sstevel@tonic-gate 			return (TRUE);
33737c478bd9Sstevel@tonic-gate 		if (objp->data_val != NULL)
33747c478bd9Sstevel@tonic-gate 			kmem_free(objp->data_val, objp->data_len);
33757c478bd9Sstevel@tonic-gate 		return (TRUE);
33767c478bd9Sstevel@tonic-gate 	}
33777c478bd9Sstevel@tonic-gate 
33787c478bd9Sstevel@tonic-gate 	/* on with ENCODE paths */
33797c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->status))
33807c478bd9Sstevel@tonic-gate 		return (FALSE);
33817c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
33827c478bd9Sstevel@tonic-gate 		return (TRUE);
33837c478bd9Sstevel@tonic-gate 
33847c478bd9Sstevel@tonic-gate 	if (!XDR_PUTINT32(xdrs, &objp->eof))
33857c478bd9Sstevel@tonic-gate 		return (FALSE);
33867c478bd9Sstevel@tonic-gate 
33877c478bd9Sstevel@tonic-gate 	mp = objp->mblk;
3388e36d7b11SSebastien Roy 	if (mp != NULL) {
3389e36d7b11SSebastien Roy 		if (xdrs->x_ops == &xdrmblk_ops) {
3390e36d7b11SSebastien Roy 			if (xdrmblk_putmblk(xdrs, mp, objp->data_len)) {
33917c478bd9Sstevel@tonic-gate 				objp->mblk = NULL;
33927c478bd9Sstevel@tonic-gate 				return (TRUE);
3393e36d7b11SSebastien Roy 			} else {
3394e36d7b11SSebastien Roy 				return (FALSE);
33957c478bd9Sstevel@tonic-gate 			}
3396e36d7b11SSebastien Roy 		} else if (mp->b_cont != NULL) {
3397e36d7b11SSebastien Roy 			/*
3398e36d7b11SSebastien Roy 			 * See xdr_READ3res() for an explanation of why we need
3399e36d7b11SSebastien Roy 			 * to do a pullup here.
3400e36d7b11SSebastien Roy 			 */
3401e36d7b11SSebastien Roy 			if (pullupmsg(mp, -1) == 0)
3402e36d7b11SSebastien Roy 				return (FALSE);
3403e36d7b11SSebastien Roy 			objp->data_val = (caddr_t)mp->b_rptr;
3404e36d7b11SSebastien Roy 		}
3405e36d7b11SSebastien Roy 	} else {
34060a701b1eSRobert Gordon 		if (xdr_u_int(xdrs, &objp->data_len) == FALSE) {
34070a701b1eSRobert Gordon 			return (FALSE);
34087c478bd9Sstevel@tonic-gate 		}
34090a701b1eSRobert Gordon 		/*
34100a701b1eSRobert Gordon 		 * If read data sent by wlist (RDMA_WRITE), don't do
34110a701b1eSRobert Gordon 		 * xdr_bytes() below.   RDMA_WRITE transfers the data.
34120a701b1eSRobert Gordon 		 * Note: this is encode-only because the client code
34130a701b1eSRobert Gordon 		 * uses xdr_READ4res_clnt to decode results.
34140a701b1eSRobert Gordon 		 */
34150a701b1eSRobert Gordon 		if (objp->wlist) {
34160a701b1eSRobert Gordon 			if (objp->data_len != 0) {
34170a701b1eSRobert Gordon 				return (xdrrdma_send_read_data(
3418f837ee4aSSiddheshwar Mahesh 				    xdrs, objp->data_len, objp->wlist));
34190a701b1eSRobert Gordon 			}
34200a701b1eSRobert Gordon 			return (TRUE);
34210a701b1eSRobert Gordon 		}
34220a701b1eSRobert Gordon 	}
34230a701b1eSRobert Gordon 
34247c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, (char **)&objp->data_val,
34257c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->data_len,
34267c478bd9Sstevel@tonic-gate 	    objp->data_len));
34277c478bd9Sstevel@tonic-gate }
34287c478bd9Sstevel@tonic-gate 
34297c478bd9Sstevel@tonic-gate static bool_t
34307c478bd9Sstevel@tonic-gate xdr_READ4res_clnt(XDR *xdrs, READ4res *objp, READ4args *aobjp)
34317c478bd9Sstevel@tonic-gate {
34327c478bd9Sstevel@tonic-gate 	mblk_t *mp;
34337c478bd9Sstevel@tonic-gate 	size_t n;
34347c478bd9Sstevel@tonic-gate 	int error;
34357c478bd9Sstevel@tonic-gate 	uint_t size = aobjp->res_maxsize;
34360a701b1eSRobert Gordon 	count4 ocount;
34377c478bd9Sstevel@tonic-gate 
34387c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
34397c478bd9Sstevel@tonic-gate 		return (FALSE);
34407c478bd9Sstevel@tonic-gate 
34417c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE) {
34427c478bd9Sstevel@tonic-gate 		/*
34437c478bd9Sstevel@tonic-gate 		 * Optimized free case
34447c478bd9Sstevel@tonic-gate 		 */
34457c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
34467c478bd9Sstevel@tonic-gate 			return (TRUE);
34477c478bd9Sstevel@tonic-gate 		if (objp->data_val != NULL)
34487c478bd9Sstevel@tonic-gate 			kmem_free(objp->data_val, objp->data_len);
34497c478bd9Sstevel@tonic-gate 		return (TRUE);
34507c478bd9Sstevel@tonic-gate 	}
34517c478bd9Sstevel@tonic-gate 
34527c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
34537c478bd9Sstevel@tonic-gate 		return (FALSE);
34547c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
34557c478bd9Sstevel@tonic-gate 		return (TRUE);
34567c478bd9Sstevel@tonic-gate 
34577c478bd9Sstevel@tonic-gate 	if (!XDR_GETINT32(xdrs, &objp->eof))
34587c478bd9Sstevel@tonic-gate 		return (FALSE);
34597c478bd9Sstevel@tonic-gate 
34607c478bd9Sstevel@tonic-gate 
34617c478bd9Sstevel@tonic-gate 	/*
34627c478bd9Sstevel@tonic-gate 	 * This is a special case such that the caller is providing a
34637c478bd9Sstevel@tonic-gate 	 * uio as a guide to eventual data location; this is used for
34647c478bd9Sstevel@tonic-gate 	 * handling DIRECTIO reads.
34657c478bd9Sstevel@tonic-gate 	 */
34667c478bd9Sstevel@tonic-gate 	if (aobjp->res_uiop != NULL) {
34677c478bd9Sstevel@tonic-gate 		struct uio *uiop = aobjp->res_uiop;
34687c478bd9Sstevel@tonic-gate 		int32_t *ptr;
34697c478bd9Sstevel@tonic-gate 
34707c478bd9Sstevel@tonic-gate 		if (xdrs->x_ops == &xdrmblk_ops) {
34717c478bd9Sstevel@tonic-gate 			if (!xdrmblk_getmblk(xdrs, &mp, &objp->data_len))
34727c478bd9Sstevel@tonic-gate 				return (FALSE);
34737c478bd9Sstevel@tonic-gate 
34747c478bd9Sstevel@tonic-gate 			if (objp->data_len == 0)
34757c478bd9Sstevel@tonic-gate 				return (TRUE);
34767c478bd9Sstevel@tonic-gate 
34777c478bd9Sstevel@tonic-gate 			if (objp->data_len > size)
34787c478bd9Sstevel@tonic-gate 				return (FALSE);
34797c478bd9Sstevel@tonic-gate 
34807c478bd9Sstevel@tonic-gate 			size = objp->data_len;
34817c478bd9Sstevel@tonic-gate 			do {
34827c478bd9Sstevel@tonic-gate 				n = MIN(size, mp->b_wptr - mp->b_rptr);
34837c478bd9Sstevel@tonic-gate 				if ((n = MIN(uiop->uio_resid, n)) != 0) {
34847c478bd9Sstevel@tonic-gate 
34857c478bd9Sstevel@tonic-gate 					error =	uiomove((char *)mp->b_rptr, n,
34867c478bd9Sstevel@tonic-gate 					    UIO_READ, uiop);
34877c478bd9Sstevel@tonic-gate 					if (error)
34887c478bd9Sstevel@tonic-gate 						return (FALSE);
34897c478bd9Sstevel@tonic-gate 					mp->b_rptr += n;
34907c478bd9Sstevel@tonic-gate 					size -= n;
34917c478bd9Sstevel@tonic-gate 				}
34927c478bd9Sstevel@tonic-gate 
34937c478bd9Sstevel@tonic-gate 				while (mp && (mp->b_rptr >= mp->b_wptr))
34947c478bd9Sstevel@tonic-gate 					mp = mp->b_cont;
34957c478bd9Sstevel@tonic-gate 			} while (mp && size > 0 && uiop->uio_resid > 0);
34967c478bd9Sstevel@tonic-gate 
34977c478bd9Sstevel@tonic-gate 			return (TRUE);
34987c478bd9Sstevel@tonic-gate 		}
34997c478bd9Sstevel@tonic-gate 
35000a701b1eSRobert Gordon 		if (xdrs->x_ops == &xdrrdma_ops) {
35010a701b1eSRobert Gordon 			struct clist *cl;
35020a701b1eSRobert Gordon 
35030a701b1eSRobert Gordon 			XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
35040a701b1eSRobert Gordon 
35050a701b1eSRobert Gordon 			objp->wlist = cl;
35060a701b1eSRobert Gordon 
35070a701b1eSRobert Gordon 			if (objp->wlist) {
35080a701b1eSRobert Gordon 				/* opaque count */
35090a701b1eSRobert Gordon 				if (!xdr_u_int(xdrs, &ocount)) {
35100a701b1eSRobert Gordon 					objp->wlist = NULL;
35110a701b1eSRobert Gordon 					return (FALSE);
35120a701b1eSRobert Gordon 				}
35130a701b1eSRobert Gordon 
3514f837ee4aSSiddheshwar Mahesh 				objp->wlist_len = clist_len(cl);
3515f837ee4aSSiddheshwar Mahesh 				objp->data_len = ocount;
35160a701b1eSRobert Gordon 
3517f837ee4aSSiddheshwar Mahesh 				if (objp->wlist_len !=
3518f837ee4aSSiddheshwar Mahesh 				    roundup(
3519f837ee4aSSiddheshwar Mahesh 				    objp->data_len, BYTES_PER_XDR_UNIT)) {
35200a701b1eSRobert Gordon 					DTRACE_PROBE2(
35210a701b1eSRobert Gordon 					    xdr__e__read4resuio_clnt_fail,
35220a701b1eSRobert Gordon 					    int, ocount,
35230a701b1eSRobert Gordon 					    int, objp->data_len);
35240a701b1eSRobert Gordon 					objp->wlist = NULL;
35250a701b1eSRobert Gordon 					return (FALSE);
35260a701b1eSRobert Gordon 				}
35270a701b1eSRobert Gordon 
35280a701b1eSRobert Gordon 				uiop->uio_resid -= objp->data_len;
35290a701b1eSRobert Gordon 				uiop->uio_iov->iov_len -= objp->data_len;
35300a701b1eSRobert Gordon 				uiop->uio_iov->iov_base += objp->data_len;
35310a701b1eSRobert Gordon 				uiop->uio_loffset += objp->data_len;
35320a701b1eSRobert Gordon 
35330a701b1eSRobert Gordon 				objp->wlist = NULL;
35340a701b1eSRobert Gordon 				return (TRUE);
35350a701b1eSRobert Gordon 			}
35360a701b1eSRobert Gordon 		}
35370a701b1eSRobert Gordon 
35387c478bd9Sstevel@tonic-gate 		/*
35390a701b1eSRobert Gordon 		 * This isn't an xdrmblk stream nor RDMA.
35400a701b1eSRobert Gordon 		 * Handle the likely case that it can be
35410a701b1eSRobert Gordon 		 * inlined (ex. xdrmem).
35427c478bd9Sstevel@tonic-gate 		 */
35437c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int32_t *)&objp->data_len))
35447c478bd9Sstevel@tonic-gate 			return (FALSE);
35457c478bd9Sstevel@tonic-gate 
35467c478bd9Sstevel@tonic-gate 		if (objp->data_len == 0)
35477c478bd9Sstevel@tonic-gate 			return (TRUE);
35487c478bd9Sstevel@tonic-gate 
35497c478bd9Sstevel@tonic-gate 		if (objp->data_len > size)
35507c478bd9Sstevel@tonic-gate 			return (FALSE);
35517c478bd9Sstevel@tonic-gate 
35527c478bd9Sstevel@tonic-gate 		size = (int)objp->data_len;
35537c478bd9Sstevel@tonic-gate 		if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
35547c478bd9Sstevel@tonic-gate 			return (uiomove(ptr, size, UIO_READ, uiop) ?
35557c478bd9Sstevel@tonic-gate 			    FALSE : TRUE);
35567c478bd9Sstevel@tonic-gate 
35577c478bd9Sstevel@tonic-gate 		/*
35587c478bd9Sstevel@tonic-gate 		 * Handle some other (unlikely) stream type that will
35597c478bd9Sstevel@tonic-gate 		 * need a copy.
35607c478bd9Sstevel@tonic-gate 		 */
35617c478bd9Sstevel@tonic-gate 		if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
35627c478bd9Sstevel@tonic-gate 			return (FALSE);
35637c478bd9Sstevel@tonic-gate 
35647c478bd9Sstevel@tonic-gate 		if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
35657c478bd9Sstevel@tonic-gate 			kmem_free(ptr, size);
35667c478bd9Sstevel@tonic-gate 			return (FALSE);
35677c478bd9Sstevel@tonic-gate 		}
35687c478bd9Sstevel@tonic-gate 		error = uiomove(ptr, size, UIO_READ, uiop);
35697c478bd9Sstevel@tonic-gate 		kmem_free(ptr, size);
35707c478bd9Sstevel@tonic-gate 
35717c478bd9Sstevel@tonic-gate 		return (error ? FALSE : TRUE);
35727c478bd9Sstevel@tonic-gate 	}
35737c478bd9Sstevel@tonic-gate 
35747c478bd9Sstevel@tonic-gate 	/*
35757c478bd9Sstevel@tonic-gate 	 * Check for the other special case of the caller providing
35767c478bd9Sstevel@tonic-gate 	 * the target area for the data.
35777c478bd9Sstevel@tonic-gate 	 */
35780a701b1eSRobert Gordon 	if (aobjp->res_data_val_alt == NULL)
35790a701b1eSRobert Gordon 		return (FALSE);
35800a701b1eSRobert Gordon 
35810a701b1eSRobert Gordon 	/*
35820a701b1eSRobert Gordon 	 * If read data received via RDMA_WRITE, don't do xdr_bytes().
35830a701b1eSRobert Gordon 	 * RDMA_WRITE already moved the data so decode length of
35840a701b1eSRobert Gordon 	 * RDMA_WRITE.
35850a701b1eSRobert Gordon 	 */
35860a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops) {
35870a701b1eSRobert Gordon 		struct clist *cl;
35880a701b1eSRobert Gordon 
35890a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
35900a701b1eSRobert Gordon 
35910a701b1eSRobert Gordon 		objp->wlist = cl;
35920a701b1eSRobert Gordon 
35930a701b1eSRobert Gordon 		/*
35940a701b1eSRobert Gordon 		 * Data transferred through inline if
35950a701b1eSRobert Gordon 		 * objp->wlist == NULL
35960a701b1eSRobert Gordon 		 */
35970a701b1eSRobert Gordon 		if (objp->wlist) {
35980a701b1eSRobert Gordon 			/* opaque count */
35990a701b1eSRobert Gordon 			if (!xdr_u_int(xdrs, &ocount)) {
36000a701b1eSRobert Gordon 				objp->wlist = NULL;
36010a701b1eSRobert Gordon 				return (FALSE);
36020a701b1eSRobert Gordon 			}
36030a701b1eSRobert Gordon 
3604f837ee4aSSiddheshwar Mahesh 			objp->wlist_len = clist_len(cl);
3605f837ee4aSSiddheshwar Mahesh 			objp->data_len = ocount;
36060a701b1eSRobert Gordon 
3607f837ee4aSSiddheshwar Mahesh 			if (objp->wlist_len !=
3608f837ee4aSSiddheshwar Mahesh 			    roundup(
3609f837ee4aSSiddheshwar Mahesh 			    objp->data_len, BYTES_PER_XDR_UNIT)) {
36100a701b1eSRobert Gordon 				DTRACE_PROBE2(
36110a701b1eSRobert Gordon 				    xdr__e__read4res_clnt_fail,
36120a701b1eSRobert Gordon 				    int, ocount,
36130a701b1eSRobert Gordon 				    int, objp->data_len);
36140a701b1eSRobert Gordon 				objp->wlist = NULL;
36150a701b1eSRobert Gordon 				return (FALSE);
36160a701b1eSRobert Gordon 			}
36170a701b1eSRobert Gordon 
36180a701b1eSRobert Gordon 			objp->wlist = NULL;
36190a701b1eSRobert Gordon 			return (TRUE);
36200a701b1eSRobert Gordon 		}
36210a701b1eSRobert Gordon 	}
36220a701b1eSRobert Gordon 
36237c478bd9Sstevel@tonic-gate 	return (xdr_bytes(xdrs, (char **)&aobjp->res_data_val_alt,
36247c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->data_len,
36257c478bd9Sstevel@tonic-gate 	    aobjp->res_maxsize));
36267c478bd9Sstevel@tonic-gate }
36277c478bd9Sstevel@tonic-gate 
36287c478bd9Sstevel@tonic-gate static bool_t
36297c478bd9Sstevel@tonic-gate xdr_READDIR4args(XDR *xdrs, READDIR4args *objp)
36307c478bd9Sstevel@tonic-gate {
36310a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
36320a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
36330a701b1eSRobert Gordon 
36340a701b1eSRobert Gordon 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
36350a701b1eSRobert Gordon 	    xdrs->x_op == XDR_ENCODE) {
36360a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
36370a701b1eSRobert Gordon 		rci.rci_len = objp->maxcount;
36380a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
36390a701b1eSRobert Gordon 	}
36400a701b1eSRobert Gordon 
36417c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookie))
36427c478bd9Sstevel@tonic-gate 		return (FALSE);
36437c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
36447c478bd9Sstevel@tonic-gate 		return (FALSE);
36457c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->dircount))
36467c478bd9Sstevel@tonic-gate 		return (FALSE);
36477c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->maxcount))
36487c478bd9Sstevel@tonic-gate 		return (FALSE);
36497c478bd9Sstevel@tonic-gate 	return (xdr_bitmap4(xdrs, &objp->attr_request));
36507c478bd9Sstevel@tonic-gate }
36517c478bd9Sstevel@tonic-gate 
36527c478bd9Sstevel@tonic-gate /* ARGSUSED */
36537c478bd9Sstevel@tonic-gate static bool_t
36547c478bd9Sstevel@tonic-gate xdrmblk_putmblk_rd(XDR *xdrs, mblk_t *m)
36557c478bd9Sstevel@tonic-gate {
36567c478bd9Sstevel@tonic-gate 	if (((m->b_wptr - m->b_rptr) % BYTES_PER_XDR_UNIT) != 0)
36577c478bd9Sstevel@tonic-gate 		return (FALSE);
36587c478bd9Sstevel@tonic-gate 
36597c478bd9Sstevel@tonic-gate 	/* LINTED pointer alignment */
36607c478bd9Sstevel@tonic-gate 	((mblk_t *)xdrs->x_base)->b_cont = m;
36617c478bd9Sstevel@tonic-gate 	xdrs->x_base = (caddr_t)m;
36627c478bd9Sstevel@tonic-gate 	xdrs->x_handy = 0;
36637c478bd9Sstevel@tonic-gate 	return (TRUE);
36647c478bd9Sstevel@tonic-gate }
36657c478bd9Sstevel@tonic-gate 
36667c478bd9Sstevel@tonic-gate bool_t
36677c478bd9Sstevel@tonic-gate xdr_READDIR4res(XDR *xdrs, READDIR4res *objp)
36687c478bd9Sstevel@tonic-gate {
36697c478bd9Sstevel@tonic-gate 	mblk_t *mp = objp->mblk;
36707c478bd9Sstevel@tonic-gate 	bool_t ret_val;
36717c478bd9Sstevel@tonic-gate 	uint_t flags = 0;
36727c478bd9Sstevel@tonic-gate 
36737c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
36747c478bd9Sstevel@tonic-gate 
36757c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
36767c478bd9Sstevel@tonic-gate 		return (FALSE);
36777c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
36787c478bd9Sstevel@tonic-gate 		return (TRUE);
36797c478bd9Sstevel@tonic-gate 	if (mp == NULL)
36807c478bd9Sstevel@tonic-gate 		return (FALSE);
36817c478bd9Sstevel@tonic-gate 
36827c478bd9Sstevel@tonic-gate 	if (xdrs->x_ops == &xdrmblk_ops) {
36837c478bd9Sstevel@tonic-gate 		if (xdrmblk_putmblk_rd(xdrs, mp)
36847c478bd9Sstevel@tonic-gate 		    == TRUE) {
36857c478bd9Sstevel@tonic-gate 			/* mblk successfully inserted into outgoing chain */
36867c478bd9Sstevel@tonic-gate 			objp->mblk = NULL;
36877c478bd9Sstevel@tonic-gate 			return (TRUE);
36887c478bd9Sstevel@tonic-gate 		}
36897c478bd9Sstevel@tonic-gate 	}
36907c478bd9Sstevel@tonic-gate 
36917c478bd9Sstevel@tonic-gate 	ASSERT(mp->b_cont == NULL);
36927c478bd9Sstevel@tonic-gate 
36937c478bd9Sstevel@tonic-gate 	/*
36940a701b1eSRobert Gordon 	 * If transport is RDMA, the pre-encoded m_blk needs to be moved
36957c478bd9Sstevel@tonic-gate 	 * without being chunked.
36960a701b1eSRobert Gordon 	 * Check if chunking is enabled for the xdr stream.
36970a701b1eSRobert Gordon 	 * If it is enabled, disable it temporarily for this op,
36980a701b1eSRobert Gordon 	 * then re-enable.
36997c478bd9Sstevel@tonic-gate 	 */
37000a701b1eSRobert Gordon 	XDR_CONTROL(xdrs, XDR_RDMA_GET_FLAGS, &flags);
37010a701b1eSRobert Gordon 
37020a701b1eSRobert Gordon 	if (!(flags & XDR_RDMA_CHUNK))
37037c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len));
37047c478bd9Sstevel@tonic-gate 
37050a701b1eSRobert Gordon 	flags &= ~XDR_RDMA_CHUNK;
37060a701b1eSRobert Gordon 
37070a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
37080a701b1eSRobert Gordon 
37097c478bd9Sstevel@tonic-gate 	ret_val = xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len);
37100a701b1eSRobert Gordon 
37110a701b1eSRobert Gordon 	flags |= XDR_RDMA_CHUNK;
37120a701b1eSRobert Gordon 
37130a701b1eSRobert Gordon 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
37140a701b1eSRobert Gordon 
37157c478bd9Sstevel@tonic-gate 	return (ret_val);
37167c478bd9Sstevel@tonic-gate }
37177c478bd9Sstevel@tonic-gate 
37187c478bd9Sstevel@tonic-gate static bool_t
37197c478bd9Sstevel@tonic-gate xdr_READLINK4res(XDR *xdrs, READLINK4res *objp)
37207c478bd9Sstevel@tonic-gate {
37217c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
37227c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
37237c478bd9Sstevel@tonic-gate 			return (FALSE);
37247c478bd9Sstevel@tonic-gate 		if (objp->status != NFS4_OK)
37257c478bd9Sstevel@tonic-gate 			return (TRUE);
3726bbe876c0SMarcel Telka 		return (xdr_bytes(xdrs, (char **)&objp->link.linktext4_val,
3727bbe876c0SMarcel Telka 		    (uint_t *)&objp->link.linktext4_len,
37287c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
37297c478bd9Sstevel@tonic-gate 	}
37307c478bd9Sstevel@tonic-gate 
37317c478bd9Sstevel@tonic-gate 	/*
37327c478bd9Sstevel@tonic-gate 	 * Optimized free case
37337c478bd9Sstevel@tonic-gate 	 */
37347c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
37357c478bd9Sstevel@tonic-gate 		return (TRUE);
3736bbe876c0SMarcel Telka 	if (objp->link.linktext4_val != NULL)
3737bbe876c0SMarcel Telka 		kmem_free(objp->link.linktext4_val, objp->link.linktext4_len);
37387c478bd9Sstevel@tonic-gate 	return (TRUE);
37397c478bd9Sstevel@tonic-gate }
37407c478bd9Sstevel@tonic-gate 
37417c478bd9Sstevel@tonic-gate static bool_t
37427c478bd9Sstevel@tonic-gate xdr_REMOVE4res(XDR *xdrs, REMOVE4res *objp)
37437c478bd9Sstevel@tonic-gate {
37447c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
37457c478bd9Sstevel@tonic-gate 		return (FALSE);
37467c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
37477c478bd9Sstevel@tonic-gate 		return (TRUE);
37487c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
37497c478bd9Sstevel@tonic-gate 		return (FALSE);
37507c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
37517c478bd9Sstevel@tonic-gate 		return (FALSE);
37527c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs,
37537c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->cinfo.after));
37547c478bd9Sstevel@tonic-gate }
37557c478bd9Sstevel@tonic-gate 
37567c478bd9Sstevel@tonic-gate static bool_t
37577c478bd9Sstevel@tonic-gate xdr_RENAME4res(XDR *xdrs, RENAME4res *objp)
37587c478bd9Sstevel@tonic-gate {
37597c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
37607c478bd9Sstevel@tonic-gate 		return (FALSE);
37617c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
37627c478bd9Sstevel@tonic-gate 		return (TRUE);
37637c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->source_cinfo.atomic))
37647c478bd9Sstevel@tonic-gate 		return (FALSE);
37657c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs,
37667c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->source_cinfo.before))
37677c478bd9Sstevel@tonic-gate 		return (FALSE);
37687c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs,
37697c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->source_cinfo.after))
37707c478bd9Sstevel@tonic-gate 		return (FALSE);
37717c478bd9Sstevel@tonic-gate 	if (!xdr_bool(xdrs, &objp->target_cinfo.atomic))
37727c478bd9Sstevel@tonic-gate 		return (FALSE);
37737c478bd9Sstevel@tonic-gate 	if (!xdr_u_longlong_t(xdrs,
37747c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->target_cinfo.before))
37757c478bd9Sstevel@tonic-gate 		return (FALSE);
37767c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs,
37777c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->target_cinfo.after));
37787c478bd9Sstevel@tonic-gate }
37797c478bd9Sstevel@tonic-gate 
37807c478bd9Sstevel@tonic-gate static bool_t
37817c478bd9Sstevel@tonic-gate xdr_secinfo4(XDR *xdrs, secinfo4 *objp)
37827c478bd9Sstevel@tonic-gate {
37837c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
37847c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->flavor))
37857c478bd9Sstevel@tonic-gate 			return (FALSE);
37867c478bd9Sstevel@tonic-gate 		if (objp->flavor != RPCSEC_GSS)
37877c478bd9Sstevel@tonic-gate 			return (TRUE);
37887c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs,
37897c478bd9Sstevel@tonic-gate 		    (char **)&objp->flavor_info.oid.sec_oid4_val,
37907c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->flavor_info.oid.sec_oid4_len,
37917c478bd9Sstevel@tonic-gate 		    NFS4_MAX_SECOID4))
37927c478bd9Sstevel@tonic-gate 			return (FALSE);
37937c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->flavor_info.qop))
37947c478bd9Sstevel@tonic-gate 			return (FALSE);
37957c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs, (int *)&objp->flavor_info.service));
37967c478bd9Sstevel@tonic-gate 	}
37977c478bd9Sstevel@tonic-gate 
37987c478bd9Sstevel@tonic-gate 	/*
37997c478bd9Sstevel@tonic-gate 	 * Optimized free path
38007c478bd9Sstevel@tonic-gate 	 */
38017c478bd9Sstevel@tonic-gate 	if (objp->flavor != RPCSEC_GSS)
38027c478bd9Sstevel@tonic-gate 		return (TRUE);
38037c478bd9Sstevel@tonic-gate 
38047c478bd9Sstevel@tonic-gate 	if (objp->flavor_info.oid.sec_oid4_val != NULL)
38057c478bd9Sstevel@tonic-gate 		kmem_free(objp->flavor_info.oid.sec_oid4_val,
38067c478bd9Sstevel@tonic-gate 		    objp->flavor_info.oid.sec_oid4_len);
38077c478bd9Sstevel@tonic-gate 	return (TRUE);
38087c478bd9Sstevel@tonic-gate }
38097c478bd9Sstevel@tonic-gate 
38107c478bd9Sstevel@tonic-gate static bool_t
38117c478bd9Sstevel@tonic-gate xdr_SETCLIENTID4args(XDR *xdrs, SETCLIENTID4args *objp)
38127c478bd9Sstevel@tonic-gate {
38137c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
38147c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
38157c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->client.verifier))
38167c478bd9Sstevel@tonic-gate 			return (FALSE);
38177c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->client.id_val,
38187c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->client.id_len, NFS4_OPAQUE_LIMIT))
38197c478bd9Sstevel@tonic-gate 			return (FALSE);
38207c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->callback.cb_program))
38217c478bd9Sstevel@tonic-gate 			return (FALSE);
38227c478bd9Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_netid,
38237c478bd9Sstevel@tonic-gate 		    NFS4_OPAQUE_LIMIT))
38247c478bd9Sstevel@tonic-gate 			return (FALSE);
38257c478bd9Sstevel@tonic-gate 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_addr,
38267c478bd9Sstevel@tonic-gate 		    NFS4_OPAQUE_LIMIT))
38277c478bd9Sstevel@tonic-gate 			return (FALSE);
38287c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->callback_ident));
38297c478bd9Sstevel@tonic-gate 	}
38307c478bd9Sstevel@tonic-gate 
38317c478bd9Sstevel@tonic-gate 	/*
38327c478bd9Sstevel@tonic-gate 	 * Optimized free case
38337c478bd9Sstevel@tonic-gate 	 */
38347c478bd9Sstevel@tonic-gate 	if (objp->client.id_val != NULL)
38357c478bd9Sstevel@tonic-gate 		kmem_free(objp->client.id_val, objp->client.id_len);
38367c478bd9Sstevel@tonic-gate 	(void) xdr_string(xdrs, &objp->callback.cb_location.r_netid,
38377c478bd9Sstevel@tonic-gate 	    NFS4_OPAQUE_LIMIT);
38387c478bd9Sstevel@tonic-gate 	return (xdr_string(xdrs, &objp->callback.cb_location.r_addr,
38397c478bd9Sstevel@tonic-gate 	    NFS4_OPAQUE_LIMIT));
38407c478bd9Sstevel@tonic-gate }
38417c478bd9Sstevel@tonic-gate 
38427c478bd9Sstevel@tonic-gate static bool_t
38437c478bd9Sstevel@tonic-gate xdr_SETCLIENTID4res(XDR *xdrs, SETCLIENTID4res *objp)
38447c478bd9Sstevel@tonic-gate {
38457c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
38467c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
38477c478bd9Sstevel@tonic-gate 			return (FALSE);
38487c478bd9Sstevel@tonic-gate 		switch (objp->status) {
38497c478bd9Sstevel@tonic-gate 		case NFS4_OK:
38507c478bd9Sstevel@tonic-gate 			if (!xdr_u_longlong_t(xdrs,
38517c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.resok4.
38527c478bd9Sstevel@tonic-gate 			    clientid))
38537c478bd9Sstevel@tonic-gate 				return (FALSE);
38547c478bd9Sstevel@tonic-gate 			return (xdr_u_longlong_t(xdrs,
38557c478bd9Sstevel@tonic-gate 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.
38567c478bd9Sstevel@tonic-gate 			    resok4.setclientid_confirm));
38577c478bd9Sstevel@tonic-gate 		case NFS4ERR_CLID_INUSE:
38587c478bd9Sstevel@tonic-gate 			if (!xdr_string(xdrs,
38597c478bd9Sstevel@tonic-gate 			    &objp->SETCLIENTID4res_u.client_using.
38607c478bd9Sstevel@tonic-gate 			    r_netid, NFS4_OPAQUE_LIMIT))
38617c478bd9Sstevel@tonic-gate 				return (FALSE);
38627c478bd9Sstevel@tonic-gate 			return (xdr_string(xdrs,
38637c478bd9Sstevel@tonic-gate 			    &objp->SETCLIENTID4res_u.client_using.
38647c478bd9Sstevel@tonic-gate 			    r_addr, NFS4_OPAQUE_LIMIT));
38657c478bd9Sstevel@tonic-gate 		}
38667c478bd9Sstevel@tonic-gate 		return (TRUE);
38677c478bd9Sstevel@tonic-gate 	}
38687c478bd9Sstevel@tonic-gate 
38697c478bd9Sstevel@tonic-gate 	/*
38707c478bd9Sstevel@tonic-gate 	 * Optimized free case
38717c478bd9Sstevel@tonic-gate 	 */
38727c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4ERR_CLID_INUSE)
38737c478bd9Sstevel@tonic-gate 		return (TRUE);
38747c478bd9Sstevel@tonic-gate 
38757c478bd9Sstevel@tonic-gate 	if (!xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_netid,
38767c478bd9Sstevel@tonic-gate 	    NFS4_OPAQUE_LIMIT))
38777c478bd9Sstevel@tonic-gate 		return (FALSE);
38787c478bd9Sstevel@tonic-gate 	return (xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_addr,
38797c478bd9Sstevel@tonic-gate 	    NFS4_OPAQUE_LIMIT));
38807c478bd9Sstevel@tonic-gate }
38817c478bd9Sstevel@tonic-gate 
38827c478bd9Sstevel@tonic-gate static bool_t
38837c478bd9Sstevel@tonic-gate xdr_WRITE4args(XDR *xdrs, WRITE4args *objp)
38847c478bd9Sstevel@tonic-gate {
38857c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
38867c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
38877c478bd9Sstevel@tonic-gate 			return (FALSE);
3888bbe876c0SMarcel Telka 		if (!xdr_opaque(xdrs, objp->stateid.other, NFS4_OTHER_SIZE))
38897c478bd9Sstevel@tonic-gate 			return (FALSE);
38907c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
38917c478bd9Sstevel@tonic-gate 			return (FALSE);
38927c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int *)&objp->stable))
38937c478bd9Sstevel@tonic-gate 			return (FALSE);
38947c478bd9Sstevel@tonic-gate 		if (xdrs->x_op == XDR_DECODE) {
38957c478bd9Sstevel@tonic-gate 			if (xdrs->x_ops == &xdrmblk_ops) {
38967c478bd9Sstevel@tonic-gate 				objp->data_val = NULL;
38977c478bd9Sstevel@tonic-gate 				return (xdrmblk_getmblk(xdrs, &objp->mblk,
38987c478bd9Sstevel@tonic-gate 				    &objp->data_len));
38997c478bd9Sstevel@tonic-gate 			}
39007c478bd9Sstevel@tonic-gate 			objp->mblk = NULL;
39010a701b1eSRobert Gordon 			if (xdrs->x_ops == &xdrrdmablk_ops) {
39020a701b1eSRobert Gordon 				int retval;
39030a701b1eSRobert Gordon 				retval = xdrrdma_getrdmablk(xdrs,
39040a701b1eSRobert Gordon 				    &objp->rlist,
39050a701b1eSRobert Gordon 				    &objp->data_len,
39060a701b1eSRobert Gordon 				    &objp->conn, NFS4_DATA_LIMIT);
39070a701b1eSRobert Gordon 				if (retval == FALSE)
39080a701b1eSRobert Gordon 					return (FALSE);
3909f837ee4aSSiddheshwar Mahesh 				return (xdrrdma_read_from_client(objp->rlist,
39100a701b1eSRobert Gordon 				    &objp->conn, objp->data_len));
39117c478bd9Sstevel@tonic-gate 			}
39120a701b1eSRobert Gordon 		}
39130a701b1eSRobert Gordon 		/* Else fall thru for the xdr_bytes(). */
39147c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->data_val,
39157c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->data_len, NFS4_DATA_LIMIT));
39167c478bd9Sstevel@tonic-gate 	}
39170a701b1eSRobert Gordon 	if (objp->rlist != NULL) {
39180a701b1eSRobert Gordon 		(void) xdrrdma_free_clist(objp->conn, objp->rlist);
39190a701b1eSRobert Gordon 		objp->rlist = NULL;
39200a701b1eSRobert Gordon 		objp->data_val = NULL;
39210a701b1eSRobert Gordon 
39220a701b1eSRobert Gordon 		return (TRUE);
39230a701b1eSRobert Gordon 	}
39247c478bd9Sstevel@tonic-gate 
39257c478bd9Sstevel@tonic-gate 	/*
39267c478bd9Sstevel@tonic-gate 	 * Optimized free case
39277c478bd9Sstevel@tonic-gate 	 */
39287c478bd9Sstevel@tonic-gate 	if (objp->data_val != NULL)
39297c478bd9Sstevel@tonic-gate 		kmem_free(objp->data_val, objp->data_len);
39307c478bd9Sstevel@tonic-gate 	return (TRUE);
39317c478bd9Sstevel@tonic-gate }
39327c478bd9Sstevel@tonic-gate 
39337c478bd9Sstevel@tonic-gate static bool_t
39347c478bd9Sstevel@tonic-gate xdr_WRITE4res(XDR *xdrs, WRITE4res *objp)
39357c478bd9Sstevel@tonic-gate {
39367c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
39377c478bd9Sstevel@tonic-gate 		return (FALSE);
39387c478bd9Sstevel@tonic-gate 	if (objp->status != NFS4_OK)
39397c478bd9Sstevel@tonic-gate 		return (TRUE);
39407c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->count))
39417c478bd9Sstevel@tonic-gate 		return (FALSE);
39427c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->committed))
39437c478bd9Sstevel@tonic-gate 		return (FALSE);
39447c478bd9Sstevel@tonic-gate 	return (xdr_u_longlong_t(xdrs,
39457c478bd9Sstevel@tonic-gate 	    (u_longlong_t *)&objp->writeverf));
39467c478bd9Sstevel@tonic-gate }
39477c478bd9Sstevel@tonic-gate 
39487c478bd9Sstevel@tonic-gate static bool_t
39497c46fb7fSek110237 xdr_snfs_argop4_free(XDR *xdrs, nfs_argop4 **arrayp, int len)
39507c478bd9Sstevel@tonic-gate {
39517c478bd9Sstevel@tonic-gate 	int i;
39527c478bd9Sstevel@tonic-gate 	nfs_argop4 *array = *arrayp;
39537c478bd9Sstevel@tonic-gate 
39547c478bd9Sstevel@tonic-gate 	/*
39557c478bd9Sstevel@tonic-gate 	 * Optimized XDR_FREE only args array
39567c478bd9Sstevel@tonic-gate 	 */
39577c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_FREE);
39587c478bd9Sstevel@tonic-gate 
39597c478bd9Sstevel@tonic-gate 	/*
39607c478bd9Sstevel@tonic-gate 	 * Nothing to do?
39617c478bd9Sstevel@tonic-gate 	 */
39627c478bd9Sstevel@tonic-gate 	if (array == NULL)
39637c478bd9Sstevel@tonic-gate 		return (TRUE);
39647c478bd9Sstevel@tonic-gate 
39657c478bd9Sstevel@tonic-gate 	for (i = 0; i < len; i++) {
39667c478bd9Sstevel@tonic-gate 		/*
39677c478bd9Sstevel@tonic-gate 		 * These should be ordered by frequency of use
39687c478bd9Sstevel@tonic-gate 		 */
39697c478bd9Sstevel@tonic-gate 		switch (array[i].argop) {
3970297b4d80SVitaliy Gusev 		case OP_PUTFH: {
3971297b4d80SVitaliy Gusev 			nfs_fh4 *objp = &array[i].nfs_argop4_u.opputfh.object;
3972297b4d80SVitaliy Gusev 
3973297b4d80SVitaliy Gusev 			if (objp->nfs_fh4_val != NULL) {
3974297b4d80SVitaliy Gusev 				kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
39757c478bd9Sstevel@tonic-gate 			}
39767c478bd9Sstevel@tonic-gate 			continue;
3977297b4d80SVitaliy Gusev 		}
39787c478bd9Sstevel@tonic-gate 		case OP_GETATTR:
39797c478bd9Sstevel@tonic-gate 		case OP_GETFH:
39807c478bd9Sstevel@tonic-gate 			continue;
39817c478bd9Sstevel@tonic-gate 		case OP_LOOKUP:
39827c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oplookup.objname.
39837c478bd9Sstevel@tonic-gate 			    utf8string_val != NULL) {
39847c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oplookup.
39857c478bd9Sstevel@tonic-gate 				    objname.utf8string_val,
39867c478bd9Sstevel@tonic-gate 				    array[i].nfs_argop4_u.oplookup.
39877c478bd9Sstevel@tonic-gate 				    objname.utf8string_len);
39887c478bd9Sstevel@tonic-gate 			}
39897c478bd9Sstevel@tonic-gate 			continue;
39907c478bd9Sstevel@tonic-gate 		case OP_OPEN:
39917c478bd9Sstevel@tonic-gate 			(void) xdr_OPEN4args(xdrs,
39927c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opopen);
39937c478bd9Sstevel@tonic-gate 			continue;
39947c478bd9Sstevel@tonic-gate 		case OP_CLOSE:
39957c478bd9Sstevel@tonic-gate 		case OP_ACCESS:
39967c478bd9Sstevel@tonic-gate 		case OP_READ:
39977c478bd9Sstevel@tonic-gate 			continue;
39987c478bd9Sstevel@tonic-gate 		case OP_WRITE:
39997c478bd9Sstevel@tonic-gate 			(void) xdr_WRITE4args(xdrs,
40007c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opwrite);
40017c478bd9Sstevel@tonic-gate 			continue;
40027c478bd9Sstevel@tonic-gate 		case OP_DELEGRETURN:
40037c478bd9Sstevel@tonic-gate 		case OP_LOOKUPP:
40047c478bd9Sstevel@tonic-gate 		case OP_READDIR:
40057c478bd9Sstevel@tonic-gate 			continue;
40067c478bd9Sstevel@tonic-gate 		case OP_REMOVE:
40077c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.opremove.target.
40087c478bd9Sstevel@tonic-gate 			    utf8string_val != NULL) {
40097c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.opremove.target.
40107c478bd9Sstevel@tonic-gate 				    utf8string_val,
40117c478bd9Sstevel@tonic-gate 				    array[i].nfs_argop4_u.opremove.target.
40127c478bd9Sstevel@tonic-gate 				    utf8string_len);
40137c478bd9Sstevel@tonic-gate 			}
40147c478bd9Sstevel@tonic-gate 			continue;
40157c478bd9Sstevel@tonic-gate 		case OP_COMMIT:
40167c478bd9Sstevel@tonic-gate 			continue;
40177c478bd9Sstevel@tonic-gate 		case OP_CREATE:
40187c478bd9Sstevel@tonic-gate 			(void) xdr_CREATE4args(xdrs,
40197c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opcreate);
40207c478bd9Sstevel@tonic-gate 			continue;
40217c478bd9Sstevel@tonic-gate 		case OP_DELEGPURGE:
40227c478bd9Sstevel@tonic-gate 			continue;
40237c478bd9Sstevel@tonic-gate 		case OP_LINK:
40247c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oplink.newname.
40257c478bd9Sstevel@tonic-gate 			    utf8string_val != NULL) {
40267c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oplink.newname.
40277c478bd9Sstevel@tonic-gate 				    utf8string_val,
40287c478bd9Sstevel@tonic-gate 				    array[i].nfs_argop4_u.oplink.newname.
40297c478bd9Sstevel@tonic-gate 				    utf8string_len);
40307c478bd9Sstevel@tonic-gate 			}
40317c478bd9Sstevel@tonic-gate 			continue;
40327c478bd9Sstevel@tonic-gate 		case OP_LOCK:
40337c478bd9Sstevel@tonic-gate 			(void) xdr_LOCK4args(xdrs,
40347c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.oplock);
40357c478bd9Sstevel@tonic-gate 			continue;
40367c478bd9Sstevel@tonic-gate 		case OP_LOCKT:
40377c478bd9Sstevel@tonic-gate 			(void) xdr_LOCKT4args(xdrs,
40387c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.oplockt);
40397c478bd9Sstevel@tonic-gate 			continue;
40407c478bd9Sstevel@tonic-gate 		case OP_LOCKU:
40417c478bd9Sstevel@tonic-gate 			continue;
40427c478bd9Sstevel@tonic-gate 		case OP_NVERIFY:
40437c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
40447c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opnverify.obj_attributes);
40457c478bd9Sstevel@tonic-gate 			continue;
40467c478bd9Sstevel@tonic-gate 		case OP_OPENATTR:
40477c478bd9Sstevel@tonic-gate 		case OP_OPEN_CONFIRM:
40487c478bd9Sstevel@tonic-gate 		case OP_OPEN_DOWNGRADE:
40497c478bd9Sstevel@tonic-gate 		case OP_PUTPUBFH:
40507c478bd9Sstevel@tonic-gate 		case OP_PUTROOTFH:
40517c478bd9Sstevel@tonic-gate 		case OP_READLINK:
40527c478bd9Sstevel@tonic-gate 			continue;
40537c478bd9Sstevel@tonic-gate 		case OP_RENAME:
40547c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oprename.oldname.
40557c478bd9Sstevel@tonic-gate 			    utf8string_val != NULL) {
40567c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oprename.
40577c478bd9Sstevel@tonic-gate 				    oldname.utf8string_val,
40587c478bd9Sstevel@tonic-gate 				    array[i].nfs_argop4_u.oprename.
40597c478bd9Sstevel@tonic-gate 				    oldname.utf8string_len);
40607c478bd9Sstevel@tonic-gate 			}
40617c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oprename.newname.
40627c478bd9Sstevel@tonic-gate 			    utf8string_val != NULL) {
40637c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.oprename.
40647c478bd9Sstevel@tonic-gate 				    newname.utf8string_val,
40657c478bd9Sstevel@tonic-gate 				    array[i].nfs_argop4_u.oprename.
40667c478bd9Sstevel@tonic-gate 				    newname.utf8string_len);
40677c478bd9Sstevel@tonic-gate 			}
40687c478bd9Sstevel@tonic-gate 			continue;
40697c478bd9Sstevel@tonic-gate 		case OP_RENEW:
40707c478bd9Sstevel@tonic-gate 		case OP_RESTOREFH:
40717c478bd9Sstevel@tonic-gate 		case OP_SAVEFH:
40727c478bd9Sstevel@tonic-gate 			continue;
40737c478bd9Sstevel@tonic-gate 		case OP_SECINFO:
40747c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.opsecinfo.name.
40757c478bd9Sstevel@tonic-gate 			    utf8string_val != NULL) {
40767c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.opsecinfo.name.
40777c478bd9Sstevel@tonic-gate 				    utf8string_val,
40787c478bd9Sstevel@tonic-gate 				    array[i].nfs_argop4_u.opsecinfo.name.
40797c478bd9Sstevel@tonic-gate 				    utf8string_len);
40807c478bd9Sstevel@tonic-gate 			}
40817c478bd9Sstevel@tonic-gate 			continue;
40827c478bd9Sstevel@tonic-gate 		case OP_SETATTR:
40837c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
40847c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opsetattr.obj_attributes);
40857c478bd9Sstevel@tonic-gate 			continue;
40867c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID:
40877c478bd9Sstevel@tonic-gate 			(void) xdr_SETCLIENTID4args(xdrs,
40887c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opsetclientid);
40897c478bd9Sstevel@tonic-gate 			continue;
40907c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID_CONFIRM:
40917c478bd9Sstevel@tonic-gate 			continue;
40927c478bd9Sstevel@tonic-gate 		case OP_VERIFY:
40937c478bd9Sstevel@tonic-gate 			(void) xdr_fattr4(xdrs,
40947c478bd9Sstevel@tonic-gate 			    &array[i].nfs_argop4_u.opverify.obj_attributes);
40957c478bd9Sstevel@tonic-gate 			continue;
40967c478bd9Sstevel@tonic-gate 		case OP_RELEASE_LOCKOWNER:
40977c478bd9Sstevel@tonic-gate 			if (array[i].nfs_argop4_u.oprelease_lockowner.
40987c478bd9Sstevel@tonic-gate 			    lock_owner.owner_val != NULL) {
40997c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_argop4_u.
41007c478bd9Sstevel@tonic-gate 				    oprelease_lockowner.lock_owner.owner_val,
41017c478bd9Sstevel@tonic-gate 				    array[i].nfs_argop4_u.
41027c478bd9Sstevel@tonic-gate 				    oprelease_lockowner.lock_owner.owner_len);
41037c478bd9Sstevel@tonic-gate 			}
41047c478bd9Sstevel@tonic-gate 			continue;
41057c478bd9Sstevel@tonic-gate 		case OP_ILLEGAL:
41067c478bd9Sstevel@tonic-gate 			continue;
41077c478bd9Sstevel@tonic-gate 		default:
41087c478bd9Sstevel@tonic-gate 			/*
41097c478bd9Sstevel@tonic-gate 			 * An invalid op is a coding error, it should never
41107c478bd9Sstevel@tonic-gate 			 * have been decoded.
41117c478bd9Sstevel@tonic-gate 			 * Don't error because the caller cannot finish
41127c478bd9Sstevel@tonic-gate 			 * freeing the residual memory of the array.
41137c478bd9Sstevel@tonic-gate 			 */
41147c478bd9Sstevel@tonic-gate 			continue;
41157c478bd9Sstevel@tonic-gate 		}
41167c478bd9Sstevel@tonic-gate 	}
41177c478bd9Sstevel@tonic-gate 
41187c478bd9Sstevel@tonic-gate 	kmem_free(*arrayp, len * sizeof (nfs_argop4));
41197c478bd9Sstevel@tonic-gate 	*arrayp = NULL;
41207c478bd9Sstevel@tonic-gate 	return (TRUE);
41217c478bd9Sstevel@tonic-gate }
41227c478bd9Sstevel@tonic-gate 
41237c478bd9Sstevel@tonic-gate static bool_t
41247c478bd9Sstevel@tonic-gate xdr_nfs_argop4(XDR *xdrs, nfs_argop4 *objp)
41257c478bd9Sstevel@tonic-gate {
41260a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
41270a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
41280a701b1eSRobert Gordon 
41297c478bd9Sstevel@tonic-gate 	/*
41307c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
41317c478bd9Sstevel@tonic-gate 	 */
41327c478bd9Sstevel@tonic-gate 	switch (objp->argop) {
41337c478bd9Sstevel@tonic-gate 	case OP_PUTFH:
41347c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
41357c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_val,
41367c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_len,
41377c478bd9Sstevel@tonic-gate 		    NFS4_FHSIZE));
41387c478bd9Sstevel@tonic-gate 	case OP_GETATTR:
41398ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		/*
41408ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 * ACLs can become relatively large ( > 8K) and the default
41418ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 * 8K reply chunk of RDMA may not suffice. Check for
41428ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 * get ACL bit and if it's RDMA, add a chunk equal the size
41438ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 * of the transfer size to the reply chunk list.
41448ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		 */
41458ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
41468ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		    (xdrs->x_op == XDR_ENCODE) &&
41478ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		    (objp->nfs_argop4_u.opgetattr.attr_request &
41488ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		    FATTR4_ACL_MASK)) {
41498ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			rci.rci_type = RCI_REPLY_CHUNK;
41508ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			rci.rci_len = objp->nfs_argop4_u.opgetattr.mi->mi_tsize;
41518ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
41528ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 
41538ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			DTRACE_PROBE1(xdr__i__argop4__getattr, int,
41548ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 			    rci.rci_len);
41558ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 		}
41567c478bd9Sstevel@tonic-gate 		return (xdr_bitmap4(xdrs,
41577c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opgetattr.attr_request));
41587c478bd9Sstevel@tonic-gate 	case OP_GETFH:
41597c478bd9Sstevel@tonic-gate 		return (TRUE);
41607c478bd9Sstevel@tonic-gate 	case OP_LOOKUP:
41617c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oplookup.
41627c478bd9Sstevel@tonic-gate 		    objname.utf8string_val,
41637c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.oplookup.
41647c478bd9Sstevel@tonic-gate 		    objname.utf8string_len,
41657c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
41667c478bd9Sstevel@tonic-gate 	case OP_OPEN:
41677c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4args(xdrs, &objp->nfs_argop4_u.opopen));
41687c478bd9Sstevel@tonic-gate 	case OP_CLOSE:
41697c478bd9Sstevel@tonic-gate 		return (xdr_CLOSE4args(xdrs, &objp->nfs_argop4_u.opclose));
41707c478bd9Sstevel@tonic-gate 	case OP_ACCESS:
41717c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs,
41727c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opaccess.access));
41737c478bd9Sstevel@tonic-gate 	case OP_READ:
41747c478bd9Sstevel@tonic-gate 		return (xdr_READ4args(xdrs, &objp->nfs_argop4_u.opread));
41757c478bd9Sstevel@tonic-gate 	case OP_WRITE:
41767c478bd9Sstevel@tonic-gate 		return (xdr_WRITE4args(xdrs, &objp->nfs_argop4_u.opwrite));
41777c478bd9Sstevel@tonic-gate 	case OP_DELEGRETURN:
41787c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs,
41797c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opdelegreturn.deleg_stateid.seqid))
41807c478bd9Sstevel@tonic-gate 			return (FALSE);
41817c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs,
4182bbe876c0SMarcel Telka 		    objp->nfs_argop4_u.opdelegreturn.deleg_stateid.other,
4183bbe876c0SMarcel Telka 		    NFS4_OTHER_SIZE));
41847c478bd9Sstevel@tonic-gate 	case OP_LOOKUPP:
41857c478bd9Sstevel@tonic-gate 		return (TRUE);
41867c478bd9Sstevel@tonic-gate 	case OP_READDIR:
41877c478bd9Sstevel@tonic-gate 		return (xdr_READDIR4args(xdrs, &objp->nfs_argop4_u.opreaddir));
41887c478bd9Sstevel@tonic-gate 	case OP_REMOVE:
41897c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.opremove.
41907c478bd9Sstevel@tonic-gate 		    target.utf8string_val,
41917c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.opremove.
41927c478bd9Sstevel@tonic-gate 		    target.utf8string_len,
41937c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
41947c478bd9Sstevel@tonic-gate 	case OP_COMMIT:
41957c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
41967c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_argop4_u.opcommit.offset))
41977c478bd9Sstevel@tonic-gate 			return (FALSE);
41987c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opcommit.count));
41997c478bd9Sstevel@tonic-gate 	case OP_CREATE:
42007c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4args(xdrs, &objp->nfs_argop4_u.opcreate));
42017c478bd9Sstevel@tonic-gate 	case OP_DELEGPURGE:
42027c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
42037c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_argop4_u.opdelegpurge.clientid));
42047c478bd9Sstevel@tonic-gate 	case OP_LINK:
42057c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
42067c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.oplink.newname.utf8string_val,
42077c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.oplink.newname.utf8string_len,
42087c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
42097c478bd9Sstevel@tonic-gate 	case OP_LOCK:
42107c478bd9Sstevel@tonic-gate 		return (xdr_LOCK4args(xdrs, &objp->nfs_argop4_u.oplock));
42117c478bd9Sstevel@tonic-gate 	case OP_LOCKT:
42127c478bd9Sstevel@tonic-gate 		return (xdr_LOCKT4args(xdrs, &objp->nfs_argop4_u.oplockt));
42137c478bd9Sstevel@tonic-gate 	case OP_LOCKU:
42147c478bd9Sstevel@tonic-gate 		return (xdr_LOCKU4args(xdrs, &objp->nfs_argop4_u.oplocku));
42157c478bd9Sstevel@tonic-gate 	case OP_NVERIFY:
42167c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
42177c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opnverify.obj_attributes));
42187c478bd9Sstevel@tonic-gate 	case OP_OPENATTR:
42197c478bd9Sstevel@tonic-gate 		return (xdr_bool(xdrs,
42207c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opopenattr.createdir));
42217c478bd9Sstevel@tonic-gate 	case OP_OPEN_CONFIRM:
42227c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
42237c478bd9Sstevel@tonic-gate 		    open_stateid.seqid))
42247c478bd9Sstevel@tonic-gate 			return (FALSE);
42257c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opopen_confirm.
4226bbe876c0SMarcel Telka 		    open_stateid.other, NFS4_OTHER_SIZE))
42277c478bd9Sstevel@tonic-gate 			return (FALSE);
42287c478bd9Sstevel@tonic-gate 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
42297c478bd9Sstevel@tonic-gate 		    seqid));
42307c478bd9Sstevel@tonic-gate 	case OP_OPEN_DOWNGRADE:
42317c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_DOWNGRADE4args(xdrs,
42327c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opopen_downgrade));
42337c478bd9Sstevel@tonic-gate 	case OP_PUTPUBFH:
42347c478bd9Sstevel@tonic-gate 		return (TRUE);
42357c478bd9Sstevel@tonic-gate 	case OP_PUTROOTFH:
42367c478bd9Sstevel@tonic-gate 		return (TRUE);
42377c478bd9Sstevel@tonic-gate 	case OP_READLINK:
42380a701b1eSRobert Gordon 		if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
42390a701b1eSRobert Gordon 		    xdrs->x_op == XDR_ENCODE) {
42400a701b1eSRobert Gordon 			rci.rci_type = RCI_REPLY_CHUNK;
42410a701b1eSRobert Gordon 			rci.rci_len = MAXPATHLEN;
42420a701b1eSRobert Gordon 			XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
42430a701b1eSRobert Gordon 		}
42447c478bd9Sstevel@tonic-gate 		return (TRUE);
42457c478bd9Sstevel@tonic-gate 	case OP_RENAME:
42467c478bd9Sstevel@tonic-gate 		if (!xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
42477c478bd9Sstevel@tonic-gate 		    oldname.utf8string_val,
42487c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.oprename.
42497c478bd9Sstevel@tonic-gate 		    oldname.utf8string_len,
42507c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING))
42517c478bd9Sstevel@tonic-gate 			return (FALSE);
42527c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
42537c478bd9Sstevel@tonic-gate 		    newname.utf8string_val,
42547c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.oprename.
42557c478bd9Sstevel@tonic-gate 		    newname.utf8string_len,
42567c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
42577c478bd9Sstevel@tonic-gate 	case OP_RENEW:
42587c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
42597c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_argop4_u.oprenew.clientid));
42607c478bd9Sstevel@tonic-gate 	case OP_RESTOREFH:
42617c478bd9Sstevel@tonic-gate 		return (TRUE);
42627c478bd9Sstevel@tonic-gate 	case OP_SAVEFH:
42637c478bd9Sstevel@tonic-gate 		return (TRUE);
42647c478bd9Sstevel@tonic-gate 	case OP_SECINFO:
42657c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
42667c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.opsecinfo.name.utf8string_val,
42677c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.opsecinfo.name.utf8string_len,
42687c478bd9Sstevel@tonic-gate 		    NFS4_MAX_UTF8STRING));
42697c478bd9Sstevel@tonic-gate 	case OP_SETATTR:
42707c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opsetattr.
42717c478bd9Sstevel@tonic-gate 		    stateid.seqid))
42727c478bd9Sstevel@tonic-gate 			return (FALSE);
42737c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opsetattr.
4274bbe876c0SMarcel Telka 		    stateid.other, NFS4_OTHER_SIZE))
42757c478bd9Sstevel@tonic-gate 			return (FALSE);
42767c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs, &objp->nfs_argop4_u.opsetattr.
42777c478bd9Sstevel@tonic-gate 		    obj_attributes));
42787c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID:
42797c478bd9Sstevel@tonic-gate 		return (xdr_SETCLIENTID4args(xdrs,
42807c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opsetclientid));
42817c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID_CONFIRM:
42827c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->nfs_argop4_u.
42837c478bd9Sstevel@tonic-gate 		    opsetclientid_confirm.clientid))
42847c478bd9Sstevel@tonic-gate 			return (FALSE);
42857c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
42867c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_argop4_u.
42877c478bd9Sstevel@tonic-gate 		    opsetclientid_confirm.setclientid_confirm));
42887c478bd9Sstevel@tonic-gate 	case OP_VERIFY:
42897c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
42907c478bd9Sstevel@tonic-gate 		    &objp->nfs_argop4_u.opverify.obj_attributes));
42917c478bd9Sstevel@tonic-gate 	case OP_RELEASE_LOCKOWNER:
42927c478bd9Sstevel@tonic-gate 		if (!xdr_u_longlong_t(xdrs,
42937c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_argop4_u.
42947c478bd9Sstevel@tonic-gate 		    oprelease_lockowner.lock_owner.clientid))
42957c478bd9Sstevel@tonic-gate 			return (FALSE);
42967c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
42977c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_argop4_u.oprelease_lockowner.
42987c478bd9Sstevel@tonic-gate 		    lock_owner.owner_val,
42997c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_argop4_u.oprelease_lockowner.
43007c478bd9Sstevel@tonic-gate 		    lock_owner.owner_len, NFS4_OPAQUE_LIMIT));
43017c478bd9Sstevel@tonic-gate 	case OP_ILLEGAL:
43027c478bd9Sstevel@tonic-gate 		return (TRUE);
43037c478bd9Sstevel@tonic-gate 	}
43047c478bd9Sstevel@tonic-gate 	return (FALSE);
43057c478bd9Sstevel@tonic-gate }
43067c478bd9Sstevel@tonic-gate 
43077c46fb7fSek110237 static bool_t
43087c46fb7fSek110237 xdr_cnfs_argop4_wrap(XDR *xdrs, nfs_argop4 *objp)
43097c46fb7fSek110237 {
43107c46fb7fSek110237 	if (!xdr_int(xdrs, (int *)&objp->argop))
43117c46fb7fSek110237 		return (FALSE);
43127c46fb7fSek110237 
43137c46fb7fSek110237 	return (xdr_nfs_argop4(xdrs, objp));
43147c46fb7fSek110237 }
43157c46fb7fSek110237 
43167c46fb7fSek110237 static bool_t
43177c46fb7fSek110237 xdr_snfs_argop4(XDR *xdrs, nfs_argop4 *objp)
43187c46fb7fSek110237 {
43197c46fb7fSek110237 	if (!xdr_int(xdrs, (int *)&objp->argop))
43207c46fb7fSek110237 		return (FALSE);
43217c46fb7fSek110237 
43227c46fb7fSek110237 	switch (objp->argop) {
43237c46fb7fSek110237 	case OP_PUTFH:
4324*c93d332cSDan McDonald 		return (xdr_decode_nfs_fh4(xdrs,
4325*c93d332cSDan McDonald 		    &objp->nfs_argop4_u.opputfh.object));
43267c46fb7fSek110237 	default:
4327*c93d332cSDan McDonald 		return (xdr_nfs_argop4(xdrs, objp));
43287c46fb7fSek110237 	}
43297c46fb7fSek110237 }
43307c46fb7fSek110237 
43317c478bd9Sstevel@tonic-gate /*
43327c478bd9Sstevel@tonic-gate  * Client side encode only arg op processing
43337c478bd9Sstevel@tonic-gate  */
43347c478bd9Sstevel@tonic-gate static bool_t
43357c478bd9Sstevel@tonic-gate xdr_cnfs_argop4(XDR *xdrs, nfs_argop4 *objp)
43367c478bd9Sstevel@tonic-gate {
43377c478bd9Sstevel@tonic-gate 	int len;
43387c478bd9Sstevel@tonic-gate 	int op;
43397c478bd9Sstevel@tonic-gate 	nfs4_sharedfh_t *sfh;
43407c478bd9Sstevel@tonic-gate 	mntinfo4_t *mi;
43417c478bd9Sstevel@tonic-gate 	rpc_inline_t *ptr;
43427c478bd9Sstevel@tonic-gate 
43437c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_ENCODE);
43447c478bd9Sstevel@tonic-gate 
43457c478bd9Sstevel@tonic-gate 	/*
43467c478bd9Sstevel@tonic-gate 	 * Special case the private pseudo ops
43477c478bd9Sstevel@tonic-gate 	 */
43487c478bd9Sstevel@tonic-gate 	if (!(objp->argop & SUNW_PRIVATE_OP))
43497c46fb7fSek110237 		return (xdr_cnfs_argop4_wrap(xdrs, objp));
43507c478bd9Sstevel@tonic-gate 
43517c478bd9Sstevel@tonic-gate 	/*
43527c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
43537c478bd9Sstevel@tonic-gate 	 */
43547c478bd9Sstevel@tonic-gate 	switch (objp->argop) {
43557c478bd9Sstevel@tonic-gate 	case OP_CPUTFH:
43567c478bd9Sstevel@tonic-gate 		/*
43577c478bd9Sstevel@tonic-gate 		 * We are passed in the file handle as a nfs4_sharedfh_t *
43587c478bd9Sstevel@tonic-gate 		 * We need to acquire the correct locks so we can copy it out.
43597c478bd9Sstevel@tonic-gate 		 */
43607c478bd9Sstevel@tonic-gate 		sfh = (nfs4_sharedfh_t *)objp->nfs_argop4_u.opcputfh.sfh;
43617c478bd9Sstevel@tonic-gate 		mi = sfh->sfh_mi;
43627c478bd9Sstevel@tonic-gate 		(void) nfs_rw_enter_sig(&mi->mi_fh_lock, RW_READER, 0);
43637c478bd9Sstevel@tonic-gate 
43647c478bd9Sstevel@tonic-gate 		len = sfh->sfh_fh.nfs_fh4_len;
43657c478bd9Sstevel@tonic-gate 		ASSERT(len <= NFS4_FHSIZE);
43667c478bd9Sstevel@tonic-gate 
43677c478bd9Sstevel@tonic-gate 		/*
43687c478bd9Sstevel@tonic-gate 		 * First try and inline the copy
43697c478bd9Sstevel@tonic-gate 		 * Must first be a multiple of BYTES_PER_XDR_UNIT
43707c478bd9Sstevel@tonic-gate 		 */
43717c478bd9Sstevel@tonic-gate 		if (!(len % BYTES_PER_XDR_UNIT) &&
43727c478bd9Sstevel@tonic-gate 		    (ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + len)) !=
43737c478bd9Sstevel@tonic-gate 		    NULL) {
43747c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, OP_PUTFH);
43757c478bd9Sstevel@tonic-gate 			IXDR_PUT_U_INT32(ptr, len);
43767c478bd9Sstevel@tonic-gate 			bcopy(sfh->sfh_fh.nfs_fh4_val, ptr, len);
43777c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
43787c478bd9Sstevel@tonic-gate 			return (TRUE);
43797c478bd9Sstevel@tonic-gate 		}
43807c478bd9Sstevel@tonic-gate 
43817c478bd9Sstevel@tonic-gate 		op = OP_PUTFH;
43827c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &op)) {
43837c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
43847c478bd9Sstevel@tonic-gate 			return (FALSE);
43857c478bd9Sstevel@tonic-gate 		}
43867c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len)) {
43877c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
43887c478bd9Sstevel@tonic-gate 			return (FALSE);
43897c478bd9Sstevel@tonic-gate 		}
43907c478bd9Sstevel@tonic-gate 		if (!(len % BYTES_PER_XDR_UNIT)) {
43917c478bd9Sstevel@tonic-gate 			if (XDR_PUTBYTES(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
43927c478bd9Sstevel@tonic-gate 				nfs_rw_exit(&mi->mi_fh_lock);
43937c478bd9Sstevel@tonic-gate 				return (TRUE);
43947c478bd9Sstevel@tonic-gate 			}
43957c478bd9Sstevel@tonic-gate 		} else if (xdr_opaque(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
43967c478bd9Sstevel@tonic-gate 			nfs_rw_exit(&mi->mi_fh_lock);
43977c478bd9Sstevel@tonic-gate 			return (TRUE);
43987c478bd9Sstevel@tonic-gate 		}
43997c478bd9Sstevel@tonic-gate 		nfs_rw_exit(&mi->mi_fh_lock);
44007c478bd9Sstevel@tonic-gate 		return (FALSE);
44017c478bd9Sstevel@tonic-gate 	case OP_CLOOKUP:
44027c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opclookup.cname);
44037c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44047c478bd9Sstevel@tonic-gate 			return (FALSE);
44057c478bd9Sstevel@tonic-gate 		op = OP_LOOKUP;
44067c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
44077c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
44087c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
44097c478bd9Sstevel@tonic-gate 				    objp->nfs_argop4_u.opclookup.cname,
44107c478bd9Sstevel@tonic-gate 				    len));
44117c478bd9Sstevel@tonic-gate 			}
44127c478bd9Sstevel@tonic-gate 		}
44137c478bd9Sstevel@tonic-gate 		return (FALSE);
44147c478bd9Sstevel@tonic-gate 	case OP_COPEN:
44157c478bd9Sstevel@tonic-gate 		/* op processing inlined in xdr_OPEN4cargs */
44167c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4cargs(xdrs, &objp->nfs_argop4_u.opcopen));
44177c478bd9Sstevel@tonic-gate 	case OP_CREMOVE:
44187c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcremove.ctarget);
44197c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44207c478bd9Sstevel@tonic-gate 			return (FALSE);
44217c478bd9Sstevel@tonic-gate 		op = OP_REMOVE;
44227c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
44237c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
44247c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
44257c478bd9Sstevel@tonic-gate 				    objp->nfs_argop4_u.opcremove.ctarget,
44267c478bd9Sstevel@tonic-gate 				    len));
44277c478bd9Sstevel@tonic-gate 			}
44287c478bd9Sstevel@tonic-gate 		}
44297c478bd9Sstevel@tonic-gate 		return (FALSE);
44307c478bd9Sstevel@tonic-gate 	case OP_CCREATE:
44317c478bd9Sstevel@tonic-gate 		op = OP_CREATE;
44327c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &op))
44337c478bd9Sstevel@tonic-gate 			return (FALSE);
44347c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4cargs(xdrs, &objp->nfs_argop4_u.opccreate));
44357c478bd9Sstevel@tonic-gate 	case OP_CLINK:
44367c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opclink.cnewname);
44377c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44387c478bd9Sstevel@tonic-gate 			return (FALSE);
44397c478bd9Sstevel@tonic-gate 		op = OP_LINK;
44407c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
44417c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
44427c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
44437c478bd9Sstevel@tonic-gate 				    objp->nfs_argop4_u.opclink.cnewname,
44447c478bd9Sstevel@tonic-gate 				    len));
44457c478bd9Sstevel@tonic-gate 			}
44467c478bd9Sstevel@tonic-gate 		}
44477c478bd9Sstevel@tonic-gate 		return (FALSE);
44487c478bd9Sstevel@tonic-gate 	case OP_CRENAME:
44497c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcrename.coldname);
44507c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44517c478bd9Sstevel@tonic-gate 			return (FALSE);
44527c478bd9Sstevel@tonic-gate 		op = OP_RENAME;
44537c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &op))
44547c478bd9Sstevel@tonic-gate 			return (FALSE);
44557c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &len))
44567c478bd9Sstevel@tonic-gate 			return (FALSE);
44577c478bd9Sstevel@tonic-gate 		if (!xdr_opaque(xdrs,
44587c478bd9Sstevel@tonic-gate 		    objp->nfs_argop4_u.opcrename.coldname, len))
44597c478bd9Sstevel@tonic-gate 			return (FALSE);
44607c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcrename.cnewname);
44617c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44627c478bd9Sstevel@tonic-gate 			return (FALSE);
44637c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &len)) {
44647c478bd9Sstevel@tonic-gate 			return (xdr_opaque(xdrs,
44657c478bd9Sstevel@tonic-gate 			    objp->nfs_argop4_u.opcrename.cnewname, len));
44667c478bd9Sstevel@tonic-gate 		}
44677c478bd9Sstevel@tonic-gate 		return (FALSE);
44687c478bd9Sstevel@tonic-gate 	case OP_CSECINFO:
44697c478bd9Sstevel@tonic-gate 		len = strlen(objp->nfs_argop4_u.opcsecinfo.cname);
44707c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
44717c478bd9Sstevel@tonic-gate 			return (FALSE);
44727c478bd9Sstevel@tonic-gate 		op = OP_SECINFO;
44737c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, &op)) {
44747c478bd9Sstevel@tonic-gate 			if (XDR_PUTINT32(xdrs, &len)) {
44757c478bd9Sstevel@tonic-gate 				return (xdr_opaque(xdrs,
44767c478bd9Sstevel@tonic-gate 				    objp->nfs_argop4_u.opcsecinfo.cname,
44777c478bd9Sstevel@tonic-gate 				    len));
44787c478bd9Sstevel@tonic-gate 			}
44797c478bd9Sstevel@tonic-gate 		}
44807c478bd9Sstevel@tonic-gate 		return (FALSE);
44817c478bd9Sstevel@tonic-gate 	}
44827c478bd9Sstevel@tonic-gate 	return (FALSE);
44837c478bd9Sstevel@tonic-gate }
44847c478bd9Sstevel@tonic-gate 
44857c478bd9Sstevel@tonic-gate /*
44867c478bd9Sstevel@tonic-gate  * Note that the len and decode_len will only be different in the case
44877c478bd9Sstevel@tonic-gate  * of the client's use of this free function.  If the server is
44887c478bd9Sstevel@tonic-gate  * freeing results, then the len/decode_len will always match.
44897c478bd9Sstevel@tonic-gate  */
44907c478bd9Sstevel@tonic-gate static bool_t
44917c478bd9Sstevel@tonic-gate xdr_nfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
44927c478bd9Sstevel@tonic-gate {
44937c478bd9Sstevel@tonic-gate 	int i;
44947c478bd9Sstevel@tonic-gate 	nfs_resop4 *array = *arrayp;
44952f172c55SRobert Thurlow 	nfs4_ga_res_t *gr;
44967c478bd9Sstevel@tonic-gate 
44977c478bd9Sstevel@tonic-gate 	/*
44987c478bd9Sstevel@tonic-gate 	 * Optimized XDR_FREE only results array
44997c478bd9Sstevel@tonic-gate 	 */
45007c478bd9Sstevel@tonic-gate 	ASSERT(xdrs->x_op == XDR_FREE);
45017c478bd9Sstevel@tonic-gate 
45027c478bd9Sstevel@tonic-gate 	if (array == NULL)
45037c478bd9Sstevel@tonic-gate 		return (TRUE);
45047c478bd9Sstevel@tonic-gate 
45057c478bd9Sstevel@tonic-gate 	for (i = 0; i < decode_len; i++) {
45067c478bd9Sstevel@tonic-gate 		/*
45077c478bd9Sstevel@tonic-gate 		 * These should be ordered by frequency of use
45087c478bd9Sstevel@tonic-gate 		 */
45097c478bd9Sstevel@tonic-gate 		switch (array[i].resop) {
45107c478bd9Sstevel@tonic-gate 		case OP_PUTFH:
45117c478bd9Sstevel@tonic-gate 			continue;
45127c478bd9Sstevel@tonic-gate 		case OP_GETATTR:
45137c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetattr.status != NFS4_OK)
45147c478bd9Sstevel@tonic-gate 				continue;
45152f172c55SRobert Thurlow 
45162f172c55SRobert Thurlow 			gr = &array[i].nfs_resop4_u.opgetattr.ga_res;
45172f172c55SRobert Thurlow 			if (gr->n4g_ext_res) {
45182f172c55SRobert Thurlow 				if (gr->n4g_resbmap & FATTR4_FS_LOCATIONS_MASK)
45192f172c55SRobert Thurlow 					(void) xdr_fattr4_fs_locations(xdrs,
45202f172c55SRobert Thurlow 					    &gr->n4g_ext_res->n4g_fslocations);
45212f172c55SRobert Thurlow 				kmem_free(gr->n4g_ext_res,
45227c478bd9Sstevel@tonic-gate 				    sizeof (struct nfs4_ga_ext_res));
45232f172c55SRobert Thurlow 			}
45247c478bd9Sstevel@tonic-gate 			continue;
45257c478bd9Sstevel@tonic-gate 		case OP_GETFH:
45267c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetfh.status != NFS4_OK)
45277c478bd9Sstevel@tonic-gate 				continue;
45287c478bd9Sstevel@tonic-gate 			if (array[i].nfs_resop4_u.opgetfh.object.nfs_fh4_val !=
45297c478bd9Sstevel@tonic-gate 			    NULL) {
45307c478bd9Sstevel@tonic-gate 				kmem_free(array[i].nfs_resop4_u.opgetfh.object.
45317c478bd9Sstevel@tonic-gate 				    nfs_fh4_val,
45327c478bd9Sstevel@tonic-gate 				    array[i].nfs_resop4_u.opgetfh.object.
45337c478bd9Sstevel@tonic-gate 				    nfs_fh4_len);
45347c478bd9Sstevel@tonic-gate 			}
45357c478bd9Sstevel@tonic-gate 			continue;
45367c478bd9Sstevel@tonic-gate 		case OP_LOOKUP:
45377c478bd9Sstevel@tonic-gate 			continue;
45387c478bd9Sstevel@tonic-gate 		case OP_OPEN:
45397c478bd9Sstevel@tonic-gate 			(void) xdr_OPEN4res(xdrs, &array[i].nfs_resop4_u.
45407c478bd9Sstevel@tonic-gate 			    opopen);
45417c478bd9Sstevel@tonic-gate 			continue;
45427c478bd9Sstevel@tonic-gate 		case OP_CLOSE:
45437c478bd9Sstevel@tonic-gate 		case OP_ACCESS:
45447c478bd9Sstevel@tonic-gate 			continue;
45457c478bd9Sstevel@tonic-gate 		case OP_READ:
45467c478bd9Sstevel@tonic-gate 			(void) xdr_READ4res(xdrs,
45470a701b1eSRobert Gordon 			    &array[i].nfs_resop4_u.opread);
45487c478bd9Sstevel@tonic-gate 			continue;
45497c478bd9Sstevel@tonic-gate 		case OP_WRITE:
45507c478bd9Sstevel@tonic-gate 		case OP_DELEGRETURN:
45517c478bd9Sstevel@tonic-gate 		case OP_LOOKUPP:
45527c478bd9Sstevel@tonic-gate 		case OP_READDIR:
45537c478bd9Sstevel@tonic-gate 		case OP_REMOVE:
45547c478bd9Sstevel@tonic-gate 		case OP_COMMIT:
45557c478bd9Sstevel@tonic-gate 		case OP_CREATE:
45567c478bd9Sstevel@tonic-gate 		case OP_DELEGPURGE:
45577c478bd9Sstevel@tonic-gate 		case OP_LINK:
45587c478bd9Sstevel@tonic-gate 			continue;
45597c478bd9Sstevel@tonic-gate 		case OP_LOCK:
45607c478bd9Sstevel@tonic-gate 			(void) xdr_LOCK4res(xdrs, &array[i].nfs_resop4_u.
45617c478bd9Sstevel@tonic-gate 			    oplock);
45627c478bd9Sstevel@tonic-gate 			continue;
45637c478bd9Sstevel@tonic-gate 		case OP_LOCKT:
45647c478bd9Sstevel@tonic-gate 			(void) xdr_LOCKT4res(xdrs, &array[i].nfs_resop4_u.
45657c478bd9Sstevel@tonic-gate 			    oplockt);
45667c478bd9Sstevel@tonic-gate 			continue;
45677c478bd9Sstevel@tonic-gate 		case OP_LOCKU:
45687c478bd9Sstevel@tonic-gate 		case OP_NVERIFY:
45697c478bd9Sstevel@tonic-gate 		case OP_OPENATTR:
45707c478bd9Sstevel@tonic-gate 		case OP_OPEN_CONFIRM:
45717c478bd9Sstevel@tonic-gate 		case OP_OPEN_DOWNGRADE:
45727c478bd9Sstevel@tonic-gate 		case OP_PUTPUBFH:
45737c478bd9Sstevel@tonic-gate 		case OP_PUTROOTFH:
45747c478bd9Sstevel@tonic-gate 		case OP_RENAME:
45757c478bd9Sstevel@tonic-gate 		case OP_RENEW:
45767c478bd9Sstevel@tonic-gate 		case OP_RESTOREFH:
45777c478bd9Sstevel@tonic-gate 		case OP_SAVEFH:
45787c478bd9Sstevel@tonic-gate 			continue;
45797c478bd9Sstevel@tonic-gate 		case OP_READLINK:
45807c478bd9Sstevel@tonic-gate 			(void) xdr_READLINK4res(xdrs, &array[i].nfs_resop4_u.
45817c478bd9Sstevel@tonic-gate 			    opreadlink);
45827c478bd9Sstevel@tonic-gate 			continue;
45837c478bd9Sstevel@tonic-gate 		case OP_SECINFO:
45847c478bd9Sstevel@tonic-gate 			(void) xdr_array(xdrs,
45857c478bd9Sstevel@tonic-gate 			    (char **)&array[i].nfs_resop4_u.opsecinfo.
45867c478bd9Sstevel@tonic-gate 			    SECINFO4resok_val,
45877c478bd9Sstevel@tonic-gate 			    (uint_t *)&array[i].nfs_resop4_u.opsecinfo.
45887c478bd9Sstevel@tonic-gate 			    SECINFO4resok_len,
45897c478bd9Sstevel@tonic-gate 			    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
45907c478bd9Sstevel@tonic-gate 			    (xdrproc_t)xdr_secinfo4);
45917c478bd9Sstevel@tonic-gate 			continue;
45927c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID:
45937c478bd9Sstevel@tonic-gate 			(void) xdr_SETCLIENTID4res(xdrs,
45947c478bd9Sstevel@tonic-gate 			    &array[i].nfs_resop4_u.opsetclientid);
45957c478bd9Sstevel@tonic-gate 			continue;
45967c478bd9Sstevel@tonic-gate 		case OP_SETATTR:
45977c478bd9Sstevel@tonic-gate 		case OP_SETCLIENTID_CONFIRM:
45987c478bd9Sstevel@tonic-gate 		case OP_VERIFY:
45997c478bd9Sstevel@tonic-gate 		case OP_RELEASE_LOCKOWNER:
46007c478bd9Sstevel@tonic-gate 		case OP_ILLEGAL:
46017c478bd9Sstevel@tonic-gate 			continue;
46027c478bd9Sstevel@tonic-gate 		default:
46037c478bd9Sstevel@tonic-gate 			/*
46047c478bd9Sstevel@tonic-gate 			 * An invalid op is a coding error, it should never
46057c478bd9Sstevel@tonic-gate 			 * have been decoded.
46067c478bd9Sstevel@tonic-gate 			 * Don't error because the caller cannot finish
46077c478bd9Sstevel@tonic-gate 			 * freeing the residual memory of the array.
46087c478bd9Sstevel@tonic-gate 			 */
46097c478bd9Sstevel@tonic-gate 			continue;
46107c478bd9Sstevel@tonic-gate 		}
46117c478bd9Sstevel@tonic-gate 	}
46127c478bd9Sstevel@tonic-gate 
46137c478bd9Sstevel@tonic-gate 	kmem_free(*arrayp, len * sizeof (nfs_resop4));
46147c478bd9Sstevel@tonic-gate 	*arrayp = NULL;
46157c478bd9Sstevel@tonic-gate 	return (TRUE);
46167c478bd9Sstevel@tonic-gate }
46177c478bd9Sstevel@tonic-gate 
46187c478bd9Sstevel@tonic-gate static bool_t
46197c46fb7fSek110237 xdr_snfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
46207c46fb7fSek110237 {
46217c46fb7fSek110237 	return (xdr_nfs_resop4_free(xdrs, arrayp, len, decode_len));
46227c46fb7fSek110237 }
46237c46fb7fSek110237 
46247c46fb7fSek110237 static bool_t
46257c478bd9Sstevel@tonic-gate xdr_nfs_resop4(XDR *xdrs, nfs_resop4 *objp)
46267c478bd9Sstevel@tonic-gate {
46277c478bd9Sstevel@tonic-gate 	/*
46287c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
46297c478bd9Sstevel@tonic-gate 	 */
46307c478bd9Sstevel@tonic-gate 	switch (objp->resop) {
46317c478bd9Sstevel@tonic-gate 	case OP_PUTFH:
46327c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46337c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
46347c478bd9Sstevel@tonic-gate 	case OP_GETATTR:
46357c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
46367c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
46377c478bd9Sstevel@tonic-gate 			return (FALSE);
46387c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
46397c478bd9Sstevel@tonic-gate 			return (TRUE);
46407c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
46417c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opgetattr.obj_attributes));
46427c478bd9Sstevel@tonic-gate 	case OP_GETFH:
46437c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
46447c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
46457c478bd9Sstevel@tonic-gate 			return (FALSE);
46467c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
46477c478bd9Sstevel@tonic-gate 			return (TRUE);
46487c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
46497c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
46507c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
46517c478bd9Sstevel@tonic-gate 		    NFS4_FHSIZE));
46527c478bd9Sstevel@tonic-gate 	case OP_LOOKUP:
46537c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46547c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
46557c478bd9Sstevel@tonic-gate 	case OP_OPEN:
46567c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
46577c478bd9Sstevel@tonic-gate 	case OP_CLOSE:
46587c478bd9Sstevel@tonic-gate 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
46597c478bd9Sstevel@tonic-gate 	case OP_ACCESS:
46607c478bd9Sstevel@tonic-gate 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
46617c478bd9Sstevel@tonic-gate 	case OP_READ:
46627c478bd9Sstevel@tonic-gate 		return (xdr_READ4res(xdrs, &objp->nfs_resop4_u.opread));
46637c478bd9Sstevel@tonic-gate 	case OP_WRITE:
46647c478bd9Sstevel@tonic-gate 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
46657c478bd9Sstevel@tonic-gate 	case OP_DELEGRETURN:
46667c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46677c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
46687c478bd9Sstevel@tonic-gate 	case OP_LOOKUPP:
46697c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46707c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
46717c478bd9Sstevel@tonic-gate 	case OP_READDIR:
46727c478bd9Sstevel@tonic-gate 		return (xdr_READDIR4res(xdrs, &objp->nfs_resop4_u.opreaddir));
46737c478bd9Sstevel@tonic-gate 	case OP_REMOVE:
46747c478bd9Sstevel@tonic-gate 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
46757c478bd9Sstevel@tonic-gate 
46767c478bd9Sstevel@tonic-gate 	case OP_COMMIT:
46777c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
46787c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
46797c478bd9Sstevel@tonic-gate 			return (FALSE);
46807c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
46817c478bd9Sstevel@tonic-gate 			return (TRUE);
46827c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
46837c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
46847c478bd9Sstevel@tonic-gate 		    writeverf));
46857c478bd9Sstevel@tonic-gate 	case OP_CREATE:
46867c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
46877c478bd9Sstevel@tonic-gate 	case OP_DELEGPURGE:
46887c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
46897c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
46907c478bd9Sstevel@tonic-gate 	case OP_LINK:
46917c478bd9Sstevel@tonic-gate 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
46927c478bd9Sstevel@tonic-gate 	case OP_LOCK:
46937c478bd9Sstevel@tonic-gate 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
46947c478bd9Sstevel@tonic-gate 	case OP_LOCKT:
46957c478bd9Sstevel@tonic-gate 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
46967c478bd9Sstevel@tonic-gate 	case OP_LOCKU:
46977c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
46987c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
46997c478bd9Sstevel@tonic-gate 			return (FALSE);
47007c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
47017c478bd9Sstevel@tonic-gate 			return (TRUE);
47027c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs,
47037c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
47047c478bd9Sstevel@tonic-gate 			return (FALSE);
47057c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs,
47067c478bd9Sstevel@tonic-gate 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
4707bbe876c0SMarcel Telka 		    NFS4_OTHER_SIZE));
47087c478bd9Sstevel@tonic-gate 	case OP_NVERIFY:
47097c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47107c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
47117c478bd9Sstevel@tonic-gate 	case OP_OPENATTR:
47127c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47137c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
47147c478bd9Sstevel@tonic-gate 	case OP_OPEN_CONFIRM:
47157c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_CONFIRM4res(xdrs,
47167c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opopen_confirm));
47177c478bd9Sstevel@tonic-gate 	case OP_OPEN_DOWNGRADE:
47187c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
47197c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opopen_downgrade));
47207c478bd9Sstevel@tonic-gate 	case OP_PUTPUBFH:
47217c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47227c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
47237c478bd9Sstevel@tonic-gate 	case OP_PUTROOTFH:
47247c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47257c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
47267c478bd9Sstevel@tonic-gate 	case OP_READLINK:
47277c478bd9Sstevel@tonic-gate 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
47287c478bd9Sstevel@tonic-gate 	case OP_RENAME:
47297c478bd9Sstevel@tonic-gate 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
47307c478bd9Sstevel@tonic-gate 	case OP_RENEW:
47317c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47327c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
47337c478bd9Sstevel@tonic-gate 	case OP_RESTOREFH:
47347c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47357c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
47367c478bd9Sstevel@tonic-gate 	case OP_SAVEFH:
47377c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47387c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
47397c478bd9Sstevel@tonic-gate 	case OP_SECINFO:
47407c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
47417c478bd9Sstevel@tonic-gate 		    status))
47427c478bd9Sstevel@tonic-gate 			return (FALSE);
47437c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
47447c478bd9Sstevel@tonic-gate 			return (TRUE);
47457c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
47467c478bd9Sstevel@tonic-gate 		    SECINFO4resok_val,
47477c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
47487c478bd9Sstevel@tonic-gate 		    SECINFO4resok_len,
47497c478bd9Sstevel@tonic-gate 		    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
47507c478bd9Sstevel@tonic-gate 		    (xdrproc_t)xdr_secinfo4));
47517c478bd9Sstevel@tonic-gate 	case OP_SETATTR:
47527c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
47537c478bd9Sstevel@tonic-gate 		    status))
47547c478bd9Sstevel@tonic-gate 			return (FALSE);
47557c478bd9Sstevel@tonic-gate 		return (xdr_bitmap4(xdrs,
47567c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opsetattr.attrsset));
47577c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID:
47587c478bd9Sstevel@tonic-gate 		return (xdr_SETCLIENTID4res(xdrs,
47597c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opsetclientid));
47607c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID_CONFIRM:
47617c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47627c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
47637c478bd9Sstevel@tonic-gate 		    status));
47647c478bd9Sstevel@tonic-gate 	case OP_VERIFY:
47657c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47667c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
47677c478bd9Sstevel@tonic-gate 	case OP_RELEASE_LOCKOWNER:
47687c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47697c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
47707c478bd9Sstevel@tonic-gate 	case OP_ILLEGAL:
47717c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
47727c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
47737c478bd9Sstevel@tonic-gate 	}
47747c478bd9Sstevel@tonic-gate 	return (FALSE);
47757c478bd9Sstevel@tonic-gate }
47767c478bd9Sstevel@tonic-gate 
47777c478bd9Sstevel@tonic-gate static bool_t
47787c46fb7fSek110237 xdr_snfs_resop4(XDR *xdrs, nfs_resop4 *objp)
47797c46fb7fSek110237 {
47807c46fb7fSek110237 	if (!xdr_int(xdrs, (int *)&objp->resop))
47817c46fb7fSek110237 		return (FALSE);
47827c46fb7fSek110237 
47837c46fb7fSek110237 	switch (objp->resop) {
47847c46fb7fSek110237 	case OP_GETFH:
47857c46fb7fSek110237 		if (!XDR_PUTINT32(xdrs,
47867c46fb7fSek110237 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
47877c46fb7fSek110237 			return (FALSE);
47887c46fb7fSek110237 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
4789*c93d332cSDan McDonald 			return (TRUE);
4790*c93d332cSDan McDonald 		return (xdr_encode_nfs_fh4(xdrs,
4791*c93d332cSDan McDonald 		    &objp->nfs_resop4_u.opgetfh.object));
47927c46fb7fSek110237 	default:
4793*c93d332cSDan McDonald 		return (xdr_nfs_resop4(xdrs, objp));
47947c46fb7fSek110237 	}
47957c46fb7fSek110237 }
47967c46fb7fSek110237 
47977c46fb7fSek110237 static bool_t
47987c478bd9Sstevel@tonic-gate xdr_nfs_resop4_clnt(XDR *xdrs, nfs_resop4 *objp, nfs_argop4 *aobjp)
47997c478bd9Sstevel@tonic-gate {
48007c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int *)&objp->resop))
48017c478bd9Sstevel@tonic-gate 		return (FALSE);
48027c478bd9Sstevel@tonic-gate 	/*
48037c478bd9Sstevel@tonic-gate 	 * These should be ordered by frequency of use
48047c478bd9Sstevel@tonic-gate 	 */
48057c478bd9Sstevel@tonic-gate 	switch (objp->resop) {
48067c478bd9Sstevel@tonic-gate 	case OP_PUTFH:
48077c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48087c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
48097c478bd9Sstevel@tonic-gate 	case OP_GETATTR:
48107c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
48117c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
48127c478bd9Sstevel@tonic-gate 			return (FALSE);
48137c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
48147c478bd9Sstevel@tonic-gate 			return (TRUE);
48157c478bd9Sstevel@tonic-gate 		return (xdr_ga_res(xdrs,
48167c478bd9Sstevel@tonic-gate 		    (GETATTR4res *)&objp->nfs_resop4_u.opgetattr,
48177c478bd9Sstevel@tonic-gate 		    &aobjp->nfs_argop4_u.opgetattr));
48187c478bd9Sstevel@tonic-gate 	case OP_GETFH:
48197c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
48207c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
48217c478bd9Sstevel@tonic-gate 			return (FALSE);
48227c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
48237c478bd9Sstevel@tonic-gate 			return (TRUE);
48247c478bd9Sstevel@tonic-gate 		return (xdr_bytes(xdrs,
48257c478bd9Sstevel@tonic-gate 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
48267c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
48277c478bd9Sstevel@tonic-gate 		    NFS4_FHSIZE));
48287c478bd9Sstevel@tonic-gate 	case OP_LOOKUP:
48297c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48307c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
48317c478bd9Sstevel@tonic-gate 	case OP_NVERIFY:
48327c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48337c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
48347c478bd9Sstevel@tonic-gate 	case OP_OPEN:
48357c478bd9Sstevel@tonic-gate 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
48367c478bd9Sstevel@tonic-gate 	case OP_CLOSE:
48377c478bd9Sstevel@tonic-gate 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
48387c478bd9Sstevel@tonic-gate 	case OP_ACCESS:
48397c478bd9Sstevel@tonic-gate 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
48407c478bd9Sstevel@tonic-gate 	case OP_READ:
48417c478bd9Sstevel@tonic-gate 		return (xdr_READ4res_clnt(xdrs, &objp->nfs_resop4_u.opread,
48427c478bd9Sstevel@tonic-gate 		    &aobjp->nfs_argop4_u.opread));
48437c478bd9Sstevel@tonic-gate 	case OP_WRITE:
48447c478bd9Sstevel@tonic-gate 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
48457c478bd9Sstevel@tonic-gate 	case OP_DELEGRETURN:
48467c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48477c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
48487c478bd9Sstevel@tonic-gate 	case OP_LOOKUPP:
48497c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48507c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
48517c478bd9Sstevel@tonic-gate 	case OP_READDIR:
48527c478bd9Sstevel@tonic-gate 		return (xdr_READDIR4res_clnt(xdrs,
48537c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opreaddirclnt,
48547c478bd9Sstevel@tonic-gate 		    &aobjp->nfs_argop4_u.opreaddir));
48557c478bd9Sstevel@tonic-gate 	case OP_REMOVE:
48567c478bd9Sstevel@tonic-gate 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
48577c478bd9Sstevel@tonic-gate 
48587c478bd9Sstevel@tonic-gate 	case OP_COMMIT:
48597c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
48607c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
48617c478bd9Sstevel@tonic-gate 			return (FALSE);
48627c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
48637c478bd9Sstevel@tonic-gate 			return (TRUE);
48647c478bd9Sstevel@tonic-gate 		return (xdr_u_longlong_t(xdrs,
48657c478bd9Sstevel@tonic-gate 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
48667c478bd9Sstevel@tonic-gate 		    writeverf));
48677c478bd9Sstevel@tonic-gate 	case OP_CREATE:
48687c478bd9Sstevel@tonic-gate 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
48697c478bd9Sstevel@tonic-gate 	case OP_DELEGPURGE:
48707c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48717c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
48727c478bd9Sstevel@tonic-gate 	case OP_LINK:
48737c478bd9Sstevel@tonic-gate 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
48747c478bd9Sstevel@tonic-gate 	case OP_LOCK:
48757c478bd9Sstevel@tonic-gate 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
48767c478bd9Sstevel@tonic-gate 	case OP_LOCKT:
48777c478bd9Sstevel@tonic-gate 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
48787c478bd9Sstevel@tonic-gate 	case OP_LOCKU:
48797c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
48807c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
48817c478bd9Sstevel@tonic-gate 			return (FALSE);
48827c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
48837c478bd9Sstevel@tonic-gate 			return (TRUE);
48847c478bd9Sstevel@tonic-gate 		if (!xdr_u_int(xdrs,
48857c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
48867c478bd9Sstevel@tonic-gate 			return (FALSE);
48877c478bd9Sstevel@tonic-gate 		return (xdr_opaque(xdrs,
48887c478bd9Sstevel@tonic-gate 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
4889bbe876c0SMarcel Telka 		    NFS4_OTHER_SIZE));
48907c478bd9Sstevel@tonic-gate 	case OP_OPENATTR:
48917c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
48927c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
48937c478bd9Sstevel@tonic-gate 	case OP_OPEN_CONFIRM:
48947c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_CONFIRM4res(xdrs,
48957c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opopen_confirm));
48967c478bd9Sstevel@tonic-gate 	case OP_OPEN_DOWNGRADE:
48977c478bd9Sstevel@tonic-gate 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
48987c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opopen_downgrade));
48997c478bd9Sstevel@tonic-gate 	case OP_PUTPUBFH:
49007c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49017c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
49027c478bd9Sstevel@tonic-gate 	case OP_PUTROOTFH:
49037c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49047c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
49057c478bd9Sstevel@tonic-gate 	case OP_READLINK:
49067c478bd9Sstevel@tonic-gate 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
49077c478bd9Sstevel@tonic-gate 	case OP_RENAME:
49087c478bd9Sstevel@tonic-gate 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
49097c478bd9Sstevel@tonic-gate 	case OP_RENEW:
49107c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49117c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
49127c478bd9Sstevel@tonic-gate 	case OP_RESTOREFH:
49137c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49147c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
49157c478bd9Sstevel@tonic-gate 	case OP_SAVEFH:
49167c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49177c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
49187c478bd9Sstevel@tonic-gate 	case OP_SECINFO:
49197c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
49207c478bd9Sstevel@tonic-gate 		    status))
49217c478bd9Sstevel@tonic-gate 			return (FALSE);
49227c478bd9Sstevel@tonic-gate 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
49237c478bd9Sstevel@tonic-gate 			return (TRUE);
49247c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
49257c478bd9Sstevel@tonic-gate 		    SECINFO4resok_val,
49267c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
49277c478bd9Sstevel@tonic-gate 		    SECINFO4resok_len,
49287c478bd9Sstevel@tonic-gate 		    ~0, sizeof (secinfo4), (xdrproc_t)xdr_secinfo4));
49297c478bd9Sstevel@tonic-gate 	case OP_SETATTR:
49307c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
49317c478bd9Sstevel@tonic-gate 		    status))
49327c478bd9Sstevel@tonic-gate 			return (FALSE);
49337c478bd9Sstevel@tonic-gate 		return (xdr_bitmap4(xdrs,
49347c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opsetattr.attrsset));
49357c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID:
49367c478bd9Sstevel@tonic-gate 		return (xdr_SETCLIENTID4res(xdrs,
49377c478bd9Sstevel@tonic-gate 		    &objp->nfs_resop4_u.opsetclientid));
49387c478bd9Sstevel@tonic-gate 	case OP_SETCLIENTID_CONFIRM:
49397c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49407c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
49417c478bd9Sstevel@tonic-gate 		    status));
49427c478bd9Sstevel@tonic-gate 	case OP_VERIFY:
49437c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49447c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
49457c478bd9Sstevel@tonic-gate 	case OP_RELEASE_LOCKOWNER:
49467c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49477c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
49487c478bd9Sstevel@tonic-gate 	case OP_ILLEGAL:
49497c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
49507c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
49517c478bd9Sstevel@tonic-gate 	}
49527c478bd9Sstevel@tonic-gate 	return (FALSE);
49537c478bd9Sstevel@tonic-gate }
49547c478bd9Sstevel@tonic-gate 
49557c478bd9Sstevel@tonic-gate bool_t
49567c478bd9Sstevel@tonic-gate xdr_COMPOUND4args_clnt(XDR *xdrs, COMPOUND4args_clnt *objp)
49577c478bd9Sstevel@tonic-gate {
49587c478bd9Sstevel@tonic-gate 	static int32_t twelve = 12;
49597c478bd9Sstevel@tonic-gate 	static int32_t minorversion = NFS4_MINORVERSION;
49607c478bd9Sstevel@tonic-gate 	uint32_t *ctagp;
49617c478bd9Sstevel@tonic-gate 	rpc_inline_t *ptr;
49620a701b1eSRobert Gordon 	rdma_chunkinfo_t rci;
49630a701b1eSRobert Gordon 	struct xdr_ops *xops = xdrrdma_xops();
49647c478bd9Sstevel@tonic-gate 
49657c478bd9Sstevel@tonic-gate 	/*
49667c478bd9Sstevel@tonic-gate 	 * XDR_ENCODE only
49677c478bd9Sstevel@tonic-gate 	 */
49687c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
49697c478bd9Sstevel@tonic-gate 		return (TRUE);
49707c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
49717c478bd9Sstevel@tonic-gate 		return (FALSE);
49727c478bd9Sstevel@tonic-gate 
49737c478bd9Sstevel@tonic-gate 	ctagp = (uint32_t *)&nfs4_ctags[objp->ctag].ct_tag;
49747c478bd9Sstevel@tonic-gate 
49757c478bd9Sstevel@tonic-gate 	if ((ptr = XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT)) != NULL) {
49767c478bd9Sstevel@tonic-gate 		/*
49777c478bd9Sstevel@tonic-gate 		 * Efficiently encode fixed length tags, could be longlongs
49787c478bd9Sstevel@tonic-gate 		 * but 8 byte XDR alignment not assured
49797c478bd9Sstevel@tonic-gate 		 */
49807c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, 12);
49817c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, ctagp[0]);
49827c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, ctagp[1]);
49837c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, ctagp[2]);
49847c478bd9Sstevel@tonic-gate 
49857c478bd9Sstevel@tonic-gate 		/*
49867c478bd9Sstevel@tonic-gate 		 * Fixed minor version for now
49877c478bd9Sstevel@tonic-gate 		 */
49887c478bd9Sstevel@tonic-gate 		IXDR_PUT_U_INT32(ptr, NFS4_MINORVERSION);
49897c478bd9Sstevel@tonic-gate 	} else {
49907c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, &twelve))
49917c478bd9Sstevel@tonic-gate 			return (FALSE);
49927c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[0]))
49937c478bd9Sstevel@tonic-gate 			return (FALSE);
49947c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[1]))
49957c478bd9Sstevel@tonic-gate 			return (FALSE);
49967c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[2]))
49977c478bd9Sstevel@tonic-gate 			return (FALSE);
49987c478bd9Sstevel@tonic-gate 		if (!XDR_PUTINT32(xdrs, (int32_t *)&minorversion))
49997c478bd9Sstevel@tonic-gate 			return (FALSE);
50007c478bd9Sstevel@tonic-gate 	}
50010a701b1eSRobert Gordon 	if (xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) {
50020a701b1eSRobert Gordon 		rci.rci_type = RCI_REPLY_CHUNK;
50030a701b1eSRobert Gordon 		rci.rci_len = MAXPATHLEN * 2;
50040a701b1eSRobert Gordon 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
50050a701b1eSRobert Gordon 	}
50067c478bd9Sstevel@tonic-gate 
50077c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->array,
50087c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
50097c478bd9Sstevel@tonic-gate 	    sizeof (nfs_argop4), (xdrproc_t)xdr_cnfs_argop4));
50107c478bd9Sstevel@tonic-gate }
50117c478bd9Sstevel@tonic-gate 
50127c478bd9Sstevel@tonic-gate bool_t
50137c46fb7fSek110237 xdr_COMPOUND4args_srv(XDR *xdrs, COMPOUND4args *objp)
50147c478bd9Sstevel@tonic-gate {
50157c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
50167c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->tag.utf8string_len,
50177c478bd9Sstevel@tonic-gate 	    NFS4_MAX_UTF8STRING))
50187c478bd9Sstevel@tonic-gate 		return (FALSE);
50197c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->minorversion))
50207c478bd9Sstevel@tonic-gate 		return (FALSE);
50217c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE)
50227c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->array,
50237c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
50247c46fb7fSek110237 		    sizeof (nfs_argop4), (xdrproc_t)xdr_snfs_argop4));
50257c478bd9Sstevel@tonic-gate 
50267c46fb7fSek110237 	return (xdr_snfs_argop4_free(xdrs, &objp->array, objp->array_len));
50277c478bd9Sstevel@tonic-gate }
50287c478bd9Sstevel@tonic-gate 
50297c478bd9Sstevel@tonic-gate bool_t
50307c478bd9Sstevel@tonic-gate xdr_COMPOUND4res_clnt(XDR *xdrs, COMPOUND4res_clnt *objp)
50317c478bd9Sstevel@tonic-gate {
50327c478bd9Sstevel@tonic-gate 	uint32_t len;
50337c478bd9Sstevel@tonic-gate 	int32_t *ptr;
50347c478bd9Sstevel@tonic-gate 	nfs_argop4 *argop;
50357c478bd9Sstevel@tonic-gate 	nfs_resop4 *resop;
50367c478bd9Sstevel@tonic-gate 
50377c478bd9Sstevel@tonic-gate 	/*
50387c478bd9Sstevel@tonic-gate 	 * No XDR_ENCODE
50397c478bd9Sstevel@tonic-gate 	 */
50407c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
50417c478bd9Sstevel@tonic-gate 		return (FALSE);
50427c478bd9Sstevel@tonic-gate 
50437c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE) {
50447c478bd9Sstevel@tonic-gate 		if ((ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL) {
50457c478bd9Sstevel@tonic-gate 			objp->status = IXDR_GET_U_INT32(ptr);
50467c478bd9Sstevel@tonic-gate 			len = IXDR_GET_U_INT32(ptr);
50477c478bd9Sstevel@tonic-gate 		} else {
50487c478bd9Sstevel@tonic-gate 			if (!xdr_int(xdrs, (int32_t *)&objp->status))
50497c478bd9Sstevel@tonic-gate 				return (FALSE);
50507c478bd9Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (uint32_t *)&len))
50517c478bd9Sstevel@tonic-gate 				return (FALSE);
50527c478bd9Sstevel@tonic-gate 		}
50537c478bd9Sstevel@tonic-gate 		if (len > NFS4_MAX_UTF8STRING)
50547c478bd9Sstevel@tonic-gate 			return (FALSE);
50557c478bd9Sstevel@tonic-gate 		/*
50567c478bd9Sstevel@tonic-gate 		 * Ignore the tag
50577c478bd9Sstevel@tonic-gate 		 */
50587c478bd9Sstevel@tonic-gate 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &len))
50597c478bd9Sstevel@tonic-gate 			return (FALSE);
50607c478bd9Sstevel@tonic-gate 
50617c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs, (int32_t *)&objp->array_len))
50627c478bd9Sstevel@tonic-gate 			return (FALSE);
50637c478bd9Sstevel@tonic-gate 
50647c478bd9Sstevel@tonic-gate 		if (objp->array_len > objp->argsp->array_len)
50657c478bd9Sstevel@tonic-gate 			return (FALSE);
50667c478bd9Sstevel@tonic-gate 
50672c2d21e9SRichard Lowe 		if (objp->status == NFS4_OK &&
50687c478bd9Sstevel@tonic-gate 		    objp->array_len != objp->argsp->array_len)
50697c478bd9Sstevel@tonic-gate 			return (FALSE);
50707c478bd9Sstevel@tonic-gate 
50717c478bd9Sstevel@tonic-gate 		/* Alloc the results array */
50727c478bd9Sstevel@tonic-gate 		argop = objp->argsp->array;
50737c478bd9Sstevel@tonic-gate 		len = objp->array_len * sizeof (nfs_resop4);
50747c478bd9Sstevel@tonic-gate 		objp->decode_len = 0;
50757c478bd9Sstevel@tonic-gate 		objp->array = resop = kmem_zalloc(len, KM_SLEEP);
50767c478bd9Sstevel@tonic-gate 
50777c478bd9Sstevel@tonic-gate 		for (len = 0; len < objp->array_len;
50787c478bd9Sstevel@tonic-gate 		    len++, resop++, argop++, objp->decode_len++) {
50797c478bd9Sstevel@tonic-gate 			if (!xdr_nfs_resop4_clnt(xdrs, resop, argop)) {
50807c478bd9Sstevel@tonic-gate 				/*
50817c478bd9Sstevel@tonic-gate 				 * Make sure to free anything that may
50827c478bd9Sstevel@tonic-gate 				 * have been allocated along the way.
50837c478bd9Sstevel@tonic-gate 				 */
50847c478bd9Sstevel@tonic-gate 				xdrs->x_op = XDR_FREE;
50857c478bd9Sstevel@tonic-gate 				(void) xdr_nfs_resop4_free(xdrs, &objp->array,
50867c478bd9Sstevel@tonic-gate 				    objp->array_len,
50877c478bd9Sstevel@tonic-gate 				    objp->decode_len);
50887c478bd9Sstevel@tonic-gate 				return (FALSE);
50897c478bd9Sstevel@tonic-gate 			}
50907c478bd9Sstevel@tonic-gate 		}
50917c478bd9Sstevel@tonic-gate 		return (TRUE);
50927c478bd9Sstevel@tonic-gate 	}
50937c478bd9Sstevel@tonic-gate 	return (xdr_nfs_resop4_free(xdrs, &objp->array,
50947c478bd9Sstevel@tonic-gate 	    objp->array_len, objp->decode_len));
50957c478bd9Sstevel@tonic-gate }
50967c478bd9Sstevel@tonic-gate 
50977c478bd9Sstevel@tonic-gate bool_t
50987c46fb7fSek110237 xdr_COMPOUND4res_srv(XDR *xdrs, COMPOUND4res *objp)
50997c478bd9Sstevel@tonic-gate {
51007c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
51017c478bd9Sstevel@tonic-gate 		return (FALSE);
51027c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
51037c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->tag.utf8string_len,
51047c478bd9Sstevel@tonic-gate 	    NFS4_MAX_UTF8STRING))
51057c478bd9Sstevel@tonic-gate 		return (FALSE);
51067c478bd9Sstevel@tonic-gate 
51077c478bd9Sstevel@tonic-gate 	if (xdrs->x_op != XDR_FREE)
51087c478bd9Sstevel@tonic-gate 		return (xdr_array(xdrs, (char **)&objp->array,
51097c478bd9Sstevel@tonic-gate 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
51107c46fb7fSek110237 		    sizeof (nfs_resop4), (xdrproc_t)xdr_snfs_resop4));
51117c478bd9Sstevel@tonic-gate 
51127c46fb7fSek110237 	return (xdr_snfs_resop4_free(xdrs, &objp->array,
51137c478bd9Sstevel@tonic-gate 	    objp->array_len, objp->array_len));
51147c478bd9Sstevel@tonic-gate }
51157c478bd9Sstevel@tonic-gate 
5116eac3aab7Srobinson /*
5117eac3aab7Srobinson  * NFS server side callback, initiating the callback request so it
5118eac3aab7Srobinson  * is the RPC client. Must convert from server's internal filehandle
5119eac3aab7Srobinson  * format to wire format.
5120eac3aab7Srobinson  */
51217c478bd9Sstevel@tonic-gate static bool_t
5122eac3aab7Srobinson xdr_snfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
51237c478bd9Sstevel@tonic-gate {
5124eac3aab7Srobinson 	CB_GETATTR4args *gargs;
5125eac3aab7Srobinson 	CB_RECALL4args *rargs;
5126eac3aab7Srobinson 
5127eac3aab7Srobinson 	ASSERT(xdrs->x_op == XDR_ENCODE);
5128eac3aab7Srobinson 
5129eac3aab7Srobinson 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->argop))
5130eac3aab7Srobinson 		return (FALSE);
5131eac3aab7Srobinson 
5132eac3aab7Srobinson 	switch (objp->argop) {
5133eac3aab7Srobinson 	case OP_CB_GETATTR:
5134eac3aab7Srobinson 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
5135eac3aab7Srobinson 
5136eac3aab7Srobinson 		if (!xdr_encode_nfs_fh4(xdrs, &gargs->fh))
5137eac3aab7Srobinson 			return (FALSE);
5138eac3aab7Srobinson 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
5139eac3aab7Srobinson 	case OP_CB_RECALL:
5140eac3aab7Srobinson 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
5141eac3aab7Srobinson 
5142eac3aab7Srobinson 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->stateid.seqid))
5143eac3aab7Srobinson 			return (FALSE);
5144bbe876c0SMarcel Telka 		if (!xdr_opaque(xdrs, rargs->stateid.other, NFS4_OTHER_SIZE))
5145eac3aab7Srobinson 			return (FALSE);
5146eac3aab7Srobinson 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->truncate))
5147eac3aab7Srobinson 			return (FALSE);
5148eac3aab7Srobinson 		return (xdr_encode_nfs_fh4(xdrs, &rargs->fh));
5149eac3aab7Srobinson 	case OP_CB_ILLEGAL:
5150eac3aab7Srobinson 		return (TRUE);
5151eac3aab7Srobinson 	}
5152eac3aab7Srobinson 	return (FALSE);
5153eac3aab7Srobinson }
5154eac3aab7Srobinson 
5155eac3aab7Srobinson /*
5156eac3aab7Srobinson  * NFS client side callback, receiving the callback request so it
5157eac3aab7Srobinson  * is the RPC server. Must treat the file handles as opaque.
5158eac3aab7Srobinson  */
5159eac3aab7Srobinson static bool_t
5160eac3aab7Srobinson xdr_cnfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
5161eac3aab7Srobinson {
5162eac3aab7Srobinson 	CB_GETATTR4args *gargs;
5163eac3aab7Srobinson 	CB_RECALL4args *rargs;
5164eac3aab7Srobinson 
5165eac3aab7Srobinson 	ASSERT(xdrs->x_op != XDR_ENCODE);
5166eac3aab7Srobinson 
51677c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->argop))
51687c478bd9Sstevel@tonic-gate 		return (FALSE);
51697c478bd9Sstevel@tonic-gate 	switch (objp->argop) {
51707c478bd9Sstevel@tonic-gate 	case OP_CB_GETATTR:
5171eac3aab7Srobinson 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
5172eac3aab7Srobinson 
5173eac3aab7Srobinson 		if (!xdr_bytes(xdrs, (char **)&gargs->fh.nfs_fh4_val,
5174eac3aab7Srobinson 		    (uint_t *)&gargs->fh.nfs_fh4_len, NFS4_FHSIZE))
51757c478bd9Sstevel@tonic-gate 			return (FALSE);
5176eac3aab7Srobinson 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
51777c478bd9Sstevel@tonic-gate 	case OP_CB_RECALL:
5178eac3aab7Srobinson 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
5179eac3aab7Srobinson 
5180eac3aab7Srobinson 		if (!xdr_u_int(xdrs, &rargs->stateid.seqid))
51817c478bd9Sstevel@tonic-gate 			return (FALSE);
5182bbe876c0SMarcel Telka 		if (!xdr_opaque(xdrs, rargs->stateid.other, NFS4_OTHER_SIZE))
51837c478bd9Sstevel@tonic-gate 			return (FALSE);
5184eac3aab7Srobinson 		if (!xdr_bool(xdrs, &rargs->truncate))
51857c478bd9Sstevel@tonic-gate 			return (FALSE);
5186eac3aab7Srobinson 		return (xdr_bytes(xdrs, (char **)&rargs->fh.nfs_fh4_val,
5187eac3aab7Srobinson 		    (uint_t *)&rargs->fh.nfs_fh4_len, NFS4_FHSIZE));
51887c478bd9Sstevel@tonic-gate 	case OP_CB_ILLEGAL:
51897c478bd9Sstevel@tonic-gate 		return (TRUE);
51907c478bd9Sstevel@tonic-gate 	}
51917c478bd9Sstevel@tonic-gate 	return (FALSE);
51927c478bd9Sstevel@tonic-gate }
51937c478bd9Sstevel@tonic-gate 
51947c478bd9Sstevel@tonic-gate static bool_t
51957c478bd9Sstevel@tonic-gate xdr_nfs_cb_resop4(XDR *xdrs, nfs_cb_resop4 *objp)
51967c478bd9Sstevel@tonic-gate {
51977c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->resop))
51987c478bd9Sstevel@tonic-gate 		return (FALSE);
51997c478bd9Sstevel@tonic-gate 	switch (objp->resop) {
52007c478bd9Sstevel@tonic-gate 	case OP_CB_GETATTR:
52017c478bd9Sstevel@tonic-gate 		if (!xdr_int(xdrs,
52027c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbgetattr.
52037c478bd9Sstevel@tonic-gate 		    status))
52047c478bd9Sstevel@tonic-gate 			return (FALSE);
52057c478bd9Sstevel@tonic-gate 		if (objp->nfs_cb_resop4_u.opcbgetattr.status != NFS4_OK)
52067c478bd9Sstevel@tonic-gate 			return (TRUE);
52077c478bd9Sstevel@tonic-gate 		return (xdr_fattr4(xdrs,
52087c478bd9Sstevel@tonic-gate 		    &objp->nfs_cb_resop4_u.opcbgetattr.
52097c478bd9Sstevel@tonic-gate 		    obj_attributes));
52107c478bd9Sstevel@tonic-gate 	case OP_CB_RECALL:
52117c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
52127c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbrecall.status));
52137c478bd9Sstevel@tonic-gate 	case OP_CB_ILLEGAL:
52147c478bd9Sstevel@tonic-gate 		return (xdr_int(xdrs,
52157c478bd9Sstevel@tonic-gate 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbillegal.status));
52167c478bd9Sstevel@tonic-gate 	}
52177c478bd9Sstevel@tonic-gate 	return (FALSE);
52187c478bd9Sstevel@tonic-gate }
52197c478bd9Sstevel@tonic-gate 
5220eac3aab7Srobinson /*
5221eac3aab7Srobinson  * The NFS client side callback, RPC server
5222eac3aab7Srobinson  */
52237c478bd9Sstevel@tonic-gate bool_t
5224eac3aab7Srobinson xdr_CB_COMPOUND4args_clnt(XDR *xdrs, CB_COMPOUND4args *objp)
52257c478bd9Sstevel@tonic-gate {
52267c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
52277c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->tag.utf8string_len,
52287c478bd9Sstevel@tonic-gate 	    NFS4_MAX_UTF8STRING))
52297c478bd9Sstevel@tonic-gate 		return (FALSE);
52307c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->minorversion))
52317c478bd9Sstevel@tonic-gate 		return (FALSE);
52327c478bd9Sstevel@tonic-gate 	if (!xdr_u_int(xdrs, &objp->callback_ident))
52337c478bd9Sstevel@tonic-gate 		return (FALSE);
52347c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->array,
52357c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5236eac3aab7Srobinson 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_cnfs_cb_argop4));
5237eac3aab7Srobinson }
5238eac3aab7Srobinson 
5239eac3aab7Srobinson /*
5240eac3aab7Srobinson  * The NFS server side callback, RPC client
5241eac3aab7Srobinson  */
5242eac3aab7Srobinson bool_t
5243eac3aab7Srobinson xdr_CB_COMPOUND4args_srv(XDR *xdrs, CB_COMPOUND4args *objp)
5244eac3aab7Srobinson {
5245eac3aab7Srobinson 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
5246eac3aab7Srobinson 	    (uint_t *)&objp->tag.utf8string_len,
5247eac3aab7Srobinson 	    NFS4_MAX_UTF8STRING))
5248eac3aab7Srobinson 		return (FALSE);
5249eac3aab7Srobinson 	if (!xdr_u_int(xdrs, &objp->minorversion))
5250eac3aab7Srobinson 		return (FALSE);
5251eac3aab7Srobinson 	if (!xdr_u_int(xdrs, &objp->callback_ident))
5252eac3aab7Srobinson 		return (FALSE);
5253eac3aab7Srobinson 	return (xdr_array(xdrs, (char **)&objp->array,
5254eac3aab7Srobinson 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5255eac3aab7Srobinson 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_snfs_cb_argop4));
52567c478bd9Sstevel@tonic-gate }
52577c478bd9Sstevel@tonic-gate 
52587c478bd9Sstevel@tonic-gate bool_t
52597c478bd9Sstevel@tonic-gate xdr_CB_COMPOUND4res(XDR *xdrs, CB_COMPOUND4res *objp)
52607c478bd9Sstevel@tonic-gate {
52617c478bd9Sstevel@tonic-gate 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
52627c478bd9Sstevel@tonic-gate 		return (FALSE);
52637c478bd9Sstevel@tonic-gate 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
52647c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->tag.utf8string_len,
52657c478bd9Sstevel@tonic-gate 	    NFS4_MAX_UTF8STRING))
52667c478bd9Sstevel@tonic-gate 		return (FALSE);
52677c478bd9Sstevel@tonic-gate 	return (xdr_array(xdrs, (char **)&objp->array,
52687c478bd9Sstevel@tonic-gate 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
52697c478bd9Sstevel@tonic-gate 	    sizeof (nfs_cb_resop4), (xdrproc_t)xdr_nfs_cb_resop4));
52707c478bd9Sstevel@tonic-gate }
5271