xref: /illumos-gate/usr/src/uts/common/fs/nfs/nfs4_xdr.c (revision 297b4d80)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
27  */
28 
29 /*
30  * A handcoded version based on the original rpcgen code.
31  *
32  * Note: All future NFS4 protocol changes should be added by hand
33  * to this file.
34  *
35  * CAUTION: All protocol changes must also be propagated to:
36  *     usr/src/cmd/cmd-inet/usr.sbin/snoop/nfs4_xdr.c
37  */
38 
39 #include <sys/types.h>
40 #include <sys/sunddi.h>
41 #include <sys/dnlc.h>
42 #include <nfs/nfs.h>
43 #include <nfs/nfs4_kprot.h>
44 #include <nfs/rnode4.h>
45 #include <nfs/nfs4.h>
46 #include <nfs/nfs4_clnt.h>
47 #include <sys/sdt.h>
48 #include <sys/mkdev.h>
49 #include <rpc/rpc_rdma.h>
50 #include <rpc/xdr.h>
51 
52 #define	xdr_dev_t xdr_u_int
53 
54 extern bool_t xdr_netbuf(XDR *, struct netbuf *);
55 extern bool_t xdr_vector(XDR *, char *, const uint_t, const uint_t,
56 	const xdrproc_t);
57 bool_t xdr_knetconfig(XDR *, struct knetconfig *);
58 
59 bool_t
60 xdr_bitmap4(XDR *xdrs, bitmap4 *objp)
61 {
62 	int32_t len, size;
63 
64 	if (xdrs->x_op == XDR_FREE)
65 		return (TRUE);
66 
67 	/*
68 	 * Simplified bitmap4 processing, always encode from uint64_t
69 	 * to 2 uint32_t's, always decode first 2 uint32_t's into a
70 	 * uint64_t and ignore all of the rest.
71 	 */
72 	if (xdrs->x_op == XDR_ENCODE) {
73 		len = 2;
74 
75 		if (!XDR_PUTINT32(xdrs, &len))
76 			return (FALSE);
77 
78 #if defined(_LITTLE_ENDIAN)
79 		if (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
80 		    BYTES_PER_XDR_UNIT)) == TRUE) {
81 			return (XDR_PUTINT32(xdrs, (int32_t *)objp));
82 		}
83 #elif defined(_BIG_ENDIAN)
84 		if (XDR_PUTINT32(xdrs, (int32_t *)objp) == TRUE) {
85 			return (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
86 			    BYTES_PER_XDR_UNIT)));
87 		}
88 #endif
89 		return (FALSE);
90 	}
91 
92 	if (!XDR_GETINT32(xdrs, &len))
93 		return (FALSE);
94 
95 	/*
96 	 * Common fast DECODE cases
97 	 */
98 	if (len == 2) {
99 #if defined(_LITTLE_ENDIAN)
100 		if (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
101 		    BYTES_PER_XDR_UNIT)) == TRUE) {
102 			return (XDR_GETINT32(xdrs, (int32_t *)objp));
103 		}
104 #elif defined(_BIG_ENDIAN)
105 		if (XDR_GETINT32(xdrs, (int32_t *)objp) == TRUE) {
106 			return (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
107 			    BYTES_PER_XDR_UNIT)));
108 		}
109 #endif
110 		return (FALSE);
111 	}
112 
113 	*objp = 0;
114 	if (len == 0)
115 		return (TRUE);
116 
117 	/*
118 	 * The not so common DECODE cases, len == 1 || len > 2
119 	 */
120 #if defined(_LITTLE_ENDIAN)
121 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
122 		return (FALSE);
123 	if (--len == 0)
124 		return (TRUE);
125 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
126 		return (FALSE);
127 #elif defined(_BIG_ENDIAN)
128 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
129 		return (FALSE);
130 	if (--len == 0)
131 		return (TRUE);
132 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
133 		return (FALSE);
134 #else
135 	return (FALSE);
136 #endif
137 
138 	if (--len == 0)
139 		return (TRUE);
140 
141 	size = len * BYTES_PER_XDR_UNIT;
142 	return (XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size));
143 }
144 
145 /* Called by xdr_array, nfsid_map_xdr */
146 bool_t
147 xdr_utf8string(XDR *xdrs, utf8string *objp)
148 {
149 	if (xdrs->x_op != XDR_FREE)
150 		return (xdr_bytes(xdrs, (char **)&objp->utf8string_val,
151 		    (uint_t *)&objp->utf8string_len, NFS4_MAX_UTF8STRING));
152 
153 	if (objp->utf8string_val != NULL) {
154 		kmem_free(objp->utf8string_val, objp->utf8string_len);
155 		objp->utf8string_val = NULL;
156 	}
157 	return (TRUE);
158 }
159 
160 /*
161  * used by NFSv4 referrals to get info needed for NFSv4 referral mount.
162  */
163 bool_t
164 xdr_nfs_fsl_info(XDR *xdrs, struct nfs_fsl_info *objp)
165 {
166 
167 	if (!xdr_u_int(xdrs, &objp->netbuf_len))
168 		return (FALSE);
169 	if (!xdr_u_int(xdrs, &objp->netnm_len))
170 		return (FALSE);
171 	if (!xdr_u_int(xdrs, &objp->knconf_len))
172 		return (FALSE);
173 
174 #if defined(_LP64)
175 	/*
176 	 * The object can come from a 32-bit binary; nfsmapid.
177 	 * To be safe we double the size of the knetconfig to
178 	 * allow some buffering for decoding.
179 	 */
180 	if (xdrs->x_op == XDR_DECODE)
181 		objp->knconf_len += sizeof (struct knetconfig);
182 #endif
183 
184 	if (!xdr_string(xdrs, &objp->netname, ~0))
185 		return (FALSE);
186 	if (!xdr_pointer(xdrs, (char **)&objp->addr, objp->netbuf_len,
187 	    (xdrproc_t)xdr_netbuf))
188 		return (FALSE);
189 	if (!xdr_pointer(xdrs, (char **)&objp->knconf,
190 	    objp->knconf_len, (xdrproc_t)xdr_knetconfig))
191 		return (FALSE);
192 	return (TRUE);
193 }
194 
195 bool_t
196 xdr_knetconfig(XDR *xdrs, struct knetconfig *objp)
197 {
198 	rpc_inline_t *buf;
199 	u_longlong_t dev64;
200 #if !defined(_LP64)
201 	uint32_t major, minor;
202 #endif
203 	int i;
204 
205 	if (!xdr_u_int(xdrs, &objp->knc_semantics))
206 		return (FALSE);
207 	if (xdrs->x_op == XDR_DECODE) {
208 		objp->knc_protofmly = (((char *)objp) +
209 		    sizeof (struct knetconfig));
210 		objp->knc_proto = objp->knc_protofmly + KNC_STRSIZE;
211 	}
212 	if (!xdr_opaque(xdrs, objp->knc_protofmly, KNC_STRSIZE))
213 		return (FALSE);
214 	if (!xdr_opaque(xdrs, objp->knc_proto, KNC_STRSIZE))
215 		return (FALSE);
216 
217 	/*
218 	 * For interoperability between 32-bit daemon and 64-bit kernel,
219 	 * we always treat dev_t as 64-bit number and do the expanding
220 	 * or compression of dev_t as needed.
221 	 * We have to hand craft the conversion since there is no available
222 	 * function in ddi.c. Besides ddi.c is available only in the kernel
223 	 * and we want to keep both user and kernel of xdr_knetconfig() the
224 	 * same for consistency.
225 	 */
226 	if (xdrs->x_op == XDR_ENCODE) {
227 #if defined(_LP64)
228 		dev64 = objp->knc_rdev;
229 #else
230 		major = (objp->knc_rdev >> NBITSMINOR32) & MAXMAJ32;
231 		minor = objp->knc_rdev & MAXMIN32;
232 		dev64 = (((unsigned long long)major) << NBITSMINOR64) | minor;
233 #endif
234 		if (!xdr_u_longlong_t(xdrs, &dev64))
235 			return (FALSE);
236 	}
237 	if (xdrs->x_op == XDR_DECODE) {
238 #if defined(_LP64)
239 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->knc_rdev))
240 			return (FALSE);
241 #else
242 		if (!xdr_u_longlong_t(xdrs, &dev64))
243 			return (FALSE);
244 
245 		major = (dev64 >> NBITSMINOR64) & L_MAXMAJ32;
246 		minor = dev64 & L_MAXMIN32;
247 		objp->knc_rdev = (major << L_BITSMINOR32) | minor;
248 #endif
249 	}
250 
251 	if (xdrs->x_op == XDR_ENCODE) {
252 		buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT);
253 		if (buf == NULL) {
254 			if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
255 			    sizeof (uint_t), (xdrproc_t)xdr_u_int))
256 				return (FALSE);
257 		} else {
258 			uint_t *genp;
259 
260 			for (i = 0, genp = objp->knc_unused;
261 			    i < 8; i++) {
262 #if defined(_LP64) || defined(_KERNEL)
263 				IXDR_PUT_U_INT32(buf, *genp++);
264 #else
265 				IXDR_PUT_U_LONG(buf, *genp++);
266 #endif
267 			}
268 		}
269 		return (TRUE);
270 	} else if (xdrs->x_op == XDR_DECODE) {
271 		buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT);
272 		if (buf == NULL) {
273 			if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
274 			    sizeof (uint_t), (xdrproc_t)xdr_u_int))
275 				return (FALSE);
276 		} else {
277 			uint_t *genp;
278 
279 			for (i = 0, genp = objp->knc_unused;
280 			    i < 8; i++) {
281 #if defined(_LP64) || defined(_KERNEL)
282 					*genp++ = IXDR_GET_U_INT32(buf);
283 #else
284 					*genp++ = IXDR_GET_U_LONG(buf);
285 #endif
286 			}
287 		}
288 		return (TRUE);
289 	}
290 
291 	if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8,
292 	    sizeof (uint_t), (xdrproc_t)xdr_u_int))
293 		return (FALSE);
294 	return (TRUE);
295 }
296 
297 /*
298  * XDR_INLINE decode a filehandle.
299  */
300 bool_t
301 xdr_inline_decode_nfs_fh4(uint32_t *ptr, nfs_fh4_fmt_t *fhp, uint32_t fhsize)
302 {
303 	uchar_t *bp = (uchar_t *)ptr;
304 	uchar_t *cp;
305 	uint32_t dsize;
306 	uintptr_t resid;
307 
308 	/*
309 	 * Check to see if what the client sent us is bigger or smaller
310 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
311 	 * unfortunately badly named as it is no longer the max and is
312 	 * really the min of what is sent over the wire.
313 	 */
314 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
315 	    sizeof (ushort_t) + NFS_FHMAXDATA +
316 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
317 		return (FALSE);
318 	}
319 
320 	/*
321 	 * All internal parts of a filehandle are in native byte order.
322 	 *
323 	 * Decode what should be fh4_fsid, it is aligned.
324 	 */
325 	fhp->fh4_fsid.val[0] = *(uint32_t *)bp;
326 	bp += BYTES_PER_XDR_UNIT;
327 	fhp->fh4_fsid.val[1] = *(uint32_t *)bp;
328 	bp += BYTES_PER_XDR_UNIT;
329 
330 	/*
331 	 * Decode what should be fh4_len.  fh4_len is two bytes, so we're
332 	 * unaligned now.
333 	 */
334 	cp = (uchar_t *)&fhp->fh4_len;
335 	*cp++ = *bp++;
336 	*cp++ = *bp++;
337 	fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
338 
339 	/*
340 	 * For backwards compatibility, the fid length may be less than
341 	 * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
342 	 */
343 	dsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
344 
345 	/*
346 	 * Make sure the client isn't sending us a bogus length for fh4_data.
347 	 */
348 	if (fhsize < dsize)
349 		return (FALSE);
350 	bcopy(bp, fhp->fh4_data, dsize);
351 	bp += dsize;
352 	fhsize -= dsize;
353 
354 	if (fhsize < sizeof (ushort_t))
355 		return (FALSE);
356 	cp = (uchar_t *)&fhp->fh4_xlen;
357 	*cp++ = *bp++;
358 	*cp++ = *bp++;
359 	fhsize -= sizeof (ushort_t);
360 
361 	dsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
362 
363 	/*
364 	 * Make sure the client isn't sending us a bogus length for fh4_xdata.
365 	 */
366 	if (fhsize < dsize)
367 		return (FALSE);
368 	bcopy(bp, fhp->fh4_xdata, dsize);
369 	fhsize -= dsize;
370 	bp += dsize;
371 
372 	/*
373 	 * We realign things on purpose, so skip any padding
374 	 */
375 	resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
376 	if (resid != 0) {
377 		if (fhsize < (BYTES_PER_XDR_UNIT - resid))
378 			return (FALSE);
379 		bp += BYTES_PER_XDR_UNIT - resid;
380 		fhsize -= BYTES_PER_XDR_UNIT - resid;
381 	}
382 
383 	if (fhsize < BYTES_PER_XDR_UNIT)
384 		return (FALSE);
385 	fhp->fh4_flag = *(uint32_t *)bp;
386 	bp += BYTES_PER_XDR_UNIT;
387 	fhsize -= BYTES_PER_XDR_UNIT;
388 
389 #ifdef VOLATILE_FH_TEST
390 	if (fhsize < BYTES_PER_XDR_UNIT)
391 		return (FALSE);
392 	fhp->fh4_volatile_id = *(uint32_t *)bp;
393 	bp += BYTES_PER_XDR_UNIT;
394 	fhsize -= BYTES_PER_XDR_UNIT;
395 #endif
396 	/*
397 	 * Make sure client didn't send extra bytes
398 	 */
399 	if (fhsize != 0)
400 		return (FALSE);
401 	return (TRUE);
402 }
403 
404 static bool_t
405 xdr_decode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
406 {
407 	uint32_t fhsize;		/* filehandle size */
408 	uint32_t bufsize;
409 	rpc_inline_t *ptr;
410 	uchar_t *bp;
411 
412 	ASSERT(xdrs->x_op == XDR_DECODE);
413 
414 	/*
415 	 * Retrieve the filehandle length.
416 	 */
417 	if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
418 		return (FALSE);
419 
420 	objp->nfs_fh4_val = NULL;
421 	objp->nfs_fh4_len = 0;
422 
423 	/*
424 	 * Check to see if what the client sent us is bigger or smaller
425 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
426 	 * unfortunately badly named as it is no longer the max and is
427 	 * really the min of what is sent over the wire.
428 	 */
429 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
430 	    sizeof (ushort_t) + NFS_FHMAXDATA +
431 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
432 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
433 			return (FALSE);
434 		return (TRUE);
435 	}
436 
437 	/*
438 	 * bring in fhsize plus any padding
439 	 */
440 	bufsize = RNDUP(fhsize);
441 	ptr = XDR_INLINE(xdrs, bufsize);
442 	bp = (uchar_t *)ptr;
443 	if (ptr == NULL) {
444 		bp = kmem_alloc(bufsize, KM_SLEEP);
445 		if (!xdr_opaque(xdrs, (char *)bp, bufsize)) {
446 			kmem_free(bp, bufsize);
447 			return (FALSE);
448 		}
449 	}
450 
451 	objp->nfs_fh4_val = kmem_zalloc(sizeof (nfs_fh4_fmt_t), KM_SLEEP);
452 	objp->nfs_fh4_len = sizeof (nfs_fh4_fmt_t);
453 
454 	if (xdr_inline_decode_nfs_fh4((uint32_t *)bp,
455 	    (nfs_fh4_fmt_t *)objp->nfs_fh4_val, fhsize) == FALSE) {
456 		/*
457 		 * If in the process of decoding we find the file handle
458 		 * is not correctly formed, we need to continue decoding
459 		 * and trigger an NFS layer error. Set the nfs_fh4_len to
460 		 * zero so it gets caught as a bad length.
461 		 */
462 		kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
463 		objp->nfs_fh4_val = NULL;
464 		objp->nfs_fh4_len = 0;
465 	}
466 
467 	if (ptr == NULL)
468 		kmem_free(bp, bufsize);
469 	return (TRUE);
470 }
471 
472 /*
473  * XDR_INLINE encode a filehandle.
474  */
475 bool_t
476 xdr_inline_encode_nfs_fh4(uint32_t **ptrp, uint32_t *ptr_redzone,
477 	nfs_fh4_fmt_t *fhp)
478 {
479 	uint32_t *ptr = *ptrp;
480 	uchar_t *cp;
481 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
482 	uint32_t padword;
483 
484 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
485 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
486 
487 	/*
488 	 * First get the initial and variable sized part of the filehandle.
489 	 */
490 	otw_len = sizeof (fhp->fh4_fsid) +
491 	    sizeof (fhp->fh4_len) + fsize +
492 	    sizeof (fhp->fh4_xlen) + xsize;
493 
494 	/*
495 	 * Round out to a full word.
496 	 */
497 	otw_len = RNDUP(otw_len);
498 	padword = (otw_len / BYTES_PER_XDR_UNIT);	/* includes fhlen */
499 
500 	/*
501 	 * Add in the fixed sized pieces.
502 	 */
503 	otw_len += sizeof (fhp->fh4_flag);
504 #ifdef VOLATILE_FH_TEST
505 	otw_len += sizeof (fhp->fh4_volatile_id);
506 #endif
507 
508 	/*
509 	 * Make sure we don't exceed our buffer.
510 	 */
511 	if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone)
512 		return (FALSE);
513 
514 	/*
515 	 * Zero out the padding.
516 	 */
517 	ptr[padword] = 0;
518 
519 	IXDR_PUT_U_INT32(ptr, otw_len);
520 
521 	/*
522 	 * The rest of the filehandle is in native byteorder
523 	 */
524 	/* fh4_fsid */
525 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[0];
526 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[1];
527 
528 	/*
529 	 * Since the next pieces are unaligned, we need to
530 	 * do bytewise copies.
531 	 */
532 	cp = (uchar_t *)ptr;
533 
534 	/* fh4_len + fh4_data */
535 	bcopy(&fhp->fh4_len, cp, sizeof (fhp->fh4_len) + fsize);
536 	cp += sizeof (fhp->fh4_len) + fsize;
537 
538 	/* fh4_xlen + fh4_xdata */
539 	bcopy(&fhp->fh4_xlen, cp, sizeof (fhp->fh4_xlen) + xsize);
540 	cp += sizeof (fhp->fh4_xlen) + xsize;
541 
542 	/* do necessary rounding/padding */
543 	cp = (uchar_t *)RNDUP((uintptr_t)cp);
544 	ptr = (uint32_t *)cp;
545 
546 	/*
547 	 * With the above padding, we're word aligned again.
548 	 */
549 	ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0);
550 
551 	/* fh4_flag */
552 	*ptr++ = (uint32_t)fhp->fh4_flag;
553 
554 #ifdef VOLATILE_FH_TEST
555 	/* fh4_volatile_id */
556 	*ptr++ = (uint32_t)fhp->fh4_volatile_id;
557 #endif
558 	*ptrp = ptr;
559 
560 	return (TRUE);
561 }
562 
563 static bool_t
564 xdr_encode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
565 {
566 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
567 	bool_t ret;
568 	rpc_inline_t *ptr;
569 	rpc_inline_t *buf = NULL;
570 	uint32_t *ptr_redzone;
571 	nfs_fh4_fmt_t *fhp;
572 
573 	ASSERT(xdrs->x_op == XDR_ENCODE);
574 
575 	fhp = (nfs_fh4_fmt_t *)objp->nfs_fh4_val;
576 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
577 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
578 
579 	/*
580 	 * First get the over the wire size, it is the 4 bytes
581 	 * for the length, plus the combined size of the
582 	 * file handle components.
583 	 */
584 	otw_len = BYTES_PER_XDR_UNIT + sizeof (fhp->fh4_fsid) +
585 	    sizeof (fhp->fh4_len) + fsize +
586 	    sizeof (fhp->fh4_xlen) + xsize +
587 	    sizeof (fhp->fh4_flag);
588 #ifdef VOLATILE_FH_TEST
589 	otw_len += sizeof (fhp->fh4_volatile_id);
590 #endif
591 	/*
592 	 * Round out to a full word.
593 	 */
594 	otw_len = RNDUP(otw_len);
595 
596 	/*
597 	 * Next try to inline the XDR stream, if that fails (rare)
598 	 * allocate a buffer to encode the file handle and then
599 	 * copy it using xdr_opaque and free the buffer.
600 	 */
601 	ptr = XDR_INLINE(xdrs, otw_len);
602 	if (ptr == NULL)
603 		ptr = buf = kmem_alloc(otw_len, KM_SLEEP);
604 
605 	ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT));
606 	ret = xdr_inline_encode_nfs_fh4((uint32_t **)&ptr, ptr_redzone, fhp);
607 
608 	if (buf != NULL) {
609 		if (ret == TRUE)
610 			ret = xdr_opaque(xdrs, (char *)buf, otw_len);
611 		kmem_free(buf, otw_len);
612 	}
613 	return (ret);
614 }
615 
616 /*
617  * XDR a NFSv4 filehandle.
618  * Encoding interprets the contents (server).
619  * Decoding the contents are opaque (client).
620  */
621 bool_t
622 xdr_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
623 {
624 	switch (xdrs->x_op) {
625 	case XDR_ENCODE:
626 		return (xdr_encode_nfs_fh4(xdrs, objp));
627 	case XDR_DECODE:
628 		return (xdr_bytes(xdrs, (char **)&objp->nfs_fh4_val,
629 		    (uint_t *)&objp->nfs_fh4_len, NFS4_FHSIZE));
630 	case XDR_FREE:
631 		if (objp->nfs_fh4_val != NULL) {
632 			kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
633 			objp->nfs_fh4_val = NULL;
634 		}
635 		return (TRUE);
636 	}
637 	return (FALSE);
638 }
639 
640 /* Called by xdr_array */
641 static bool_t
642 xdr_fs_location4(XDR *xdrs, fs_location4 *objp)
643 {
644 	if (xdrs->x_op == XDR_DECODE) {
645 		objp->server_val = NULL;
646 		objp->rootpath.pathname4_val = NULL;
647 	}
648 	if (!xdr_array(xdrs, (char **)&objp->server_val,
649 	    (uint_t *)&objp->server_len, NFS4_MAX_UTF8STRING,
650 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
651 		return (FALSE);
652 	return (xdr_array(xdrs, (char **)&objp->rootpath.pathname4_val,
653 	    (uint_t *)&objp->rootpath.pathname4_len,
654 	    NFS4_MAX_PATHNAME4,
655 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string));
656 }
657 
658 /* Called by xdr_array */
659 static bool_t
660 xdr_nfsace4(XDR *xdrs, nfsace4 *objp)
661 {
662 	if (xdrs->x_op != XDR_FREE) {
663 		if (!xdr_u_int(xdrs, &objp->type))
664 			return (FALSE);
665 		if (!xdr_u_int(xdrs, &objp->flag))
666 			return (FALSE);
667 		if (!xdr_u_int(xdrs, &objp->access_mask))
668 			return (FALSE);
669 
670 		if (xdrs->x_op == XDR_DECODE) {
671 			objp->who.utf8string_val = NULL;
672 			objp->who.utf8string_len = 0;
673 		}
674 
675 		return (xdr_bytes(xdrs, (char **)&objp->who.utf8string_val,
676 		    (uint_t *)&objp->who.utf8string_len,
677 		    NFS4_MAX_UTF8STRING));
678 	}
679 
680 	/*
681 	 * Optimized free case
682 	 */
683 	if (objp->who.utf8string_val != NULL) {
684 		kmem_free(objp->who.utf8string_val, objp->who.utf8string_len);
685 		objp->who.utf8string_val = NULL;
686 	}
687 	return (TRUE);
688 }
689 
690 /*
691  * These functions are called out of nfs4_attr.c
692  */
693 bool_t
694 xdr_fattr4_fsid(XDR *xdrs, fattr4_fsid *objp)
695 {
696 	if (xdrs->x_op == XDR_FREE)
697 		return (TRUE);
698 
699 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->major))
700 		return (FALSE);
701 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->minor));
702 }
703 
704 
705 bool_t
706 xdr_fattr4_acl(XDR *xdrs, fattr4_acl *objp)
707 {
708 	return (xdr_array(xdrs, (char **)&objp->fattr4_acl_val,
709 	    (uint_t *)&objp->fattr4_acl_len, NFS4_ACL_LIMIT,
710 	    sizeof (nfsace4), (xdrproc_t)xdr_nfsace4));
711 }
712 
713 bool_t
714 xdr_fattr4_fs_locations(XDR *xdrs, fattr4_fs_locations *objp)
715 {
716 	if (xdrs->x_op == XDR_DECODE) {
717 		objp->fs_root.pathname4_len = 0;
718 		objp->fs_root.pathname4_val = NULL;
719 		objp->locations_val = NULL;
720 	}
721 	if (!xdr_array(xdrs, (char **)&objp->fs_root.pathname4_val,
722 	    (uint_t *)&objp->fs_root.pathname4_len,
723 	    NFS4_MAX_PATHNAME4,
724 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
725 		return (FALSE);
726 	return (xdr_array(xdrs, (char **)&objp->locations_val,
727 	    (uint_t *)&objp->locations_len, NFS4_FS_LOCATIONS_LIMIT,
728 	    sizeof (fs_location4), (xdrproc_t)xdr_fs_location4));
729 }
730 
731 bool_t
732 xdr_fattr4_rawdev(XDR *xdrs, fattr4_rawdev *objp)
733 {
734 	if (xdrs->x_op == XDR_FREE)
735 		return (TRUE);
736 
737 	if (!xdr_u_int(xdrs, &objp->specdata1))
738 		return (FALSE);
739 	return (xdr_u_int(xdrs, &objp->specdata2));
740 }
741 
742 bool_t
743 xdr_nfstime4(XDR *xdrs, nfstime4 *objp)
744 {
745 	if (xdrs->x_op == XDR_FREE)
746 		return (TRUE);
747 
748 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->seconds))
749 		return (FALSE);
750 	return (xdr_u_int(xdrs, &objp->nseconds));
751 }
752 
753 
754 /*
755  * structured used for calls into xdr_ga_fattr_res() as a means
756  * to do an immediate/short-term cache of owner/group strings
757  * for callers like the readdir processing.  In the case of readdir,
758  * it is likely that the directory objects will be owned by the same
759  * owner/group and if so there is no need to call into the uid/gid
760  * mapping code.  While the uid/gid interfaces have their own cache
761  * having one here will reduct pathlength further.
762  */
763 #define	MAX_OG_NAME 100
764 typedef struct ug_cache
765 {
766 	uid_t	uid;
767 	gid_t	gid;
768 	utf8string u_curr, u_last;
769 	utf8string g_curr, g_last;
770 	char	u_buf1[MAX_OG_NAME];
771 	char	u_buf2[MAX_OG_NAME];
772 	char	g_buf1[MAX_OG_NAME];
773 	char	g_buf2[MAX_OG_NAME];
774 } ug_cache_t;
775 
776 #define	U_SWAP_CURR_LAST(ug) \
777 	(ug)->u_last.utf8string_len = (ug)->u_curr.utf8string_len;	\
778 	if ((ug)->u_last.utf8string_val == (ug)->u_buf1) {		\
779 		(ug)->u_last.utf8string_val = (ug)->u_buf2;		\
780 		(ug)->u_curr.utf8string_val = (ug)->u_buf1;		\
781 	} else {							\
782 		(ug)->u_last.utf8string_val = (ug)->u_buf1;		\
783 		(ug)->u_curr.utf8string_val = (ug)->u_buf2;		\
784 	}
785 
786 #define	G_SWAP_CURR_LAST(ug) \
787 	(ug)->g_last.utf8string_len = (ug)->g_curr.utf8string_len;	\
788 	if ((ug)->g_last.utf8string_val == (ug)->g_buf1) {		\
789 		(ug)->g_last.utf8string_val = (ug)->g_buf2;		\
790 		(ug)->g_curr.utf8string_val = (ug)->g_buf1;		\
791 	} else {							\
792 		(ug)->g_last.utf8string_val = (ug)->g_buf1;		\
793 		(ug)->g_curr.utf8string_val = (ug)->g_buf2;		\
794 	}
795 
796 static ug_cache_t *
797 alloc_ugcache()
798 {
799 	ug_cache_t *pug = kmem_alloc(sizeof (ug_cache_t), KM_SLEEP);
800 
801 	pug->uid = pug->gid = 0;
802 	pug->u_curr.utf8string_len = 0;
803 	pug->u_last.utf8string_len = 0;
804 	pug->g_curr.utf8string_len = 0;
805 	pug->g_last.utf8string_len = 0;
806 	pug->u_curr.utf8string_val = pug->u_buf1;
807 	pug->u_last.utf8string_val = pug->u_buf2;
808 	pug->g_curr.utf8string_val = pug->g_buf1;
809 	pug->g_last.utf8string_val = pug->g_buf2;
810 
811 	return (pug);
812 }
813 
814 static void
815 xdr_ga_prefill_vattr(struct nfs4_ga_res *garp, struct mntinfo4 *mi)
816 {
817 	static vattr_t s_vattr = {
818 		AT_ALL,		/* va_mask */
819 		VNON,		/* va_type */
820 		0777,		/* va_mode */
821 		UID_NOBODY,	/* va_uid */
822 		GID_NOBODY,	/* va_gid */
823 		0,		/* va_fsid */
824 		0,		/* va_nodeid */
825 		1,		/* va_nlink */
826 		0,		/* va_size */
827 		{0, 0},		/* va_atime */
828 		{0, 0},		/* va_mtime */
829 		{0, 0},		/* va_ctime */
830 		0,		/* va_rdev */
831 		MAXBSIZE,	/* va_blksize */
832 		0,		/* va_nblocks */
833 		0		/* va_seq */
834 	};
835 
836 
837 	garp->n4g_va = s_vattr;
838 	garp->n4g_va.va_fsid = mi->mi_vfsp->vfs_dev;
839 	hrt2ts(gethrtime(), &garp->n4g_va.va_atime);
840 	garp->n4g_va.va_mtime = garp->n4g_va.va_ctime = garp->n4g_va.va_atime;
841 }
842 
843 static void
844 xdr_ga_prefill_statvfs(struct nfs4_ga_ext_res *gesp, struct mntinfo4 *mi)
845 {
846 	static statvfs64_t s_sb = {
847 		MAXBSIZE,	/* f_bsize */
848 		DEV_BSIZE,	/* f_frsize */
849 		(fsfilcnt64_t)-1, /* f_blocks */
850 		(fsfilcnt64_t)-1, /* f_bfree */
851 		(fsfilcnt64_t)-1, /* f_bavail */
852 		(fsfilcnt64_t)-1, /* f_files */
853 		(fsfilcnt64_t)-1, /* f_ffree */
854 		(fsfilcnt64_t)-1, /* f_favail */
855 		0,		/* f_fsid */
856 		"\0",		/* f_basetype */
857 		0,		/* f_flag */
858 		MAXNAMELEN,	/* f_namemax */
859 		"\0",		/* f_fstr */
860 	};
861 
862 	gesp->n4g_sb = s_sb;
863 	gesp->n4g_sb.f_fsid = mi->mi_vfsp->vfs_fsid.val[0];
864 }
865 
866 static bool_t
867 xdr_ga_fattr_res(XDR *xdrs, struct nfs4_ga_res *garp, bitmap4 resbmap,
868 		bitmap4 argbmap, struct mntinfo4 *mi, ug_cache_t *pug)
869 {
870 	int truefalse;
871 	struct nfs4_ga_ext_res ges, *gesp;
872 	vattr_t *vap = &garp->n4g_va;
873 	vsecattr_t *vsap = &garp->n4g_vsa;
874 
875 	ASSERT(xdrs->x_op == XDR_DECODE);
876 
877 	if (garp->n4g_ext_res)
878 		gesp = garp->n4g_ext_res;
879 	else
880 		gesp = &ges;
881 
882 	vap->va_mask = 0;
883 
884 	/* Check to see if the vattr should be pre-filled */
885 	if (argbmap & NFS4_VATTR_MASK)
886 		xdr_ga_prefill_vattr(garp, mi);
887 
888 	if (argbmap & NFS4_STATFS_ATTR_MASK)
889 		xdr_ga_prefill_statvfs(gesp, mi);
890 
891 	if (resbmap &
892 	    (FATTR4_SUPPORTED_ATTRS_MASK |
893 	    FATTR4_TYPE_MASK |
894 	    FATTR4_FH_EXPIRE_TYPE_MASK |
895 	    FATTR4_CHANGE_MASK |
896 	    FATTR4_SIZE_MASK |
897 	    FATTR4_LINK_SUPPORT_MASK |
898 	    FATTR4_SYMLINK_SUPPORT_MASK |
899 	    FATTR4_NAMED_ATTR_MASK)) {
900 
901 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
902 			if (!xdr_bitmap4(xdrs, &gesp->n4g_suppattrs))
903 				return (FALSE);
904 		}
905 		if (resbmap & FATTR4_TYPE_MASK) {
906 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_type))
907 				return (FALSE);
908 
909 			if ((nfs_ftype4)vap->va_type < NF4REG ||
910 			    (nfs_ftype4)vap->va_type > NF4NAMEDATTR)
911 				vap->va_type = VBAD;
912 			else
913 				vap->va_type = nf4_to_vt[vap->va_type];
914 			if (vap->va_type == VBLK)
915 				vap->va_blksize = DEV_BSIZE;
916 
917 			vap->va_mask |= AT_TYPE;
918 		}
919 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
920 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_fet))
921 				return (FALSE);
922 		}
923 		if (resbmap & FATTR4_CHANGE_MASK) {
924 			if (!xdr_u_longlong_t(xdrs,
925 			    (u_longlong_t *)&garp->n4g_change))
926 				return (FALSE);
927 			garp->n4g_change_valid = 1;
928 		}
929 		if (resbmap & FATTR4_SIZE_MASK) {
930 			if (!xdr_u_longlong_t(xdrs,
931 			    (u_longlong_t *)&vap->va_size))
932 				return (FALSE);
933 			if (!NFS4_SIZE_OK(vap->va_size)) {
934 				garp->n4g_attrerr = EFBIG;
935 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
936 			} else {
937 				vap->va_mask |= AT_SIZE;
938 			}
939 		}
940 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
941 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
942 				return (FALSE);
943 			gesp->n4g_pc4.pc4_link_support =
944 			    (truefalse ? TRUE : FALSE);
945 		}
946 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
947 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
948 				return (FALSE);
949 			gesp->n4g_pc4.pc4_symlink_support =
950 			    (truefalse ? TRUE : FALSE);
951 		}
952 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
953 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
954 				return (FALSE);
955 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
956 			gesp->n4g_pc4.pc4_xattr_exists =
957 			    (truefalse ? TRUE : FALSE);
958 		}
959 	}
960 	if (resbmap &
961 	    (FATTR4_FSID_MASK |
962 	    FATTR4_UNIQUE_HANDLES_MASK |
963 	    FATTR4_LEASE_TIME_MASK |
964 	    FATTR4_RDATTR_ERROR_MASK)) {
965 
966 		if (resbmap & FATTR4_FSID_MASK) {
967 			if ((!xdr_u_longlong_t(xdrs,
968 			    (u_longlong_t *)&garp->n4g_fsid.major)) ||
969 			    (!xdr_u_longlong_t(xdrs,
970 			    (u_longlong_t *)&garp->n4g_fsid.minor)))
971 				return (FALSE);
972 			garp->n4g_fsid_valid = 1;
973 		}
974 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
975 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
976 				return (FALSE);
977 			gesp->n4g_pc4.pc4_unique_handles =
978 			    (truefalse ? TRUE : FALSE);
979 		}
980 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
981 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_leasetime))
982 				return (FALSE);
983 		}
984 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
985 			if (!XDR_GETINT32(xdrs,
986 			    (int *)&gesp->n4g_rdattr_error))
987 				return (FALSE);
988 		}
989 	}
990 	if (resbmap &
991 	    (FATTR4_ACL_MASK |
992 	    FATTR4_ACLSUPPORT_MASK |
993 	    FATTR4_ARCHIVE_MASK |
994 	    FATTR4_CANSETTIME_MASK)) {
995 
996 		if (resbmap & FATTR4_ACL_MASK) {
997 			fattr4_acl	acl;
998 
999 			acl.fattr4_acl_val = NULL;
1000 			acl.fattr4_acl_len = 0;
1001 
1002 			if (!xdr_fattr4_acl(xdrs, &acl))
1003 				return (FALSE);
1004 
1005 			vsap->vsa_aclcnt = acl.fattr4_acl_len;
1006 			vsap->vsa_aclentp = acl.fattr4_acl_val;
1007 			vsap->vsa_mask = VSA_ACE | VSA_ACECNT;
1008 			vsap->vsa_aclentsz = vsap->vsa_aclcnt * sizeof (ace_t);
1009 
1010 		}
1011 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
1012 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_aclsupport))
1013 				return (FALSE);
1014 		}
1015 		if (resbmap & FATTR4_ARCHIVE_MASK) {
1016 			ASSERT(0);
1017 		}
1018 		if (resbmap & FATTR4_CANSETTIME_MASK) {
1019 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
1020 				return (FALSE);
1021 			gesp->n4g_pc4.pc4_cansettime =
1022 			    (truefalse ? TRUE : FALSE);
1023 		}
1024 	}
1025 	if (resbmap &
1026 	    (FATTR4_CASE_INSENSITIVE_MASK |
1027 	    FATTR4_CASE_PRESERVING_MASK |
1028 	    FATTR4_CHOWN_RESTRICTED_MASK |
1029 	    FATTR4_FILEHANDLE_MASK |
1030 	    FATTR4_FILEID_MASK |
1031 	    FATTR4_FILES_AVAIL_MASK |
1032 	    FATTR4_FILES_FREE_MASK |
1033 	    FATTR4_FILES_TOTAL_MASK)) {
1034 
1035 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
1036 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
1037 				return (FALSE);
1038 			gesp->n4g_pc4.pc4_case_insensitive =
1039 			    (truefalse ? TRUE : FALSE);
1040 		}
1041 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
1042 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
1043 				return (FALSE);
1044 			gesp->n4g_pc4.pc4_case_preserving =
1045 			    (truefalse ? TRUE : FALSE);
1046 		}
1047 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
1048 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
1049 				return (FALSE);
1050 			gesp->n4g_pc4.pc4_chown_restricted =
1051 			    (truefalse ? TRUE : FALSE);
1052 		}
1053 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
1054 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
1055 			gesp->n4g_fh_u.nfs_fh4_alt.val =
1056 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
1057 			if (!xdr_bytes(xdrs,
1058 			    (char **)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_val,
1059 			    (uint_t *)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_len,
1060 			    NFS4_FHSIZE))
1061 				return (FALSE);
1062 		}
1063 		if (resbmap & FATTR4_FILEID_MASK) {
1064 			if (!xdr_u_longlong_t(xdrs,
1065 			    (u_longlong_t *)&vap->va_nodeid))
1066 				return (FALSE);
1067 			vap->va_mask |= AT_NODEID;
1068 		}
1069 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
1070 			if (!xdr_u_longlong_t(xdrs,
1071 			    (u_longlong_t *)&gesp->n4g_sb.f_favail))
1072 				return (FALSE);
1073 		}
1074 		if (resbmap & FATTR4_FILES_FREE_MASK) {
1075 			if (!xdr_u_longlong_t(xdrs,
1076 			    (u_longlong_t *)&gesp->n4g_sb.f_ffree))
1077 				return (FALSE);
1078 		}
1079 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
1080 			if (!xdr_u_longlong_t(xdrs,
1081 			    (u_longlong_t *)&gesp->n4g_sb.f_files))
1082 				return (FALSE);
1083 		}
1084 	}
1085 	if (resbmap &
1086 	    (FATTR4_FS_LOCATIONS_MASK |
1087 	    FATTR4_HIDDEN_MASK |
1088 	    FATTR4_HOMOGENEOUS_MASK)) {
1089 
1090 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
1091 			if (!xdr_fattr4_fs_locations(xdrs,
1092 			    &gesp->n4g_fslocations))
1093 				return (FALSE);
1094 		}
1095 		if (resbmap & FATTR4_HIDDEN_MASK) {
1096 			ASSERT(0);
1097 		}
1098 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
1099 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
1100 				return (FALSE);
1101 			gesp->n4g_pc4.pc4_homogeneous =
1102 			    (truefalse ? TRUE : FALSE);
1103 		}
1104 	}
1105 	if (resbmap &
1106 	    (FATTR4_MAXFILESIZE_MASK |
1107 	    FATTR4_MAXLINK_MASK |
1108 	    FATTR4_MAXNAME_MASK |
1109 	    FATTR4_MAXREAD_MASK |
1110 	    FATTR4_MAXWRITE_MASK)) {
1111 
1112 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
1113 			if (!xdr_u_longlong_t(xdrs,
1114 			    (u_longlong_t *)&gesp->n4g_maxfilesize))
1115 				return (FALSE);
1116 		}
1117 		if (resbmap & FATTR4_MAXLINK_MASK) {
1118 			if (!XDR_GETINT32(xdrs,
1119 			    (int *)&gesp->n4g_pc4.pc4_link_max))
1120 				return (FALSE);
1121 		}
1122 		if (resbmap & FATTR4_MAXNAME_MASK) {
1123 			if (!XDR_GETINT32(xdrs,
1124 			    (int *)&gesp->n4g_pc4.pc4_name_max))
1125 				return (FALSE);
1126 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
1127 		}
1128 		if (resbmap & FATTR4_MAXREAD_MASK) {
1129 			if (!xdr_u_longlong_t(xdrs,
1130 			    (u_longlong_t *)&gesp->n4g_maxread))
1131 				return (FALSE);
1132 		}
1133 		if (resbmap & FATTR4_MAXWRITE_MASK) {
1134 			if (!xdr_u_longlong_t(xdrs,
1135 			    (u_longlong_t *)&gesp->n4g_maxwrite))
1136 				return (FALSE);
1137 		}
1138 	}
1139 	if (resbmap &
1140 	    (FATTR4_MIMETYPE_MASK |
1141 	    FATTR4_MODE_MASK |
1142 	    FATTR4_NO_TRUNC_MASK |
1143 	    FATTR4_NUMLINKS_MASK)) {
1144 
1145 		if (resbmap & FATTR4_MIMETYPE_MASK) {
1146 			ASSERT(0);
1147 		}
1148 		if (resbmap & FATTR4_MODE_MASK) {
1149 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_mode))
1150 				return (FALSE);
1151 			vap->va_mask |= AT_MODE;
1152 		}
1153 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
1154 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
1155 				return (FALSE);
1156 			gesp->n4g_pc4.pc4_no_trunc =
1157 			    (truefalse ? TRUE : FALSE);
1158 		}
1159 		if (resbmap & FATTR4_NUMLINKS_MASK) {
1160 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_nlink))
1161 				return (FALSE);
1162 			vap->va_mask |= AT_NLINK;
1163 		}
1164 	}
1165 	if (resbmap &
1166 	    (FATTR4_OWNER_MASK |
1167 	    FATTR4_OWNER_GROUP_MASK |
1168 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
1169 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
1170 
1171 		if (resbmap & FATTR4_OWNER_MASK) {
1172 			uint_t *owner_length, ol;
1173 			char *owner_val = NULL;
1174 			char *owner_alloc = NULL;
1175 			utf8string ov;
1176 			int error;
1177 
1178 			/* get the OWNER_LENGTH */
1179 			if (!xdr_u_int(xdrs, &ol))
1180 				return (FALSE);
1181 
1182 			/* Manage the owner length location */
1183 			if (pug && ol <= MAX_OG_NAME) {
1184 				owner_length = &pug->u_curr.utf8string_len;
1185 				*owner_length = ol;
1186 			} else {
1187 				owner_length = &ol;
1188 			}
1189 
1190 			/* find memory to store the decode */
1191 			if (*owner_length > MAX_OG_NAME || pug == NULL)
1192 				owner_val = owner_alloc =
1193 				    kmem_alloc(*owner_length, KM_SLEEP);
1194 			else
1195 				owner_val = pug->u_curr.utf8string_val;
1196 
1197 			/* get the OWNER string */
1198 			if (!xdr_opaque(xdrs, owner_val, *owner_length)) {
1199 				if (owner_alloc)
1200 					kmem_free(owner_alloc, *owner_length);
1201 				return (FALSE);
1202 			}
1203 
1204 			/* Optimize for matching if called for */
1205 			if (pug &&
1206 			    *owner_length == pug->u_last.utf8string_len &&
1207 			    bcmp(owner_val, pug->u_last.utf8string_val,
1208 			    *owner_length) == 0) {
1209 				vap->va_uid = pug->uid;
1210 				vap->va_mask |= AT_UID;
1211 			} else {
1212 				uid_t uid;
1213 
1214 				ov.utf8string_len = *owner_length;
1215 				ov.utf8string_val = owner_val;
1216 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
1217 				/*
1218 				 * String was mapped, but to nobody because
1219 				 * we are nfsmapid, indicate it should not
1220 				 * be cached.
1221 				 */
1222 				if (error == ENOTSUP) {
1223 					error = 0;
1224 					garp->n4g_attrwhy =
1225 					    NFS4_GETATTR_NOCACHE_OK;
1226 				}
1227 
1228 				if (error) {
1229 					garp->n4g_attrerr = error;
1230 					garp->n4g_attrwhy =
1231 					    NFS4_GETATTR_ATUID_ERR;
1232 				} else {
1233 					vap->va_uid = uid;
1234 					vap->va_mask |= AT_UID;
1235 					if (pug && ol <= MAX_OG_NAME) {
1236 						pug->uid = uid;
1237 						U_SWAP_CURR_LAST(pug);
1238 					}
1239 				}
1240 				if (owner_alloc)
1241 					kmem_free(owner_alloc, *owner_length);
1242 			}
1243 		}
1244 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
1245 			uint_t *group_length, gl;
1246 			char *group_val = NULL;
1247 			char *group_alloc = NULL;
1248 			utf8string gv;
1249 			int error;
1250 
1251 			/* get the OWNER_GROUP_LENGTH */
1252 			if (!xdr_u_int(xdrs, &gl))
1253 				return (FALSE);
1254 
1255 			/* Manage the group length location */
1256 			if (pug && gl <= MAX_OG_NAME) {
1257 				group_length = &pug->g_curr.utf8string_len;
1258 				*group_length = gl;
1259 			} else {
1260 				group_length = &gl;
1261 			}
1262 
1263 			/* find memory to store the decode */
1264 			if (*group_length > MAX_OG_NAME || pug == NULL)
1265 				group_val = group_alloc =
1266 				    kmem_alloc(*group_length, KM_SLEEP);
1267 			else
1268 				group_val = pug->g_curr.utf8string_val;
1269 
1270 			/* get the OWNER_GROUP string */
1271 			if (!xdr_opaque(xdrs, group_val, *group_length)) {
1272 				if (group_alloc)
1273 					kmem_free(group_alloc, *group_length);
1274 				return (FALSE);
1275 			}
1276 
1277 			/* Optimize for matching if called for */
1278 			if (pug &&
1279 			    *group_length == pug->g_last.utf8string_len &&
1280 			    bcmp(group_val, pug->g_last.utf8string_val,
1281 			    *group_length) == 0) {
1282 				vap->va_gid = pug->gid;
1283 				vap->va_mask |= AT_GID;
1284 			} else {
1285 				uid_t gid;
1286 
1287 				gv.utf8string_len = *group_length;
1288 				gv.utf8string_val = group_val;
1289 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
1290 				/*
1291 				 * String was mapped, but to nobody because
1292 				 * we are nfsmapid, indicate it should not
1293 				 * be cached.
1294 				 */
1295 				if (error == ENOTSUP) {
1296 					error = 0;
1297 					garp->n4g_attrwhy =
1298 					    NFS4_GETATTR_NOCACHE_OK;
1299 				}
1300 
1301 				if (error) {
1302 					garp->n4g_attrerr = error;
1303 					garp->n4g_attrwhy =
1304 					    NFS4_GETATTR_ATGID_ERR;
1305 				} else {
1306 					vap->va_gid = gid;
1307 					vap->va_mask |= AT_GID;
1308 					if (pug && gl <= MAX_OG_NAME) {
1309 						pug->gid = gid;
1310 						G_SWAP_CURR_LAST(pug);
1311 					}
1312 				}
1313 				if (group_alloc) {
1314 					kmem_free(group_alloc, *group_length);
1315 				}
1316 			}
1317 		}
1318 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
1319 			ASSERT(0);
1320 		}
1321 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
1322 			ASSERT(0);
1323 		}
1324 	}
1325 	if (resbmap &
1326 	    (FATTR4_QUOTA_USED_MASK |
1327 	    FATTR4_SPACE_AVAIL_MASK |
1328 	    FATTR4_SPACE_FREE_MASK |
1329 	    FATTR4_SPACE_TOTAL_MASK |
1330 	    FATTR4_SPACE_USED_MASK |
1331 	    FATTR4_SYSTEM_MASK)) {
1332 
1333 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
1334 			ASSERT(0);
1335 		}
1336 		if (resbmap & FATTR4_RAWDEV_MASK) {
1337 			fattr4_rawdev rawdev;
1338 			if (!xdr_fattr4_rawdev(xdrs, &rawdev))
1339 				return (FALSE);
1340 
1341 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
1342 				vap->va_rdev = makedevice(rawdev.specdata1,
1343 				    rawdev.specdata2);
1344 			} else {
1345 				vap->va_rdev = 0;
1346 			}
1347 			vap->va_mask |= AT_RDEV;
1348 		}
1349 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
1350 			if (!xdr_u_longlong_t(xdrs,
1351 			    (u_longlong_t *)&gesp->n4g_sb.f_bavail))
1352 				return (FALSE);
1353 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
1354 		}
1355 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
1356 			if (!xdr_u_longlong_t(xdrs,
1357 			    (u_longlong_t *)&gesp->n4g_sb.f_bfree))
1358 				return (FALSE);
1359 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
1360 		}
1361 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
1362 			if (!xdr_u_longlong_t(xdrs,
1363 			    (u_longlong_t *)&gesp->n4g_sb.f_blocks))
1364 				return (FALSE);
1365 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
1366 		}
1367 		if (resbmap & FATTR4_SPACE_USED_MASK) {
1368 			uint64_t space_used;
1369 			if (!xdr_u_longlong_t(xdrs,
1370 			    (u_longlong_t *)&space_used))
1371 				return (FALSE);
1372 
1373 			/* Compute space depending on device type */
1374 			ASSERT((vap->va_mask & AT_TYPE));
1375 			if (vap->va_type == VREG || vap->va_type == VDIR ||
1376 			    vap->va_type == VLNK) {
1377 				vap->va_nblocks = (u_longlong_t)
1378 				    ((space_used + (offset4)DEV_BSIZE -
1379 				    (offset4)1) / (offset4)DEV_BSIZE);
1380 			} else {
1381 				vap->va_nblocks = 0;
1382 			}
1383 			vap->va_mask |= AT_NBLOCKS;
1384 		}
1385 		if (resbmap & FATTR4_SYSTEM_MASK) {
1386 			ASSERT(0);
1387 		}
1388 	}
1389 	if (resbmap &
1390 	    (FATTR4_TIME_ACCESS_MASK |
1391 	    FATTR4_TIME_ACCESS_SET_MASK |
1392 	    FATTR4_TIME_BACKUP_MASK |
1393 	    FATTR4_TIME_CREATE_MASK |
1394 	    FATTR4_TIME_DELTA_MASK |
1395 	    FATTR4_TIME_METADATA_MASK |
1396 	    FATTR4_TIME_MODIFY_MASK |
1397 	    FATTR4_TIME_MODIFY_SET_MASK |
1398 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
1399 
1400 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
1401 			nfstime4 atime;
1402 			int error;
1403 
1404 			if (!xdr_longlong_t(xdrs,
1405 			    (longlong_t *)&atime.seconds))
1406 				return (FALSE);
1407 			if (!XDR_GETINT32(xdrs, (int *)&atime.nseconds))
1408 				return (FALSE);
1409 			error = nfs4_time_ntov(&atime, &vap->va_atime);
1410 			if (error) {
1411 				garp->n4g_attrerr = error;
1412 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
1413 			}
1414 			vap->va_mask |= AT_ATIME;
1415 		}
1416 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
1417 			ASSERT(0);
1418 		}
1419 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
1420 			ASSERT(0);
1421 		}
1422 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
1423 			ASSERT(0);
1424 		}
1425 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
1426 			if ((!xdr_u_longlong_t(xdrs,
1427 			    (u_longlong_t *)&gesp->n4g_delta.seconds)) ||
1428 			    (!xdr_u_int(xdrs, &gesp->n4g_delta.nseconds)))
1429 				return (FALSE);
1430 		}
1431 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
1432 			nfstime4 mdt;
1433 			int error;
1434 
1435 			if (!xdr_longlong_t(xdrs, (longlong_t *)&mdt.seconds))
1436 				return (FALSE);
1437 			if (!XDR_GETINT32(xdrs, (int32_t *)&mdt.nseconds))
1438 				return (FALSE);
1439 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
1440 			if (error) {
1441 				garp->n4g_attrerr = error;
1442 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
1443 			}
1444 			vap->va_mask |= AT_CTIME;
1445 		}
1446 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
1447 			nfstime4 mtime;
1448 			int error;
1449 
1450 			if (!xdr_longlong_t(xdrs,
1451 			    (longlong_t *)&mtime.seconds))
1452 				return (FALSE);
1453 			if (!XDR_GETINT32(xdrs, (int32_t *)&mtime.nseconds))
1454 				return (FALSE);
1455 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
1456 			if (error) {
1457 				garp->n4g_attrerr = error;
1458 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
1459 			}
1460 			vap->va_mask |= AT_MTIME;
1461 		}
1462 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
1463 			ASSERT(0);
1464 		}
1465 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
1466 			if (!xdr_u_longlong_t(xdrs,
1467 			    (u_longlong_t *)&garp->n4g_mon_fid))
1468 				return (FALSE);
1469 			garp->n4g_mon_fid_valid = 1;
1470 		}
1471 	}
1472 
1473 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
1474 		/* copy only if not provided */
1475 		if (garp->n4g_ext_res == NULL) {
1476 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
1477 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
1478 		}
1479 	}
1480 
1481 	return (TRUE);
1482 }
1483 
1484 /*
1485  * Inlined version of get_bitmap4 processing
1486  */
1487 bitmap4
1488 xdr_get_bitmap4_inline(uint32_t **iptr)
1489 {
1490 	uint32_t resbmaplen;
1491 	bitmap4 bm;
1492 	uint32_t *ptr = *iptr;
1493 
1494 	/* bitmap LENGTH */
1495 	resbmaplen = IXDR_GET_U_INT32(ptr);
1496 
1497 	/* Inline the bitmap and attrlen for common case of two word map */
1498 	if (resbmaplen == 2) {
1499 		IXDR_GET_HYPER(ptr, bm);
1500 		*iptr = ptr;
1501 		return (bm);
1502 	}
1503 
1504 #if defined(_LITTLE_ENDIAN)
1505 	bm = IXDR_GET_U_INT32(ptr);
1506 	if (--resbmaplen == 0) {
1507 		*iptr = ptr;
1508 		return (bm);
1509 	}
1510 	*((uint32_t *)&bm) |= IXDR_GET_U_INT32(ptr);
1511 	if (--resbmaplen == 0) {
1512 		*iptr = ptr;
1513 		return (bm);
1514 	}
1515 	ptr += resbmaplen;
1516 	*iptr = ptr;
1517 	return (bm);
1518 #elif defined(_BIG_ENDIAN)
1519 	*((uint32_t *)&bm) = IXDR_GET_U_INT32(ptr);
1520 	if (--resbmaplen == 0) {
1521 		*iptr = ptr;
1522 		return (bm);
1523 	}
1524 	bm |= IXDR_GET_U_INT32(ptr);
1525 	if (--resbmaplen == 0) {
1526 		*iptr = ptr;
1527 		return (bm);
1528 	}
1529 	ptr += resbmaplen;
1530 	*iptr = ptr;
1531 	return (bm);
1532 #else
1533 	ASSERT(0);
1534 	ptr += resbmaplen;
1535 	*iptr = ptr;
1536 	return (0);
1537 #endif
1538 }
1539 
1540 static bool_t
1541 xdr_ga_fattr_res_inline(uint32_t *ptr, struct nfs4_ga_res *garp,
1542 			bitmap4 resbmap, bitmap4 argbmap, struct mntinfo4 *mi,
1543 			ug_cache_t *pug)
1544 {
1545 	int truefalse;
1546 	struct nfs4_ga_ext_res ges, *gesp;
1547 	vattr_t *vap = &garp->n4g_va;
1548 
1549 	if (garp->n4g_ext_res)
1550 		gesp = garp->n4g_ext_res;
1551 	else
1552 		gesp = &ges;
1553 
1554 	vap->va_mask = 0;
1555 
1556 	/* Check to see if the vattr should be pre-filled */
1557 	if (argbmap & NFS4_VATTR_MASK)
1558 		xdr_ga_prefill_vattr(garp, mi);
1559 
1560 	if (argbmap & NFS4_STATFS_ATTR_MASK)
1561 		xdr_ga_prefill_statvfs(gesp, mi);
1562 
1563 	if (resbmap &
1564 	    (FATTR4_SUPPORTED_ATTRS_MASK |
1565 	    FATTR4_TYPE_MASK |
1566 	    FATTR4_FH_EXPIRE_TYPE_MASK |
1567 	    FATTR4_CHANGE_MASK |
1568 	    FATTR4_SIZE_MASK |
1569 	    FATTR4_LINK_SUPPORT_MASK |
1570 	    FATTR4_SYMLINK_SUPPORT_MASK |
1571 	    FATTR4_NAMED_ATTR_MASK)) {
1572 
1573 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
1574 			gesp->n4g_suppattrs = xdr_get_bitmap4_inline(&ptr);
1575 		}
1576 		if (resbmap & FATTR4_TYPE_MASK) {
1577 			vap->va_type = IXDR_GET_U_INT32(ptr);
1578 
1579 			if ((nfs_ftype4)vap->va_type < NF4REG ||
1580 			    (nfs_ftype4)vap->va_type > NF4NAMEDATTR)
1581 				vap->va_type = VBAD;
1582 			else
1583 				vap->va_type = nf4_to_vt[vap->va_type];
1584 			if (vap->va_type == VBLK)
1585 				vap->va_blksize = DEV_BSIZE;
1586 
1587 			vap->va_mask |= AT_TYPE;
1588 		}
1589 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
1590 			gesp->n4g_fet = IXDR_GET_U_INT32(ptr);
1591 		}
1592 		if (resbmap & FATTR4_CHANGE_MASK) {
1593 			IXDR_GET_U_HYPER(ptr, garp->n4g_change);
1594 			garp->n4g_change_valid = 1;
1595 		}
1596 		if (resbmap & FATTR4_SIZE_MASK) {
1597 			IXDR_GET_U_HYPER(ptr, vap->va_size);
1598 
1599 			if (!NFS4_SIZE_OK(vap->va_size)) {
1600 				garp->n4g_attrerr = EFBIG;
1601 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
1602 			} else {
1603 				vap->va_mask |= AT_SIZE;
1604 			}
1605 		}
1606 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
1607 			truefalse = IXDR_GET_U_INT32(ptr);
1608 			gesp->n4g_pc4.pc4_link_support =
1609 			    (truefalse ? TRUE : FALSE);
1610 		}
1611 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
1612 			truefalse = IXDR_GET_U_INT32(ptr);
1613 			gesp->n4g_pc4.pc4_symlink_support =
1614 			    (truefalse ? TRUE : FALSE);
1615 		}
1616 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
1617 			truefalse = IXDR_GET_U_INT32(ptr);
1618 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
1619 			gesp->n4g_pc4.pc4_xattr_exists =
1620 			    (truefalse ? TRUE : FALSE);
1621 		}
1622 	}
1623 	if (resbmap &
1624 	    (FATTR4_FSID_MASK |
1625 	    FATTR4_UNIQUE_HANDLES_MASK |
1626 	    FATTR4_LEASE_TIME_MASK |
1627 	    FATTR4_RDATTR_ERROR_MASK)) {
1628 
1629 		if (resbmap & FATTR4_FSID_MASK) {
1630 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.major);
1631 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.minor);
1632 			garp->n4g_fsid_valid = 1;
1633 		}
1634 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
1635 			truefalse = IXDR_GET_U_INT32(ptr);
1636 			gesp->n4g_pc4.pc4_unique_handles =
1637 			    (truefalse ? TRUE : FALSE);
1638 		}
1639 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
1640 			gesp->n4g_leasetime = IXDR_GET_U_INT32(ptr);
1641 		}
1642 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
1643 			gesp->n4g_rdattr_error = IXDR_GET_U_INT32(ptr);
1644 		}
1645 	}
1646 	if (resbmap &
1647 	    (FATTR4_ACL_MASK |
1648 	    FATTR4_ACLSUPPORT_MASK |
1649 	    FATTR4_ARCHIVE_MASK |
1650 	    FATTR4_CANSETTIME_MASK)) {
1651 
1652 		if (resbmap & FATTR4_ACL_MASK) {
1653 			ASSERT(0);
1654 		}
1655 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
1656 			gesp->n4g_aclsupport = IXDR_GET_U_INT32(ptr);
1657 		}
1658 		if (resbmap & FATTR4_ARCHIVE_MASK) {
1659 			ASSERT(0);
1660 		}
1661 		if (resbmap & FATTR4_CANSETTIME_MASK) {
1662 			truefalse = IXDR_GET_U_INT32(ptr);
1663 			gesp->n4g_pc4.pc4_cansettime =
1664 			    (truefalse ? TRUE : FALSE);
1665 		}
1666 	}
1667 	if (resbmap &
1668 	    (FATTR4_CASE_INSENSITIVE_MASK |
1669 	    FATTR4_CASE_PRESERVING_MASK |
1670 	    FATTR4_CHOWN_RESTRICTED_MASK |
1671 	    FATTR4_FILEHANDLE_MASK |
1672 	    FATTR4_FILEID_MASK |
1673 	    FATTR4_FILES_AVAIL_MASK |
1674 	    FATTR4_FILES_FREE_MASK |
1675 	    FATTR4_FILES_TOTAL_MASK)) {
1676 
1677 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
1678 			truefalse = IXDR_GET_U_INT32(ptr);
1679 			gesp->n4g_pc4.pc4_case_insensitive =
1680 			    (truefalse ? TRUE : FALSE);
1681 		}
1682 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
1683 			truefalse = IXDR_GET_U_INT32(ptr);
1684 			gesp->n4g_pc4.pc4_case_preserving =
1685 			    (truefalse ? TRUE : FALSE);
1686 		}
1687 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
1688 			truefalse = IXDR_GET_U_INT32(ptr);
1689 			gesp->n4g_pc4.pc4_chown_restricted =
1690 			    (truefalse ? TRUE : FALSE);
1691 		}
1692 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
1693 			int len = IXDR_GET_U_INT32(ptr);
1694 
1695 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
1696 			gesp->n4g_fh_u.nfs_fh4_alt.val =
1697 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
1698 			gesp->n4g_fh_u.n4g_fh.nfs_fh4_len = len;
1699 
1700 			bcopy(ptr, gesp->n4g_fh_u.n4g_fh.nfs_fh4_val, len);
1701 
1702 			ptr += RNDUP(len) / BYTES_PER_XDR_UNIT;
1703 		}
1704 		if (resbmap & FATTR4_FILEID_MASK) {
1705 			IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
1706 			vap->va_mask |= AT_NODEID;
1707 		}
1708 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
1709 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_favail);
1710 		}
1711 		if (resbmap & FATTR4_FILES_FREE_MASK) {
1712 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_ffree);
1713 		}
1714 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
1715 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_files);
1716 		}
1717 	}
1718 	if (resbmap &
1719 	    (FATTR4_FS_LOCATIONS_MASK |
1720 	    FATTR4_HIDDEN_MASK |
1721 	    FATTR4_HOMOGENEOUS_MASK)) {
1722 
1723 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
1724 			ASSERT(0);
1725 		}
1726 		if (resbmap & FATTR4_HIDDEN_MASK) {
1727 			ASSERT(0);
1728 		}
1729 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
1730 			truefalse = IXDR_GET_U_INT32(ptr);
1731 			gesp->n4g_pc4.pc4_homogeneous =
1732 			    (truefalse ? TRUE : FALSE);
1733 		}
1734 	}
1735 	if (resbmap &
1736 	    (FATTR4_MAXFILESIZE_MASK |
1737 	    FATTR4_MAXLINK_MASK |
1738 	    FATTR4_MAXNAME_MASK |
1739 	    FATTR4_MAXREAD_MASK |
1740 	    FATTR4_MAXWRITE_MASK)) {
1741 
1742 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
1743 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxfilesize);
1744 		}
1745 		if (resbmap & FATTR4_MAXLINK_MASK) {
1746 			gesp->n4g_pc4.pc4_link_max = IXDR_GET_U_INT32(ptr);
1747 		}
1748 		if (resbmap & FATTR4_MAXNAME_MASK) {
1749 			gesp->n4g_pc4.pc4_name_max = IXDR_GET_U_INT32(ptr);
1750 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
1751 		}
1752 		if (resbmap & FATTR4_MAXREAD_MASK) {
1753 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxread);
1754 		}
1755 		if (resbmap & FATTR4_MAXWRITE_MASK) {
1756 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxwrite);
1757 		}
1758 	}
1759 	if (resbmap &
1760 	    (FATTR4_MIMETYPE_MASK |
1761 	    FATTR4_MODE_MASK |
1762 	    FATTR4_NO_TRUNC_MASK |
1763 	    FATTR4_NUMLINKS_MASK)) {
1764 
1765 		if (resbmap & FATTR4_MIMETYPE_MASK) {
1766 			ASSERT(0);
1767 		}
1768 		if (resbmap & FATTR4_MODE_MASK) {
1769 			vap->va_mode = IXDR_GET_U_INT32(ptr);
1770 			vap->va_mask |= AT_MODE;
1771 		}
1772 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
1773 			truefalse = IXDR_GET_U_INT32(ptr);
1774 			gesp->n4g_pc4.pc4_no_trunc =
1775 			    (truefalse ? TRUE : FALSE);
1776 		}
1777 		if (resbmap & FATTR4_NUMLINKS_MASK) {
1778 			vap->va_nlink = IXDR_GET_U_INT32(ptr);
1779 			vap->va_mask |= AT_NLINK;
1780 		}
1781 	}
1782 	if (resbmap &
1783 	    (FATTR4_OWNER_MASK |
1784 	    FATTR4_OWNER_GROUP_MASK |
1785 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
1786 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
1787 
1788 		if (resbmap & FATTR4_OWNER_MASK) {
1789 			uint_t *owner_length, ol;
1790 			char *owner_val = NULL;
1791 			utf8string ov;
1792 			int error;
1793 
1794 			/* get the OWNER_LENGTH */
1795 			ol = IXDR_GET_U_INT32(ptr);
1796 
1797 			/* Manage the owner length location */
1798 			if (pug && ol <= MAX_OG_NAME) {
1799 				owner_length = &pug->u_curr.utf8string_len;
1800 				*owner_length = ol;
1801 			} else {
1802 				owner_length = &ol;
1803 			}
1804 
1805 			/* find memory to store the decode */
1806 			if (*owner_length > MAX_OG_NAME || pug == NULL)
1807 				owner_val = (char *)ptr;
1808 			else
1809 				owner_val = (char *)ptr;
1810 
1811 			/* Optimize for matching if called for */
1812 			if (pug &&
1813 			    *owner_length == pug->u_last.utf8string_len &&
1814 			    bcmp(owner_val, pug->u_last.utf8string_val,
1815 			    *owner_length) == 0) {
1816 				vap->va_uid = pug->uid;
1817 				vap->va_mask |= AT_UID;
1818 			} else {
1819 				uid_t uid;
1820 
1821 				ov.utf8string_len = *owner_length;
1822 				ov.utf8string_val = owner_val;
1823 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
1824 				/*
1825 				 * String was mapped, but to nobody because
1826 				 * we are nfsmapid, indicate it should not
1827 				 * be cached.
1828 				 */
1829 				if (error == ENOTSUP) {
1830 					error = 0;
1831 					garp->n4g_attrwhy =
1832 					    NFS4_GETATTR_NOCACHE_OK;
1833 				}
1834 
1835 				if (error) {
1836 					garp->n4g_attrerr = error;
1837 					garp->n4g_attrwhy =
1838 					    NFS4_GETATTR_ATUID_ERR;
1839 				} else {
1840 					vap->va_uid = uid;
1841 					vap->va_mask |= AT_UID;
1842 					/* save the results for next time */
1843 					if (pug && ol <= MAX_OG_NAME) {
1844 						pug->uid = uid;
1845 						pug->u_curr.utf8string_len =
1846 						    ov.utf8string_len;
1847 						bcopy(owner_val,
1848 						    pug->u_curr.utf8string_val,
1849 						    ol);
1850 						U_SWAP_CURR_LAST(pug);
1851 					}
1852 				}
1853 			}
1854 			ptr += RNDUP(ol) / BYTES_PER_XDR_UNIT;
1855 		}
1856 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
1857 			uint_t *group_length, gl;
1858 			char *group_val = NULL;
1859 			utf8string gv;
1860 			int error;
1861 
1862 			/* get the OWNER_GROUP_LENGTH */
1863 			gl = IXDR_GET_U_INT32(ptr);
1864 
1865 			/* Manage the group length location */
1866 			if (pug && gl <= MAX_OG_NAME) {
1867 				group_length = &pug->g_curr.utf8string_len;
1868 				*group_length = gl;
1869 			} else {
1870 				group_length = &gl;
1871 			}
1872 
1873 			/* find memory to store the decode */
1874 			if (*group_length > MAX_OG_NAME || pug == NULL)
1875 				group_val = (char *)ptr;
1876 			else
1877 				group_val = (char *)ptr;
1878 
1879 			/* Optimize for matching if called for */
1880 			if (pug &&
1881 			    *group_length == pug->g_last.utf8string_len &&
1882 			    bcmp(group_val, pug->g_last.utf8string_val,
1883 			    *group_length) == 0) {
1884 				vap->va_gid = pug->gid;
1885 				vap->va_mask |= AT_GID;
1886 			} else {
1887 				uid_t gid;
1888 
1889 				gv.utf8string_len = *group_length;
1890 				gv.utf8string_val = group_val;
1891 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
1892 				/*
1893 				 * String was mapped, but to nobody because
1894 				 * we are nfsmapid, indicate it should not
1895 				 * be cached.
1896 				 */
1897 				if (error == ENOTSUP) {
1898 					error = 0;
1899 					garp->n4g_attrwhy =
1900 					    NFS4_GETATTR_NOCACHE_OK;
1901 				}
1902 
1903 				if (error) {
1904 					garp->n4g_attrerr = error;
1905 					garp->n4g_attrwhy =
1906 					    NFS4_GETATTR_ATGID_ERR;
1907 				} else {
1908 					vap->va_gid = gid;
1909 					vap->va_mask |= AT_GID;
1910 					if (pug && gl <= MAX_OG_NAME) {
1911 						pug->gid = gid;
1912 						pug->g_curr.utf8string_len =
1913 						    gv.utf8string_len;
1914 						bcopy(group_val,
1915 						    pug->g_curr.utf8string_val,
1916 						    gl);
1917 						G_SWAP_CURR_LAST(pug);
1918 					}
1919 				}
1920 			}
1921 			ptr += RNDUP(gl) / BYTES_PER_XDR_UNIT;
1922 		}
1923 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
1924 			ASSERT(0);
1925 		}
1926 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
1927 			ASSERT(0);
1928 		}
1929 	}
1930 	if (resbmap &
1931 	    (FATTR4_QUOTA_USED_MASK |
1932 	    FATTR4_SPACE_AVAIL_MASK |
1933 	    FATTR4_SPACE_FREE_MASK |
1934 	    FATTR4_SPACE_TOTAL_MASK |
1935 	    FATTR4_SPACE_USED_MASK |
1936 	    FATTR4_SYSTEM_MASK)) {
1937 
1938 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
1939 			ASSERT(0);
1940 		}
1941 		if (resbmap & FATTR4_RAWDEV_MASK) {
1942 			fattr4_rawdev rawdev;
1943 
1944 			rawdev.specdata1 = IXDR_GET_U_INT32(ptr);
1945 			rawdev.specdata2 = IXDR_GET_U_INT32(ptr);
1946 
1947 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
1948 				vap->va_rdev = makedevice(rawdev.specdata1,
1949 				    rawdev.specdata2);
1950 			} else {
1951 				vap->va_rdev = 0;
1952 			}
1953 			vap->va_mask |= AT_RDEV;
1954 		}
1955 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
1956 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bavail);
1957 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
1958 		}
1959 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
1960 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bfree);
1961 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
1962 		}
1963 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
1964 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_blocks);
1965 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
1966 		}
1967 		if (resbmap & FATTR4_SPACE_USED_MASK) {
1968 			uint64_t space_used;
1969 			IXDR_GET_U_HYPER(ptr, space_used);
1970 
1971 			/* Compute space depending on device type */
1972 			ASSERT((vap->va_mask & AT_TYPE));
1973 			if (vap->va_type == VREG || vap->va_type == VDIR ||
1974 			    vap->va_type == VLNK) {
1975 				vap->va_nblocks = (u_longlong_t)
1976 				    ((space_used + (offset4)DEV_BSIZE -
1977 				    (offset4)1) / (offset4)DEV_BSIZE);
1978 			} else {
1979 				vap->va_nblocks = 0;
1980 			}
1981 			vap->va_mask |= AT_NBLOCKS;
1982 		}
1983 		if (resbmap & FATTR4_SYSTEM_MASK) {
1984 			ASSERT(0);
1985 		}
1986 	}
1987 	if (resbmap &
1988 	    (FATTR4_TIME_ACCESS_MASK |
1989 	    FATTR4_TIME_ACCESS_SET_MASK |
1990 	    FATTR4_TIME_BACKUP_MASK |
1991 	    FATTR4_TIME_CREATE_MASK |
1992 	    FATTR4_TIME_DELTA_MASK |
1993 	    FATTR4_TIME_METADATA_MASK |
1994 	    FATTR4_TIME_MODIFY_MASK |
1995 	    FATTR4_TIME_MODIFY_SET_MASK |
1996 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
1997 
1998 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
1999 			nfstime4 atime;
2000 			int error;
2001 
2002 			IXDR_GET_U_HYPER(ptr, atime.seconds);
2003 			atime.nseconds = IXDR_GET_U_INT32(ptr);
2004 
2005 			error = nfs4_time_ntov(&atime, &vap->va_atime);
2006 			if (error) {
2007 				garp->n4g_attrerr = error;
2008 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
2009 			}
2010 			vap->va_mask |= AT_ATIME;
2011 		}
2012 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
2013 			ASSERT(0);
2014 		}
2015 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
2016 			ASSERT(0);
2017 		}
2018 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
2019 			ASSERT(0);
2020 		}
2021 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
2022 			IXDR_GET_U_HYPER(ptr, gesp->n4g_delta.seconds);
2023 			gesp->n4g_delta.nseconds = IXDR_GET_U_INT32(ptr);
2024 		}
2025 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
2026 			nfstime4 mdt;
2027 			int error;
2028 
2029 			IXDR_GET_U_HYPER(ptr, mdt.seconds);
2030 			mdt.nseconds = IXDR_GET_U_INT32(ptr);
2031 
2032 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
2033 			if (error) {
2034 				garp->n4g_attrerr = error;
2035 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
2036 			}
2037 			vap->va_mask |= AT_CTIME;
2038 		}
2039 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
2040 			nfstime4 mtime;
2041 			int error;
2042 
2043 			IXDR_GET_U_HYPER(ptr, mtime.seconds);
2044 			mtime.nseconds = IXDR_GET_U_INT32(ptr);
2045 
2046 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
2047 			if (error) {
2048 				garp->n4g_attrerr = error;
2049 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
2050 			}
2051 			vap->va_mask |= AT_MTIME;
2052 		}
2053 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
2054 			ASSERT(0);
2055 		}
2056 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
2057 			IXDR_GET_U_HYPER(ptr, garp->n4g_mon_fid);
2058 			garp->n4g_mon_fid_valid = 1;
2059 		}
2060 	}
2061 
2062 	/*
2063 	 * FATTR4_ACL_MASK is not yet supported by this function, but
2064 	 * we check against it anyway, in case it ever is.
2065 	 */
2066 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
2067 		/* copy only if not provided */
2068 		if (garp->n4g_ext_res == NULL) {
2069 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
2070 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
2071 		}
2072 	}
2073 
2074 	return (TRUE);
2075 }
2076 
2077 
2078 /*
2079  * "." and ".." buffers for filling in on read and readdir
2080  * calls. Intialize the first time and fill in on every
2081  * call to to readdir.
2082  */
2083 char	*nfs4_dot_entries;
2084 char	*nfs4_dot_dot_entry;
2085 
2086 /*
2087  * Create the "." or ".." and pad the buffer once so they are
2088  * copied out as required into the user supplied buffer everytime.
2089  * DIRENT64_RECLEN(sizeof (".") - 1) = DIRENT64_RECLEN(1)
2090  * DIRENT64_RECLEN(sizeof ("..") - 1) = DIRENT64_RECLEN(2)
2091  */
2092 void
2093 nfs4_init_dot_entries()
2094 {
2095 	struct dirent64 *odp;
2096 
2097 	/*
2098 	 * zalloc it so it zeros the buffer out. Need
2099 	 * to just do it once.
2100 	 */
2101 	nfs4_dot_entries = kmem_zalloc(DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2),
2102 	    KM_SLEEP);
2103 
2104 	odp = (struct dirent64 *)nfs4_dot_entries;
2105 	odp->d_off = 1; /* magic cookie for "." entry */
2106 	odp->d_reclen = DIRENT64_RECLEN(1);
2107 	odp->d_name[0] = '.';
2108 	odp->d_name[1] = '\0';
2109 
2110 	nfs4_dot_dot_entry = nfs4_dot_entries + DIRENT64_RECLEN(1);
2111 	odp = (struct dirent64 *)nfs4_dot_dot_entry;
2112 
2113 	odp->d_off = 2;
2114 	odp->d_reclen = DIRENT64_RECLEN(2);
2115 	odp->d_name[0] = '.';
2116 	odp->d_name[1] = '.';
2117 	odp->d_name[2] = '\0';
2118 }
2119 
2120 void
2121 nfs4_destroy_dot_entries()
2122 {
2123 	if (nfs4_dot_entries)
2124 		kmem_free(nfs4_dot_entries, DIRENT64_RECLEN(1) +
2125 		    DIRENT64_RECLEN(2));
2126 
2127 	nfs4_dot_entries = nfs4_dot_dot_entry = NULL;
2128 }
2129 
2130 bool_t
2131 xdr_READDIR4res_clnt(XDR *xdrs, READDIR4res_clnt *objp, READDIR4args *aobjp)
2132 {
2133 	bool_t more_data;
2134 	rddir4_cache *rdc = aobjp->rdc;
2135 	dirent64_t *dp = NULL;
2136 	int entry_length = 0;
2137 	int space_left = 0;
2138 	bitmap4 resbmap;
2139 	uint32_t attrlen;
2140 	nfs4_ga_res_t gar;
2141 	struct nfs4_ga_ext_res ges;
2142 	uint64_t last_cookie = 0;
2143 	int skip_to_end;
2144 	ug_cache_t *pug = NULL;
2145 
2146 	ASSERT(xdrs->x_op == XDR_DECODE);
2147 	ASSERT(rdc->entries == NULL);
2148 	ASSERT(aobjp->dircount > 0);
2149 
2150 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
2151 		return (FALSE);
2152 	if (objp->status != NFS4_OK)
2153 		return (TRUE);
2154 
2155 	gar.n4g_va.va_mask = 0;
2156 	gar.n4g_change_valid = 0;
2157 	gar.n4g_mon_fid_valid = 0;
2158 	gar.n4g_fsid_valid = 0;
2159 	gar.n4g_vsa.vsa_mask = 0;
2160 	gar.n4g_attrwhy = NFS4_GETATTR_OP_OK;
2161 	ges.n4g_pc4.pc4_cache_valid = 0;
2162 	ges.n4g_pc4.pc4_xattr_valid = 0;
2163 	gar.n4g_ext_res = &ges;
2164 
2165 	/* READDIR4res_clnt_free needs to kmem_free this buffer */
2166 	rdc->entries = kmem_alloc(aobjp->dircount, KM_SLEEP);
2167 
2168 	dp = (dirent64_t *)rdc->entries;
2169 	rdc->entlen = rdc->buflen = space_left = aobjp->dircount;
2170 
2171 	/* Fill in dot and dot-dot if needed */
2172 	if (rdc->nfs4_cookie == (nfs_cookie4) 0 ||
2173 	    rdc->nfs4_cookie == (nfs_cookie4) 1) {
2174 
2175 		if (rdc->nfs4_cookie == (nfs_cookie4)0) {
2176 			bcopy(nfs4_dot_entries, rdc->entries,
2177 			    DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2));
2178 			objp->dotp = dp;
2179 			dp = (struct dirent64 *)(((char *)dp) +
2180 			    DIRENT64_RECLEN(1));
2181 			objp->dotdotp = dp;
2182 			dp = (struct dirent64 *)(((char *)dp) +
2183 			    DIRENT64_RECLEN(2));
2184 			space_left -= DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2);
2185 
2186 		} else	{	/* for ".." entry */
2187 			bcopy(nfs4_dot_dot_entry, rdc->entries,
2188 			    DIRENT64_RECLEN(2));
2189 			objp->dotp = NULL;
2190 			objp->dotdotp = dp;
2191 			dp = (struct dirent64 *)(((char *)dp) +
2192 			    DIRENT64_RECLEN(2));
2193 			space_left -= DIRENT64_RECLEN(2);
2194 		}
2195 		/* Magic NFSv4 number for entry after start */
2196 		last_cookie = 2;
2197 	}
2198 
2199 	/* Get the cookie VERIFIER */
2200 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
2201 		goto noentries;
2202 
2203 	/* Get the do-we-have-a-next-entry BOOL */
2204 	if (!xdr_bool(xdrs, &more_data))
2205 		goto noentries;
2206 
2207 	if (aobjp->attr_request & (FATTR4_OWNER_MASK | FATTR4_OWNER_GROUP_MASK))
2208 		pug = alloc_ugcache();
2209 
2210 	skip_to_end = 0;
2211 	while (more_data) {
2212 		uint_t namelen;
2213 		uint64_t cookie;
2214 
2215 		/* Get the COOKIE */
2216 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&cookie))
2217 			goto noentries;
2218 
2219 		/* Get the LENGTH of the entry name */
2220 		if (!xdr_u_int(xdrs, &namelen))
2221 			goto noentries;
2222 
2223 		if (!skip_to_end) {
2224 			/*
2225 			 * With the length of the directory entry name
2226 			 * in hand, figure out if there is room left
2227 			 * to encode it for the requestor.  If not,
2228 			 * that is okay, but the rest of the readdir
2229 			 * operation result must be decoded in the
2230 			 * case there are following operations
2231 			 * in the compound request.  Therefore, mark
2232 			 * the rest of the response as "skip" and
2233 			 * decode or skip the remaining data
2234 			 */
2235 			entry_length = DIRENT64_RECLEN(namelen);
2236 			if (space_left < entry_length)
2237 				skip_to_end = 1;
2238 		}
2239 
2240 		/* Get the NAME of the entry */
2241 		if (!skip_to_end) {
2242 			if (!xdr_opaque(xdrs, dp->d_name, namelen))
2243 				goto noentries;
2244 			bzero(&dp->d_name[namelen],
2245 			    DIRENT64_NAMELEN(entry_length) - namelen);
2246 			dp->d_off = last_cookie = cookie;
2247 			dp->d_reclen = entry_length;
2248 		} else {
2249 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &namelen))
2250 				goto noentries;
2251 		}
2252 
2253 		/* Get the attribute BITMAP */
2254 		if (!xdr_bitmap4(xdrs, &resbmap))
2255 			goto noentries;
2256 		/* Get the LENGTH of the attributes */
2257 		if (!xdr_u_int(xdrs, (uint_t *)&attrlen))
2258 			goto noentries;
2259 
2260 		/* Get the ATTRIBUTES */
2261 		if (!skip_to_end) {
2262 			uint32_t *ptr;
2263 
2264 			if (!(resbmap & FATTR4_ACL_MASK) &&
2265 			    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen))
2266 			    != NULL) {
2267 				if (!xdr_ga_fattr_res_inline(ptr, &gar, resbmap,
2268 				    aobjp->attr_request, aobjp->mi, pug))
2269 					goto noentries;
2270 			} else {
2271 				if (!xdr_ga_fattr_res(xdrs, &gar, resbmap,
2272 				    aobjp->attr_request, aobjp->mi, pug))
2273 					goto noentries;
2274 			}
2275 
2276 			/* Fill in the d_ino per the server's fid values */
2277 			/*
2278 			 * Important to note that the mounted on fileid
2279 			 * is returned in d_ino if supported.  This is
2280 			 * expected, readdir returns the mounted on fileid
2281 			 * while stat() returns the fileid of the object
2282 			 * on "top" of the mount.
2283 			 */
2284 			if (gar.n4g_mon_fid_valid)
2285 				dp->d_ino = gar.n4g_mon_fid;
2286 			else if (gar.n4g_va.va_mask & AT_NODEID)
2287 				dp->d_ino = gar.n4g_va.va_nodeid;
2288 			else
2289 				dp->d_ino = 0;
2290 
2291 			/* See about creating an rnode for this entry */
2292 			if ((resbmap &
2293 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) ==
2294 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) {
2295 				nfs4_sharedfh_t *sfhp;
2296 				vnode_t *vp;
2297 
2298 				sfhp = sfh4_put(&ges.n4g_fh_u.n4g_fh,
2299 				    aobjp->mi, NULL);
2300 				vp = makenfs4node(sfhp, &gar,
2301 				    aobjp->dvp->v_vfsp,
2302 				    aobjp->t,
2303 				    aobjp->cr,
2304 				    aobjp->dvp,
2305 				    fn_get(VTOSV(aobjp->dvp)->sv_name,
2306 				    dp->d_name, sfhp));
2307 				sfh4_rele(&sfhp);
2308 				dnlc_update(aobjp->dvp, dp->d_name, vp);
2309 				VN_RELE(vp);
2310 			}
2311 
2312 			dp = (struct dirent64 *)(((caddr_t)dp) + dp->d_reclen);
2313 
2314 			space_left -= entry_length;
2315 
2316 		} else {
2317 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &attrlen))
2318 				goto noentries;
2319 		}
2320 
2321 		/* Get the do-we-have-a-next-entry BOOL */
2322 		if (!xdr_bool(xdrs, &more_data))
2323 			goto noentries;
2324 	}
2325 
2326 	if (pug) {
2327 		kmem_free(pug, sizeof (ug_cache_t));
2328 		pug = NULL;
2329 	}
2330 
2331 	/*
2332 	 * Finish up the rddir cache
2333 	 * If no entries were returned, free up buffer &
2334 	 * set ncookie to the starting cookie for this
2335 	 * readdir request so that the direof caching
2336 	 * will work properly.
2337 	 */
2338 	ASSERT(rdc->entries);
2339 	if (last_cookie == 0) {
2340 		kmem_free(rdc->entries, rdc->entlen);
2341 		rdc->entries = NULL;
2342 		last_cookie = rdc->nfs4_cookie;
2343 	}
2344 
2345 	rdc->actlen = rdc->entlen - space_left;
2346 	rdc->nfs4_ncookie = last_cookie;
2347 
2348 	/* Get the EOF marker */
2349 	if (!xdr_bool(xdrs, &objp->eof))
2350 		goto noentries;
2351 
2352 	/*
2353 	 * If the server returns eof and there were no
2354 	 * skipped entries, set eof
2355 	 */
2356 	rdc->eof = (objp->eof && !skip_to_end) ? TRUE : FALSE;
2357 
2358 	/*
2359 	 * If we encoded entries we are done
2360 	 */
2361 	if (rdc->entries) {
2362 		rdc->error = 0;
2363 		return (TRUE);
2364 	}
2365 
2366 	/*
2367 	 * If there were no entries and we skipped because
2368 	 * there was not enough space, return EINVAL
2369 	 */
2370 	if (skip_to_end) {
2371 		rdc->error = EINVAL;
2372 		return (TRUE);
2373 	}
2374 
2375 	/*
2376 	 * No entries, nothing skipped, and EOF, return OK.
2377 	 */
2378 	if (objp->eof == TRUE) {
2379 		rdc->error = 0;
2380 		return (TRUE);
2381 	}
2382 
2383 	/*
2384 	 * No entries, nothing skipped, and not EOF
2385 	 * probably a bad cookie, return ENOENT.
2386 	 */
2387 	rdc->error = ENOENT;
2388 	return (TRUE);
2389 
2390 noentries:
2391 	if (rdc->entries) {
2392 		kmem_free(rdc->entries, rdc->entlen);
2393 		rdc->entries = NULL;
2394 	}
2395 	if (pug)
2396 		kmem_free(pug, sizeof (ug_cache_t));
2397 	rdc->error = EIO;
2398 	return (FALSE);
2399 }
2400 
2401 /*
2402  * xdr_ga_res
2403  *
2404  * Returns: FALSE on raw data processing errors, TRUE otherwise.
2405  *
2406  * This function pre-processes the OP_GETATTR response, and then
2407  * calls common routines to process the GETATTR fattr4 results into
2408  * vnode attributes and other components that the client is interested
2409  * in. If an error other than an RPC error is encountered, the details
2410  * of the error are filled into objp, although the result of the
2411  * processing is set to TRUE.
2412  */
2413 static bool_t
2414 xdr_ga_res(XDR *xdrs, GETATTR4res *objp, GETATTR4args *aobjp)
2415 {
2416 #ifdef INLINE
2417 	uint32_t *ptr;
2418 #endif
2419 	bitmap4 resbmap;
2420 	uint32_t attrlen;
2421 
2422 	ASSERT(xdrs->x_op == XDR_DECODE);
2423 
2424 	/* Initialize objp attribute error values */
2425 	objp->ga_res.n4g_attrerr =
2426 	    objp->ga_res.n4g_attrwhy = NFS4_GETATTR_OP_OK;
2427 
2428 	if (!xdr_bitmap4(xdrs, &resbmap))
2429 		return (FALSE);
2430 
2431 	/* save the response bitmap for the caller */
2432 	objp->ga_res.n4g_resbmap = resbmap;
2433 
2434 	/* attrlen */
2435 	if (!XDR_GETINT32(xdrs, (int32_t *)&attrlen))
2436 		return (FALSE);
2437 
2438 	/*
2439 	 * Handle case where request and response bitmaps don't match.
2440 	 */
2441 	if (aobjp->attr_request && aobjp->attr_request != resbmap) {
2442 		bitmap4 deltabmap;
2443 
2444 		/*
2445 		 * Return error for case where server sent extra attributes
2446 		 * because the "unknown" attributes may be anywhere in the
2447 		 * xdr stream and can't be properly processed.
2448 		 */
2449 		deltabmap = ((aobjp->attr_request ^ resbmap) & resbmap);
2450 		if (deltabmap) {
2451 			objp->ga_res.n4g_attrerr = EINVAL;
2452 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_BITMAP_ERR;
2453 			return (TRUE);
2454 		}
2455 
2456 		/*
2457 		 * Return error for case where there is a mandatory
2458 		 * attribute missing in the server response. Note that
2459 		 * missing recommended attributes are evaluated in the
2460 		 * specific routines that decode the server response.
2461 		 */
2462 		deltabmap = ((aobjp->attr_request ^ resbmap)
2463 		    & aobjp->attr_request);
2464 		if ((deltabmap & FATTR4_MANDATTR_MASK)) {
2465 			objp->ga_res.n4g_attrerr = EINVAL;
2466 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_MANDATTR_ERR;
2467 			return (TRUE);
2468 		}
2469 	}
2470 
2471 	/* Check to see if the attrs can be inlined and go for it if so */
2472 #ifdef INLINE
2473 	if (!(resbmap & FATTR4_ACL_MASK) &&
2474 	    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen)) != NULL)
2475 		return (xdr_ga_fattr_res_inline(ptr, &objp->ga_res,
2476 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
2477 	else
2478 #endif
2479 		return (xdr_ga_fattr_res(xdrs, &objp->ga_res,
2480 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
2481 }
2482 
2483 #if defined(DEBUG) && !defined(lint)
2484 /*
2485  * We assume that an enum is a 32-bit value, check it once
2486  */
2487 static enum szchk { SZVAL } szchkvar;
2488 #endif
2489 
2490 bool_t
2491 xdr_settime4(XDR *xdrs, settime4 *objp)
2492 {
2493 #if defined(DEBUG) && !defined(lint)
2494 	ASSERT(sizeof (szchkvar) == sizeof (int32_t));
2495 #endif
2496 	if (xdrs->x_op == XDR_FREE)
2497 		return (TRUE);
2498 
2499 	if (!xdr_int(xdrs, (int *)&objp->set_it))
2500 		return (FALSE);
2501 	if (objp->set_it != SET_TO_CLIENT_TIME4)
2502 		return (TRUE);
2503 	/* xdr_nfstime4 */
2504 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->time.seconds))
2505 		return (FALSE);
2506 	return (xdr_u_int(xdrs, &objp->time.nseconds));
2507 }
2508 
2509 static bool_t
2510 xdr_fattr4(XDR *xdrs, fattr4 *objp)
2511 {
2512 	if (xdrs->x_op != XDR_FREE) {
2513 		if (!xdr_bitmap4(xdrs, &objp->attrmask))
2514 			return (FALSE);
2515 		return (xdr_bytes(xdrs, (char **)&objp->attrlist4,
2516 		    (uint_t *)&objp->attrlist4_len, NFS4_FATTR4_LIMIT));
2517 	}
2518 
2519 	/*
2520 	 * Optimized free case
2521 	 */
2522 	if (objp->attrlist4 != NULL)
2523 		kmem_free(objp->attrlist4, objp->attrlist4_len);
2524 	return (TRUE);
2525 }
2526 
2527 static bool_t
2528 xdr_ACCESS4res(XDR *xdrs, ACCESS4res *objp)
2529 {
2530 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
2531 		return (FALSE);
2532 	if (objp->status != NFS4_OK)
2533 		return (TRUE);
2534 	if (!xdr_u_int(xdrs, &objp->supported))
2535 		return (FALSE);
2536 	return (xdr_u_int(xdrs, &objp->access));
2537 }
2538 
2539 static bool_t
2540 xdr_CLOSE4args(XDR *xdrs, CLOSE4args *objp)
2541 {
2542 	if (!xdr_u_int(xdrs, &objp->seqid))
2543 		return (FALSE);
2544 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
2545 		return (FALSE);
2546 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
2547 }
2548 
2549 static bool_t
2550 xdr_CLOSE4res(XDR *xdrs, CLOSE4res *objp)
2551 {
2552 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
2553 		return (FALSE);
2554 	if (objp->status != NFS4_OK)
2555 		return (TRUE);
2556 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
2557 		return (FALSE);
2558 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
2559 }
2560 
2561 static bool_t
2562 xdr_CREATE4args(XDR *xdrs, CREATE4args *objp)
2563 {
2564 	if (xdrs->x_op != XDR_FREE) {
2565 		if (!xdr_int(xdrs, (int32_t *)&objp->type))
2566 			return (FALSE);
2567 		switch (objp->type) {
2568 		case NF4LNK:
2569 			if (!xdr_bytes(xdrs,
2570 			    (char **)&objp->ftype4_u.linkdata.utf8string_val,
2571 			    (uint_t *)&objp->ftype4_u.linkdata.utf8string_len,
2572 			    NFS4_MAX_UTF8STRING))
2573 				return (FALSE);
2574 			break;
2575 		case NF4BLK:
2576 		case NF4CHR:
2577 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata1))
2578 				return (FALSE);
2579 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata2))
2580 				return (FALSE);
2581 			break;
2582 		case NF4SOCK:
2583 		case NF4FIFO:
2584 		case NF4DIR:
2585 		default:
2586 			break;	/* server should return NFS4ERR_BADTYPE */
2587 		}
2588 		if (!xdr_bytes(xdrs, (char **)&objp->objname.utf8string_val,
2589 		    (uint_t *)&objp->objname.utf8string_len,
2590 		    NFS4_MAX_UTF8STRING))
2591 			return (FALSE);
2592 		return (xdr_fattr4(xdrs, &objp->createattrs));
2593 	}
2594 
2595 	/*
2596 	 * Optimized free case
2597 	 */
2598 	if (objp->type == NF4LNK) {
2599 		if (objp->ftype4_u.linkdata.utf8string_val != NULL)
2600 			kmem_free(objp->ftype4_u.linkdata.utf8string_val,
2601 			    objp->ftype4_u.linkdata.utf8string_len);
2602 	}
2603 	if (objp->objname.utf8string_val != NULL)
2604 		kmem_free(objp->objname.utf8string_val,
2605 		    objp->objname.utf8string_len);
2606 	return (xdr_fattr4(xdrs, &objp->createattrs));
2607 }
2608 
2609 static bool_t
2610 xdr_CREATE4cargs(XDR *xdrs, CREATE4cargs *objp)
2611 {
2612 	int len;
2613 
2614 	ASSERT(xdrs->x_op == XDR_ENCODE);
2615 
2616 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->type))
2617 		return (FALSE);
2618 	switch (objp->type) {
2619 	case NF4LNK:
2620 		len = strlen(objp->ftype4_u.clinkdata);
2621 		if (len > NFS4_MAX_UTF8STRING)
2622 			return (FALSE);
2623 		if (!XDR_PUTINT32(xdrs, &len))
2624 			return (FALSE);
2625 		if (!xdr_opaque(xdrs, objp->ftype4_u.clinkdata, len))
2626 			return (FALSE);
2627 		break;
2628 	case NF4BLK:
2629 	case NF4CHR:
2630 		if (!XDR_PUTINT32(xdrs,
2631 		    (int32_t *)&objp->ftype4_u.devdata.specdata1))
2632 			return (FALSE);
2633 		if (!XDR_PUTINT32(xdrs,
2634 		    (int32_t *)&objp->ftype4_u.devdata.specdata2))
2635 			return (FALSE);
2636 		break;
2637 	case NF4SOCK:
2638 	case NF4FIFO:
2639 	case NF4DIR:
2640 	default:
2641 		break;	/* server should return NFS4ERR_BADTYPE */
2642 	}
2643 
2644 	len = strlen(objp->cname);
2645 	if (len > NFS4_MAX_UTF8STRING)
2646 		return (FALSE);
2647 	if (!XDR_PUTINT32(xdrs, &len))
2648 		return (FALSE);
2649 	if (!xdr_opaque(xdrs, objp->cname, len))
2650 		return (FALSE);
2651 
2652 	return (xdr_fattr4(xdrs, &objp->createattrs));
2653 }
2654 
2655 static bool_t
2656 xdr_CREATE4res(XDR *xdrs, CREATE4res *objp)
2657 {
2658 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
2659 		return (FALSE);
2660 	if (objp->status != NFS4_OK)
2661 		return (TRUE);
2662 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
2663 		return (FALSE);
2664 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
2665 		return (FALSE);
2666 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
2667 		return (FALSE);
2668 	return (xdr_bitmap4(xdrs, &objp->attrset));
2669 }
2670 
2671 static bool_t
2672 xdr_LINK4res(XDR *xdrs, LINK4res *objp)
2673 {
2674 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
2675 		return (FALSE);
2676 	if (objp->status != NFS4_OK)
2677 		return (TRUE);
2678 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
2679 		return (FALSE);
2680 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
2681 		return (FALSE);
2682 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after));
2683 }
2684 
2685 static bool_t
2686 xdr_LOCK4args(XDR *xdrs, LOCK4args *objp)
2687 {
2688 	if (xdrs->x_op != XDR_FREE) {
2689 		if (!xdr_int(xdrs, (int *)&objp->locktype))
2690 			return (FALSE);
2691 		if (!xdr_bool(xdrs, &objp->reclaim))
2692 			return (FALSE);
2693 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
2694 			return (FALSE);
2695 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
2696 			return (FALSE);
2697 		if (!xdr_bool(xdrs, &objp->locker.new_lock_owner))
2698 			return (FALSE);
2699 		if (objp->locker.new_lock_owner == TRUE) {
2700 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
2701 			    open_seqid))
2702 				return (FALSE);
2703 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
2704 			    open_stateid.seqid))
2705 				return (FALSE);
2706 			if (!xdr_opaque(xdrs, objp->locker.locker4_u.open_owner.
2707 			    open_stateid.other, 12))
2708 				return (FALSE);
2709 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
2710 			    lock_seqid))
2711 				return (FALSE);
2712 			if (!xdr_u_longlong_t(xdrs,
2713 			    (u_longlong_t *)&objp->locker.locker4_u.
2714 			    open_owner.lock_owner.clientid))
2715 				return (FALSE);
2716 			return (xdr_bytes(xdrs,
2717 			    (char **)&objp->locker.locker4_u.open_owner.
2718 			    lock_owner.owner_val,
2719 			    (uint_t *)&objp->locker.locker4_u.open_owner.
2720 			    lock_owner.owner_len,
2721 			    NFS4_OPAQUE_LIMIT));
2722 		}
2723 
2724 		if (objp->locker.new_lock_owner != FALSE)
2725 			return (FALSE);
2726 
2727 		if (!xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
2728 		    lock_stateid.seqid))
2729 			return (FALSE);
2730 		if (!xdr_opaque(xdrs, objp->locker.locker4_u.lock_owner.
2731 		    lock_stateid.other, 12))
2732 			return (FALSE);
2733 		return (xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
2734 		    lock_seqid));
2735 	}
2736 
2737 	/*
2738 	 * Optimized free case
2739 	 */
2740 	if (objp->locker.new_lock_owner == TRUE) {
2741 		if (objp->locker.locker4_u.open_owner.lock_owner.owner_val !=
2742 		    NULL) {
2743 			kmem_free(objp->locker.locker4_u.open_owner.lock_owner.
2744 			    owner_val,
2745 			    objp->locker.locker4_u.open_owner.lock_owner.
2746 			    owner_len);
2747 		}
2748 	}
2749 
2750 	return (TRUE);
2751 }
2752 
2753 static bool_t
2754 xdr_LOCK4res(XDR *xdrs, LOCK4res *objp)
2755 {
2756 	if (xdrs->x_op != XDR_FREE) {
2757 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
2758 			return (FALSE);
2759 		if (objp->status == NFS4_OK) {
2760 			if (!xdr_u_int(xdrs,
2761 			    &objp->LOCK4res_u.lock_stateid.seqid))
2762 				return (FALSE);
2763 			return (xdr_opaque(xdrs,
2764 			    objp->LOCK4res_u.lock_stateid.other, 12));
2765 		}
2766 		if (objp->status != NFS4ERR_DENIED)
2767 			return (TRUE);
2768 
2769 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
2770 		    denied.offset))
2771 			return (FALSE);
2772 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
2773 		    denied.length))
2774 			return (FALSE);
2775 		if (!xdr_int(xdrs, (int *)&objp->LOCK4res_u.denied.locktype))
2776 			return (FALSE);
2777 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
2778 		    denied.owner.clientid))
2779 			return (FALSE);
2780 		return (xdr_bytes(xdrs,
2781 		    (char **)&objp->LOCK4res_u.denied.owner.owner_val,
2782 		    (uint_t *)&objp->LOCK4res_u.denied.owner.owner_len,
2783 		    NFS4_OPAQUE_LIMIT));
2784 	}
2785 
2786 	/*
2787 	 * Optimized free case
2788 	 */
2789 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
2790 		return (TRUE);
2791 
2792 	if (objp->LOCK4res_u.denied.owner.owner_val != NULL)
2793 		kmem_free(objp->LOCK4res_u.denied.owner.owner_val,
2794 		    objp->LOCK4res_u.denied.owner.owner_len);
2795 	return (TRUE);
2796 }
2797 
2798 static bool_t
2799 xdr_LOCKT4args(XDR *xdrs, LOCKT4args *objp)
2800 {
2801 	if (xdrs->x_op != XDR_FREE) {
2802 		if (!xdr_int(xdrs, (int *)&objp->locktype))
2803 			return (FALSE);
2804 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
2805 			return (FALSE);
2806 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
2807 			return (FALSE);
2808 		if (!xdr_u_longlong_t(xdrs,
2809 		    (u_longlong_t *)&objp->owner.clientid))
2810 			return (FALSE);
2811 		return (xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
2812 		    (uint_t *)&objp->owner.owner_len,
2813 		    NFS4_OPAQUE_LIMIT));
2814 	}
2815 
2816 	/*
2817 	 * Optimized free case
2818 	 */
2819 	if (objp->owner.owner_val != NULL)
2820 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
2821 	return (TRUE);
2822 }
2823 
2824 static bool_t
2825 xdr_LOCKT4res(XDR *xdrs, LOCKT4res *objp)
2826 {
2827 	if (xdrs->x_op != XDR_FREE) {
2828 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
2829 			return (FALSE);
2830 		if (objp->status == NFS4_OK)
2831 			return (TRUE);
2832 		if (objp->status != NFS4ERR_DENIED)
2833 			return (TRUE);
2834 		/* xdr_LOCK4denied */
2835 		if (!xdr_u_longlong_t(xdrs,
2836 		    (u_longlong_t *)&objp->denied.offset))
2837 			return (FALSE);
2838 		if (!xdr_u_longlong_t(xdrs,
2839 		    (u_longlong_t *)&objp->denied.length))
2840 			return (FALSE);
2841 		if (!xdr_int(xdrs, (int *)&objp->denied.locktype))
2842 			return (FALSE);
2843 		if (!xdr_u_longlong_t(xdrs,
2844 		    (u_longlong_t *)&objp->denied.owner.clientid))
2845 			return (FALSE);
2846 		return (xdr_bytes(xdrs,
2847 		    (char **)&objp->denied.owner.owner_val,
2848 		    (uint_t *)&objp->denied.owner.owner_len,
2849 		    NFS4_OPAQUE_LIMIT));
2850 	}
2851 
2852 	/*
2853 	 * Optimized free case
2854 	 */
2855 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
2856 		return (TRUE);
2857 	if (objp->denied.owner.owner_val != NULL)
2858 		kmem_free(objp->denied.owner.owner_val,
2859 		    objp->denied.owner.owner_len);
2860 	return (TRUE);
2861 }
2862 
2863 static bool_t
2864 xdr_LOCKU4args(XDR *xdrs, LOCKU4args *objp)
2865 {
2866 	if (!xdr_int(xdrs, (int *)&objp->locktype))
2867 		return (FALSE);
2868 	if (!xdr_u_int(xdrs, &objp->seqid))
2869 		return (FALSE);
2870 	if (!xdr_u_int(xdrs, &objp->lock_stateid.seqid))
2871 		return (FALSE);
2872 	if (!xdr_opaque(xdrs, objp->lock_stateid.other, 12))
2873 		return (FALSE);
2874 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
2875 		return (FALSE);
2876 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length));
2877 }
2878 
2879 static bool_t
2880 xdr_OPEN4args(XDR *xdrs, OPEN4args *objp)
2881 {
2882 	if (xdrs->x_op != XDR_FREE) {
2883 		if (!xdr_u_int(xdrs, &objp->seqid))
2884 			return (FALSE);
2885 		if (!xdr_u_int(xdrs, &objp->share_access))
2886 			return (FALSE);
2887 		if (!xdr_u_int(xdrs, &objp->share_deny))
2888 			return (FALSE);
2889 
2890 		/* xdr_open_owner4 */
2891 		if (!xdr_u_longlong_t(xdrs,
2892 		    (u_longlong_t *)&objp->owner.clientid))
2893 			return (FALSE);
2894 		if (!xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
2895 		    (uint_t *)&objp->owner.owner_len,
2896 		    NFS4_OPAQUE_LIMIT))
2897 			return (FALSE);
2898 
2899 		/* xdr_openflag4 */
2900 		if (!xdr_int(xdrs, (int *)&objp->opentype))
2901 			return (FALSE);
2902 		if (objp->opentype == OPEN4_CREATE) {
2903 
2904 			/* xdr_createhow4 */
2905 			if (!xdr_int(xdrs, (int *)&objp->mode))
2906 				return (FALSE);
2907 			switch (objp->mode) {
2908 			case UNCHECKED4:
2909 			case GUARDED4:
2910 				if (!xdr_fattr4(xdrs,
2911 				    &objp->createhow4_u.createattrs))
2912 					return (FALSE);
2913 				break;
2914 			case EXCLUSIVE4:
2915 				if (!xdr_u_longlong_t(xdrs,
2916 				    (u_longlong_t *)&objp->createhow4_u.
2917 				    createverf))
2918 					return (FALSE);
2919 				break;
2920 			default:
2921 				return (FALSE);
2922 			}
2923 		}
2924 
2925 		/* xdr_open_claim4 */
2926 		if (!xdr_int(xdrs, (int *)&objp->claim))
2927 			return (FALSE);
2928 
2929 		switch (objp->claim) {
2930 		case CLAIM_NULL:
2931 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
2932 			    file.utf8string_val,
2933 			    (uint_t *)&objp->open_claim4_u.file.
2934 			    utf8string_len,
2935 			    NFS4_MAX_UTF8STRING));
2936 		case CLAIM_PREVIOUS:
2937 			return (xdr_int(xdrs,
2938 			    (int *)&objp->open_claim4_u.delegate_type));
2939 		case CLAIM_DELEGATE_CUR:
2940 			if (!xdr_u_int(xdrs, (uint_t *)&objp->open_claim4_u.
2941 			    delegate_cur_info.delegate_stateid.seqid))
2942 				return (FALSE);
2943 			if (!xdr_opaque(xdrs, objp->open_claim4_u.
2944 			    delegate_cur_info.delegate_stateid.other,
2945 			    12))
2946 				return (FALSE);
2947 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
2948 			    delegate_cur_info.file.utf8string_val,
2949 			    (uint_t *)&objp->open_claim4_u.
2950 			    delegate_cur_info.file.utf8string_len,
2951 			    NFS4_MAX_UTF8STRING));
2952 		case CLAIM_DELEGATE_PREV:
2953 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
2954 			    file_delegate_prev.utf8string_val,
2955 			    (uint_t *)&objp->open_claim4_u.
2956 			    file_delegate_prev.utf8string_len,
2957 			    NFS4_MAX_UTF8STRING));
2958 		default:
2959 			return (FALSE);
2960 		}
2961 	}
2962 
2963 	/*
2964 	 * Optimized free case
2965 	 */
2966 	if (objp->owner.owner_val != NULL)
2967 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
2968 
2969 	if (objp->opentype == OPEN4_CREATE) {
2970 		switch (objp->mode) {
2971 		case UNCHECKED4:
2972 		case GUARDED4:
2973 			(void) xdr_fattr4(xdrs,
2974 			    &objp->createhow4_u.createattrs);
2975 			break;
2976 		case EXCLUSIVE4:
2977 		default:
2978 			break;
2979 		}
2980 	}
2981 
2982 	switch (objp->claim) {
2983 	case CLAIM_NULL:
2984 		if (objp->open_claim4_u.file.utf8string_val != NULL)
2985 			kmem_free(objp->open_claim4_u.file.utf8string_val,
2986 			    objp->open_claim4_u.file.utf8string_len);
2987 		return (TRUE);
2988 	case CLAIM_PREVIOUS:
2989 		return (TRUE);
2990 	case CLAIM_DELEGATE_CUR:
2991 		if (objp->open_claim4_u.delegate_cur_info.file.utf8string_val !=
2992 		    NULL) {
2993 			kmem_free(objp->open_claim4_u.delegate_cur_info.file.
2994 			    utf8string_val,
2995 			    objp->open_claim4_u.delegate_cur_info.file.
2996 			    utf8string_len);
2997 		}
2998 		return (TRUE);
2999 	case CLAIM_DELEGATE_PREV:
3000 		if (objp->open_claim4_u.file_delegate_prev.utf8string_val !=
3001 		    NULL) {
3002 			kmem_free(objp->open_claim4_u.file_delegate_prev.
3003 			    utf8string_val,
3004 			    objp->open_claim4_u.file_delegate_prev.
3005 			    utf8string_len);
3006 		}
3007 		return (TRUE);
3008 	default:
3009 		return (TRUE);
3010 	}
3011 }
3012 
3013 static bool_t
3014 xdr_OPEN4cargs(XDR *xdrs, OPEN4cargs *objp)
3015 {
3016 	int op;
3017 	int len;
3018 	rpc_inline_t *ptr;
3019 
3020 	ASSERT(xdrs->x_op == XDR_ENCODE);
3021 
3022 	/*
3023 	 * We must always define the client's open_owner to be
3024 	 * 4 byte aligned and sized.
3025 	 */
3026 	ASSERT(objp->owner.owner_len <= NFS4_OPAQUE_LIMIT);
3027 	ASSERT(!(objp->owner.owner_len % BYTES_PER_XDR_UNIT));
3028 
3029 	len = objp->owner.owner_len;
3030 	if ((ptr = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + len)) != NULL) {
3031 		int i;
3032 		int32_t *ip;
3033 
3034 		IXDR_PUT_U_INT32(ptr, OP_OPEN);
3035 		IXDR_PUT_U_INT32(ptr, objp->seqid);
3036 		IXDR_PUT_U_INT32(ptr, objp->share_access);
3037 		IXDR_PUT_U_INT32(ptr, objp->share_deny);
3038 
3039 		/* xdr_open_owner4 */
3040 		IXDR_PUT_HYPER(ptr, objp->owner.clientid);
3041 		IXDR_PUT_U_INT32(ptr, objp->owner.owner_len);
3042 		/* We know this is very short so don't bcopy */
3043 		ip = (int32_t *)objp->owner.owner_val;
3044 		len /= BYTES_PER_XDR_UNIT;
3045 		for (i = 0; i < len; i++)
3046 			*ptr++ = *ip++;
3047 
3048 		/* xdr_openflag4 */
3049 		IXDR_PUT_U_INT32(ptr, objp->opentype);
3050 	} else {
3051 		op = OP_OPEN;
3052 		if (!XDR_PUTINT32(xdrs, (int32_t *)&op))
3053 			return (FALSE);
3054 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->seqid))
3055 			return (FALSE);
3056 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_access))
3057 			return (FALSE);
3058 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_deny))
3059 			return (FALSE);
3060 
3061 		/* xdr_open_owner4 */
3062 		if (!xdr_u_longlong_t(xdrs,
3063 		    (u_longlong_t *)&objp->owner.clientid))
3064 			return (FALSE);
3065 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->owner.owner_len))
3066 			return (FALSE);
3067 		if (!xdr_opaque(xdrs, objp->owner.owner_val,
3068 		    objp->owner.owner_len))
3069 			return (FALSE);
3070 
3071 		/* xdr_openflag4 */
3072 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->opentype))
3073 			return (FALSE);
3074 	}
3075 
3076 	if (objp->opentype == OPEN4_CREATE) {
3077 		/* xdr_createhow4 */
3078 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->mode))
3079 			return (FALSE);
3080 		switch (objp->mode) {
3081 		case UNCHECKED4:
3082 		case GUARDED4:
3083 			if (!xdr_fattr4(xdrs,
3084 			    &objp->createhow4_u.createattrs))
3085 				return (FALSE);
3086 			break;
3087 		case EXCLUSIVE4:
3088 			if (!xdr_u_longlong_t(xdrs,
3089 			    (u_longlong_t *)&objp->createhow4_u.
3090 			    createverf))
3091 				return (FALSE);
3092 			break;
3093 		default:
3094 			return (FALSE);
3095 		}
3096 	}
3097 
3098 	/* xdr_open_claim4 */
3099 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->claim))
3100 		return (FALSE);
3101 
3102 	switch (objp->claim) {
3103 	case CLAIM_NULL:
3104 		len = strlen(objp->open_claim4_u.cfile);
3105 		if (len > NFS4_MAX_UTF8STRING)
3106 			return (FALSE);
3107 		if (XDR_PUTINT32(xdrs, &len)) {
3108 			return (xdr_opaque(xdrs,
3109 			    objp->open_claim4_u.cfile, len));
3110 		}
3111 		return (FALSE);
3112 	case CLAIM_PREVIOUS:
3113 		return (XDR_PUTINT32(xdrs,
3114 		    (int32_t *)&objp->open_claim4_u.delegate_type));
3115 	case CLAIM_DELEGATE_CUR:
3116 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->open_claim4_u.
3117 		    delegate_cur_info.delegate_stateid.seqid))
3118 			return (FALSE);
3119 		if (!xdr_opaque(xdrs, objp->open_claim4_u.
3120 		    delegate_cur_info.delegate_stateid.other,
3121 		    12))
3122 			return (FALSE);
3123 		len = strlen(objp->open_claim4_u.delegate_cur_info.cfile);
3124 		if (len > NFS4_MAX_UTF8STRING)
3125 			return (FALSE);
3126 		if (XDR_PUTINT32(xdrs, &len)) {
3127 			return (xdr_opaque(xdrs,
3128 			    objp->open_claim4_u.delegate_cur_info.cfile,
3129 			    len));
3130 		}
3131 		return (FALSE);
3132 	case CLAIM_DELEGATE_PREV:
3133 		len = strlen(objp->open_claim4_u.cfile_delegate_prev);
3134 		if (len > NFS4_MAX_UTF8STRING)
3135 			return (FALSE);
3136 		if (XDR_PUTINT32(xdrs, &len)) {
3137 			return (xdr_opaque(xdrs,
3138 			    objp->open_claim4_u.cfile_delegate_prev, len));
3139 		}
3140 		return (FALSE);
3141 	default:
3142 		return (FALSE);
3143 	}
3144 }
3145 
3146 static bool_t
3147 xdr_OPEN4res(XDR *xdrs, OPEN4res *objp)
3148 {
3149 	if (xdrs->x_op != XDR_FREE) {
3150 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
3151 			return (FALSE);
3152 		if (objp->status != NFS4_OK)
3153 			return (TRUE);
3154 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
3155 			return (FALSE);
3156 		if (!xdr_opaque(xdrs, objp->stateid.other, 12))
3157 			return (FALSE);
3158 		if (!xdr_bool(xdrs, &objp->cinfo.atomic))
3159 			return (FALSE);
3160 		if (!xdr_u_longlong_t(xdrs,
3161 		    (u_longlong_t *)&objp->cinfo.before))
3162 			return (FALSE);
3163 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
3164 			return (FALSE);
3165 		if (!xdr_u_int(xdrs, &objp->rflags))
3166 			return (FALSE);
3167 		if (!xdr_bitmap4(xdrs, &objp->attrset))
3168 			return (FALSE);
3169 		if (!xdr_int(xdrs,
3170 		    (int *)&objp->delegation.delegation_type))
3171 			return (FALSE);
3172 		switch (objp->delegation.delegation_type) {
3173 		case OPEN_DELEGATE_NONE:
3174 			return (TRUE);
3175 		case OPEN_DELEGATE_READ:
3176 			if (!xdr_u_int(xdrs, &objp->delegation.
3177 			    open_delegation4_u.read.stateid.seqid))
3178 				return (FALSE);
3179 			if (!xdr_opaque(xdrs, objp->delegation.
3180 			    open_delegation4_u.read.stateid.other,
3181 			    12))
3182 				return (FALSE);
3183 			if (!xdr_bool(xdrs, &objp->delegation.
3184 			    open_delegation4_u.read.recall))
3185 				return (FALSE);
3186 			return (xdr_nfsace4(xdrs, &objp->delegation.
3187 			    open_delegation4_u.read.permissions));
3188 		case OPEN_DELEGATE_WRITE:
3189 			if (!xdr_u_int(xdrs, &objp->delegation.
3190 			    open_delegation4_u.write.stateid.seqid))
3191 				return (FALSE);
3192 			if (!xdr_opaque(xdrs, objp->delegation.
3193 			    open_delegation4_u.write.stateid.other,
3194 			    12))
3195 				return (FALSE);
3196 			if (!xdr_bool(xdrs, &objp->delegation.
3197 			    open_delegation4_u.write.recall))
3198 				return (FALSE);
3199 			if (!xdr_int(xdrs, (int *)&objp->delegation.
3200 			    open_delegation4_u.write.space_limit.
3201 			    limitby))
3202 				return (FALSE);
3203 			switch (objp->delegation.
3204 			    open_delegation4_u.write.space_limit.
3205 			    limitby) {
3206 			case NFS_LIMIT_SIZE:
3207 				if (!xdr_u_longlong_t(xdrs,
3208 				    (u_longlong_t *)&objp->delegation.
3209 				    open_delegation4_u.write.space_limit.
3210 				    nfs_space_limit4_u.filesize))
3211 					return (FALSE);
3212 				break;
3213 			case NFS_LIMIT_BLOCKS:
3214 				if (!xdr_u_int(xdrs,
3215 				    &objp->delegation.open_delegation4_u.write.
3216 				    space_limit.nfs_space_limit4_u.
3217 				    mod_blocks.num_blocks))
3218 					return (FALSE);
3219 				if (!xdr_u_int(xdrs, &objp->delegation.
3220 				    open_delegation4_u.write.space_limit.
3221 				    nfs_space_limit4_u.mod_blocks.
3222 				    bytes_per_block))
3223 					return (FALSE);
3224 				break;
3225 			default:
3226 				return (FALSE);
3227 			}
3228 			return (xdr_nfsace4(xdrs, &objp->delegation.
3229 			    open_delegation4_u.write.permissions));
3230 		}
3231 		return (FALSE);
3232 	}
3233 
3234 	/*
3235 	 * Optimized free case
3236 	 */
3237 	if (objp->status != NFS4_OK)
3238 		return (TRUE);
3239 
3240 	switch (objp->delegation.delegation_type) {
3241 	case OPEN_DELEGATE_NONE:
3242 		return (TRUE);
3243 	case OPEN_DELEGATE_READ:
3244 		return (xdr_nfsace4(xdrs, &objp->delegation.
3245 		    open_delegation4_u.read.permissions));
3246 	case OPEN_DELEGATE_WRITE:
3247 		switch (objp->delegation.
3248 		    open_delegation4_u.write.space_limit.limitby) {
3249 		case NFS_LIMIT_SIZE:
3250 		case NFS_LIMIT_BLOCKS:
3251 			break;
3252 		default:
3253 			return (FALSE);
3254 		}
3255 		return (xdr_nfsace4(xdrs, &objp->delegation.
3256 		    open_delegation4_u.write.permissions));
3257 	}
3258 	return (FALSE);
3259 }
3260 
3261 static bool_t
3262 xdr_OPEN_CONFIRM4res(XDR *xdrs, OPEN_CONFIRM4res *objp)
3263 {
3264 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
3265 		return (FALSE);
3266 	if (objp->status != NFS4_OK)
3267 		return (TRUE);
3268 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
3269 		return (FALSE);
3270 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
3271 }
3272 
3273 static bool_t
3274 xdr_OPEN_DOWNGRADE4args(XDR *xdrs, OPEN_DOWNGRADE4args *objp)
3275 {
3276 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
3277 		return (FALSE);
3278 	if (!xdr_opaque(xdrs, objp->open_stateid.other, 12))
3279 		return (FALSE);
3280 	if (!xdr_u_int(xdrs, &objp->seqid))
3281 		return (FALSE);
3282 	if (!xdr_u_int(xdrs, &objp->share_access))
3283 		return (FALSE);
3284 	return (xdr_u_int(xdrs, &objp->share_deny));
3285 }
3286 
3287 static bool_t
3288 xdr_OPEN_DOWNGRADE4res(XDR *xdrs, OPEN_DOWNGRADE4res *objp)
3289 {
3290 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
3291 		return (FALSE);
3292 	if (objp->status != NFS4_OK)
3293 		return (TRUE);
3294 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
3295 		return (FALSE);
3296 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
3297 }
3298 
3299 static bool_t
3300 xdr_READ4args(XDR *xdrs, READ4args *objp)
3301 {
3302 	rdma_chunkinfo_t rci;
3303 	rdma_wlist_conn_info_t rwci;
3304 	struct xdr_ops *xops = xdrrdma_xops();
3305 
3306 	if (!xdr_u_int(xdrs, &objp->stateid.seqid))
3307 		return (FALSE);
3308 	if (!xdr_opaque(xdrs, objp->stateid.other, 12))
3309 		return (FALSE);
3310 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
3311 		return (FALSE);
3312 	if (!xdr_u_int(xdrs, &objp->count))
3313 		return (FALSE);
3314 
3315 	DTRACE_PROBE1(xdr__i__read4args_buf_len,
3316 	    int, objp->count);
3317 
3318 	objp->wlist = NULL;
3319 
3320 	if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
3321 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
3322 		rci.rci_len = objp->count;
3323 		(void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
3324 	}
3325 
3326 	if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
3327 		return (TRUE);
3328 
3329 	if (xdrs->x_op == XDR_ENCODE) {
3330 		if (objp->res_uiop != NULL) {
3331 			rci.rci_type = RCI_WRITE_UIO_CHUNK;
3332 			rci.rci_a.rci_uiop = objp->res_uiop;
3333 			rci.rci_len = objp->count;
3334 			rci.rci_clpp = &objp->wlist;
3335 		} else {
3336 			rci.rci_type = RCI_WRITE_ADDR_CHUNK;
3337 			rci.rci_a.rci_addr = objp->res_data_val_alt;
3338 			rci.rci_len = objp->count;
3339 			rci.rci_clpp = &objp->wlist;
3340 		}
3341 
3342 		return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
3343 	}
3344 
3345 	/* XDR_DECODE case */
3346 	(void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
3347 	objp->wlist = rwci.rwci_wlist;
3348 	objp->conn = rwci.rwci_conn;
3349 
3350 	return (TRUE);
3351 }
3352 
3353 static bool_t
3354 xdr_READ4res(XDR *xdrs, READ4res *objp)
3355 {
3356 	mblk_t *mp;
3357 
3358 	if (xdrs->x_op == XDR_DECODE)
3359 		return (FALSE);
3360 
3361 	if (xdrs->x_op == XDR_FREE) {
3362 		/*
3363 		 * Optimized free case
3364 		 */
3365 		if (objp->status != NFS4_OK)
3366 			return (TRUE);
3367 		if (objp->data_val != NULL)
3368 			kmem_free(objp->data_val, objp->data_len);
3369 		return (TRUE);
3370 	}
3371 
3372 	/* on with ENCODE paths */
3373 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->status))
3374 		return (FALSE);
3375 	if (objp->status != NFS4_OK)
3376 		return (TRUE);
3377 
3378 	if (!XDR_PUTINT32(xdrs, &objp->eof))
3379 		return (FALSE);
3380 
3381 	mp = objp->mblk;
3382 	if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
3383 		if (xdrmblk_putmblk(xdrs, mp, objp->data_len) == TRUE) {
3384 			objp->mblk = NULL;
3385 			return (TRUE);
3386 		}
3387 	} else if (mp == NULL) {
3388 		if (xdr_u_int(xdrs, &objp->data_len) == FALSE) {
3389 			return (FALSE);
3390 		}
3391 		/*
3392 		 * If read data sent by wlist (RDMA_WRITE), don't do
3393 		 * xdr_bytes() below.   RDMA_WRITE transfers the data.
3394 		 * Note: this is encode-only because the client code
3395 		 * uses xdr_READ4res_clnt to decode results.
3396 		 */
3397 		if (objp->wlist) {
3398 			if (objp->data_len != 0) {
3399 				return (xdrrdma_send_read_data(
3400 				    xdrs, objp->data_len, objp->wlist));
3401 			}
3402 			return (TRUE);
3403 		}
3404 	}
3405 
3406 	return (xdr_bytes(xdrs, (char **)&objp->data_val,
3407 	    (uint_t *)&objp->data_len,
3408 	    objp->data_len));
3409 }
3410 
3411 static bool_t
3412 xdr_READ4res_clnt(XDR *xdrs, READ4res *objp, READ4args *aobjp)
3413 {
3414 	mblk_t *mp;
3415 	size_t n;
3416 	int error;
3417 	uint_t size = aobjp->res_maxsize;
3418 	count4 ocount;
3419 
3420 	if (xdrs->x_op == XDR_ENCODE)
3421 		return (FALSE);
3422 
3423 	if (xdrs->x_op == XDR_FREE) {
3424 		/*
3425 		 * Optimized free case
3426 		 */
3427 		if (objp->status != NFS4_OK)
3428 			return (TRUE);
3429 		if (objp->data_val != NULL)
3430 			kmem_free(objp->data_val, objp->data_len);
3431 		return (TRUE);
3432 	}
3433 
3434 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
3435 		return (FALSE);
3436 	if (objp->status != NFS4_OK)
3437 		return (TRUE);
3438 
3439 	if (!XDR_GETINT32(xdrs, &objp->eof))
3440 		return (FALSE);
3441 
3442 
3443 	/*
3444 	 * This is a special case such that the caller is providing a
3445 	 * uio as a guide to eventual data location; this is used for
3446 	 * handling DIRECTIO reads.
3447 	 */
3448 	if (aobjp->res_uiop != NULL) {
3449 		struct uio *uiop = aobjp->res_uiop;
3450 		int32_t *ptr;
3451 
3452 		if (xdrs->x_ops == &xdrmblk_ops) {
3453 			if (!xdrmblk_getmblk(xdrs, &mp, &objp->data_len))
3454 				return (FALSE);
3455 
3456 			if (objp->data_len == 0)
3457 				return (TRUE);
3458 
3459 			if (objp->data_len > size)
3460 				return (FALSE);
3461 
3462 			size = objp->data_len;
3463 			do {
3464 				n = MIN(size, mp->b_wptr - mp->b_rptr);
3465 				if ((n = MIN(uiop->uio_resid, n)) != 0) {
3466 
3467 					error =	uiomove((char *)mp->b_rptr, n,
3468 					    UIO_READ, uiop);
3469 					if (error)
3470 						return (FALSE);
3471 					mp->b_rptr += n;
3472 					size -= n;
3473 				}
3474 
3475 				while (mp && (mp->b_rptr >= mp->b_wptr))
3476 					mp = mp->b_cont;
3477 			} while (mp && size > 0 && uiop->uio_resid > 0);
3478 
3479 			return (TRUE);
3480 		}
3481 
3482 		if (xdrs->x_ops == &xdrrdma_ops) {
3483 			struct clist *cl;
3484 
3485 			XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
3486 
3487 			objp->wlist = cl;
3488 
3489 			if (objp->wlist) {
3490 				/* opaque count */
3491 				if (!xdr_u_int(xdrs, &ocount)) {
3492 					objp->wlist = NULL;
3493 					return (FALSE);
3494 				}
3495 
3496 				objp->wlist_len = clist_len(cl);
3497 				objp->data_len = ocount;
3498 
3499 				if (objp->wlist_len !=
3500 				    roundup(
3501 				    objp->data_len, BYTES_PER_XDR_UNIT)) {
3502 					DTRACE_PROBE2(
3503 					    xdr__e__read4resuio_clnt_fail,
3504 					    int, ocount,
3505 					    int, objp->data_len);
3506 					objp->wlist = NULL;
3507 					return (FALSE);
3508 				}
3509 
3510 				uiop->uio_resid -= objp->data_len;
3511 				uiop->uio_iov->iov_len -= objp->data_len;
3512 				uiop->uio_iov->iov_base += objp->data_len;
3513 				uiop->uio_loffset += objp->data_len;
3514 
3515 				objp->wlist = NULL;
3516 				return (TRUE);
3517 			}
3518 		}
3519 
3520 		/*
3521 		 * This isn't an xdrmblk stream nor RDMA.
3522 		 * Handle the likely case that it can be
3523 		 * inlined (ex. xdrmem).
3524 		 */
3525 		if (!XDR_GETINT32(xdrs, (int32_t *)&objp->data_len))
3526 			return (FALSE);
3527 
3528 		if (objp->data_len == 0)
3529 			return (TRUE);
3530 
3531 		if (objp->data_len > size)
3532 			return (FALSE);
3533 
3534 		size = (int)objp->data_len;
3535 		if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
3536 			return (uiomove(ptr, size, UIO_READ, uiop) ?
3537 			    FALSE : TRUE);
3538 
3539 		/*
3540 		 * Handle some other (unlikely) stream type that will
3541 		 * need a copy.
3542 		 */
3543 		if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
3544 			return (FALSE);
3545 
3546 		if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
3547 			kmem_free(ptr, size);
3548 			return (FALSE);
3549 		}
3550 		error = uiomove(ptr, size, UIO_READ, uiop);
3551 		kmem_free(ptr, size);
3552 
3553 		return (error ? FALSE : TRUE);
3554 	}
3555 
3556 	/*
3557 	 * Check for the other special case of the caller providing
3558 	 * the target area for the data.
3559 	 */
3560 	if (aobjp->res_data_val_alt == NULL)
3561 		return (FALSE);
3562 
3563 	/*
3564 	 * If read data received via RDMA_WRITE, don't do xdr_bytes().
3565 	 * RDMA_WRITE already moved the data so decode length of
3566 	 * RDMA_WRITE.
3567 	 */
3568 	if (xdrs->x_ops == &xdrrdma_ops) {
3569 		struct clist *cl;
3570 
3571 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
3572 
3573 		objp->wlist = cl;
3574 
3575 		/*
3576 		 * Data transferred through inline if
3577 		 * objp->wlist == NULL
3578 		 */
3579 		if (objp->wlist) {
3580 			/* opaque count */
3581 			if (!xdr_u_int(xdrs, &ocount)) {
3582 				objp->wlist = NULL;
3583 				return (FALSE);
3584 			}
3585 
3586 			objp->wlist_len = clist_len(cl);
3587 			objp->data_len = ocount;
3588 
3589 			if (objp->wlist_len !=
3590 			    roundup(
3591 			    objp->data_len, BYTES_PER_XDR_UNIT)) {
3592 				DTRACE_PROBE2(
3593 				    xdr__e__read4res_clnt_fail,
3594 				    int, ocount,
3595 				    int, objp->data_len);
3596 				objp->wlist = NULL;
3597 				return (FALSE);
3598 			}
3599 
3600 			objp->wlist = NULL;
3601 			return (TRUE);
3602 		}
3603 	}
3604 
3605 	return (xdr_bytes(xdrs, (char **)&aobjp->res_data_val_alt,
3606 	    (uint_t *)&objp->data_len,
3607 	    aobjp->res_maxsize));
3608 }
3609 
3610 static bool_t
3611 xdr_READDIR4args(XDR *xdrs, READDIR4args *objp)
3612 {
3613 	rdma_chunkinfo_t rci;
3614 	struct xdr_ops *xops = xdrrdma_xops();
3615 
3616 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
3617 	    xdrs->x_op == XDR_ENCODE) {
3618 		rci.rci_type = RCI_REPLY_CHUNK;
3619 		rci.rci_len = objp->maxcount;
3620 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
3621 	}
3622 
3623 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookie))
3624 		return (FALSE);
3625 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
3626 		return (FALSE);
3627 	if (!xdr_u_int(xdrs, &objp->dircount))
3628 		return (FALSE);
3629 	if (!xdr_u_int(xdrs, &objp->maxcount))
3630 		return (FALSE);
3631 	return (xdr_bitmap4(xdrs, &objp->attr_request));
3632 }
3633 
3634 /* ARGSUSED */
3635 static bool_t
3636 xdrmblk_putmblk_rd(XDR *xdrs, mblk_t *m)
3637 {
3638 	if (((m->b_wptr - m->b_rptr) % BYTES_PER_XDR_UNIT) != 0)
3639 		return (FALSE);
3640 
3641 	/* LINTED pointer alignment */
3642 	((mblk_t *)xdrs->x_base)->b_cont = m;
3643 	xdrs->x_base = (caddr_t)m;
3644 	xdrs->x_handy = 0;
3645 	return (TRUE);
3646 }
3647 
3648 bool_t
3649 xdr_READDIR4res(XDR *xdrs, READDIR4res *objp)
3650 {
3651 	mblk_t *mp = objp->mblk;
3652 	bool_t ret_val;
3653 	uint_t flags = 0;
3654 
3655 	ASSERT(xdrs->x_op == XDR_ENCODE);
3656 
3657 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
3658 		return (FALSE);
3659 	if (objp->status != NFS4_OK)
3660 		return (TRUE);
3661 	if (mp == NULL)
3662 		return (FALSE);
3663 
3664 	if (xdrs->x_ops == &xdrmblk_ops) {
3665 		if (xdrmblk_putmblk_rd(xdrs, mp)
3666 		    == TRUE) {
3667 			/* mblk successfully inserted into outgoing chain */
3668 			objp->mblk = NULL;
3669 			return (TRUE);
3670 		}
3671 	}
3672 
3673 	ASSERT(mp->b_cont == NULL);
3674 
3675 	/*
3676 	 * If transport is RDMA, the pre-encoded m_blk needs to be moved
3677 	 * without being chunked.
3678 	 * Check if chunking is enabled for the xdr stream.
3679 	 * If it is enabled, disable it temporarily for this op,
3680 	 * then re-enable.
3681 	 */
3682 	XDR_CONTROL(xdrs, XDR_RDMA_GET_FLAGS, &flags);
3683 
3684 	if (!(flags & XDR_RDMA_CHUNK))
3685 		return (xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len));
3686 
3687 	flags &= ~XDR_RDMA_CHUNK;
3688 
3689 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
3690 
3691 	ret_val = xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len);
3692 
3693 	flags |= XDR_RDMA_CHUNK;
3694 
3695 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
3696 
3697 	return (ret_val);
3698 }
3699 
3700 static bool_t
3701 xdr_READLINK4res(XDR *xdrs, READLINK4res *objp)
3702 {
3703 	if (xdrs->x_op != XDR_FREE) {
3704 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
3705 			return (FALSE);
3706 		if (objp->status != NFS4_OK)
3707 			return (TRUE);
3708 		return (xdr_bytes(xdrs, (char **)&objp->link.utf8string_val,
3709 		    (uint_t *)&objp->link.utf8string_len,
3710 		    NFS4_MAX_UTF8STRING));
3711 	}
3712 
3713 	/*
3714 	 * Optimized free case
3715 	 */
3716 	if (objp->status != NFS4_OK)
3717 		return (TRUE);
3718 	if (objp->link.utf8string_val != NULL)
3719 		kmem_free(objp->link.utf8string_val, objp->link.utf8string_len);
3720 	return (TRUE);
3721 }
3722 
3723 static bool_t
3724 xdr_REMOVE4res(XDR *xdrs, REMOVE4res *objp)
3725 {
3726 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
3727 		return (FALSE);
3728 	if (objp->status != NFS4_OK)
3729 		return (TRUE);
3730 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
3731 		return (FALSE);
3732 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
3733 		return (FALSE);
3734 	return (xdr_u_longlong_t(xdrs,
3735 	    (u_longlong_t *)&objp->cinfo.after));
3736 }
3737 
3738 static bool_t
3739 xdr_RENAME4res(XDR *xdrs, RENAME4res *objp)
3740 {
3741 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
3742 		return (FALSE);
3743 	if (objp->status != NFS4_OK)
3744 		return (TRUE);
3745 	if (!xdr_bool(xdrs, &objp->source_cinfo.atomic))
3746 		return (FALSE);
3747 	if (!xdr_u_longlong_t(xdrs,
3748 	    (u_longlong_t *)&objp->source_cinfo.before))
3749 		return (FALSE);
3750 	if (!xdr_u_longlong_t(xdrs,
3751 	    (u_longlong_t *)&objp->source_cinfo.after))
3752 		return (FALSE);
3753 	if (!xdr_bool(xdrs, &objp->target_cinfo.atomic))
3754 		return (FALSE);
3755 	if (!xdr_u_longlong_t(xdrs,
3756 	    (u_longlong_t *)&objp->target_cinfo.before))
3757 		return (FALSE);
3758 	return (xdr_u_longlong_t(xdrs,
3759 	    (u_longlong_t *)&objp->target_cinfo.after));
3760 }
3761 
3762 static bool_t
3763 xdr_secinfo4(XDR *xdrs, secinfo4 *objp)
3764 {
3765 	if (xdrs->x_op != XDR_FREE) {
3766 		if (!xdr_u_int(xdrs, &objp->flavor))
3767 			return (FALSE);
3768 		if (objp->flavor != RPCSEC_GSS)
3769 			return (TRUE);
3770 		if (!xdr_bytes(xdrs,
3771 		    (char **)&objp->flavor_info.oid.sec_oid4_val,
3772 		    (uint_t *)&objp->flavor_info.oid.sec_oid4_len,
3773 		    NFS4_MAX_SECOID4))
3774 			return (FALSE);
3775 		if (!xdr_u_int(xdrs, &objp->flavor_info.qop))
3776 			return (FALSE);
3777 		return (xdr_int(xdrs, (int *)&objp->flavor_info.service));
3778 	}
3779 
3780 	/*
3781 	 * Optimized free path
3782 	 */
3783 	if (objp->flavor != RPCSEC_GSS)
3784 		return (TRUE);
3785 
3786 	if (objp->flavor_info.oid.sec_oid4_val != NULL)
3787 		kmem_free(objp->flavor_info.oid.sec_oid4_val,
3788 		    objp->flavor_info.oid.sec_oid4_len);
3789 	return (TRUE);
3790 }
3791 
3792 static bool_t
3793 xdr_SETCLIENTID4args(XDR *xdrs, SETCLIENTID4args *objp)
3794 {
3795 	if (xdrs->x_op != XDR_FREE) {
3796 		if (!xdr_u_longlong_t(xdrs,
3797 		    (u_longlong_t *)&objp->client.verifier))
3798 			return (FALSE);
3799 		if (!xdr_bytes(xdrs, (char **)&objp->client.id_val,
3800 		    (uint_t *)&objp->client.id_len, NFS4_OPAQUE_LIMIT))
3801 			return (FALSE);
3802 		if (!xdr_u_int(xdrs, &objp->callback.cb_program))
3803 			return (FALSE);
3804 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_netid,
3805 		    NFS4_OPAQUE_LIMIT))
3806 			return (FALSE);
3807 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_addr,
3808 		    NFS4_OPAQUE_LIMIT))
3809 			return (FALSE);
3810 		return (xdr_u_int(xdrs, &objp->callback_ident));
3811 	}
3812 
3813 	/*
3814 	 * Optimized free case
3815 	 */
3816 	if (objp->client.id_val != NULL)
3817 		kmem_free(objp->client.id_val, objp->client.id_len);
3818 	(void) xdr_string(xdrs, &objp->callback.cb_location.r_netid,
3819 	    NFS4_OPAQUE_LIMIT);
3820 	return (xdr_string(xdrs, &objp->callback.cb_location.r_addr,
3821 	    NFS4_OPAQUE_LIMIT));
3822 }
3823 
3824 static bool_t
3825 xdr_SETCLIENTID4res(XDR *xdrs, SETCLIENTID4res *objp)
3826 {
3827 	if (xdrs->x_op != XDR_FREE) {
3828 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
3829 			return (FALSE);
3830 		switch (objp->status) {
3831 		case NFS4_OK:
3832 			if (!xdr_u_longlong_t(xdrs,
3833 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.resok4.
3834 			    clientid))
3835 				return (FALSE);
3836 			return (xdr_u_longlong_t(xdrs,
3837 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.
3838 			    resok4.setclientid_confirm));
3839 		case NFS4ERR_CLID_INUSE:
3840 			if (!xdr_string(xdrs,
3841 			    &objp->SETCLIENTID4res_u.client_using.
3842 			    r_netid, NFS4_OPAQUE_LIMIT))
3843 				return (FALSE);
3844 			return (xdr_string(xdrs,
3845 			    &objp->SETCLIENTID4res_u.client_using.
3846 			    r_addr, NFS4_OPAQUE_LIMIT));
3847 		}
3848 		return (TRUE);
3849 	}
3850 
3851 	/*
3852 	 * Optimized free case
3853 	 */
3854 	if (objp->status != NFS4ERR_CLID_INUSE)
3855 		return (TRUE);
3856 
3857 	if (!xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_netid,
3858 	    NFS4_OPAQUE_LIMIT))
3859 		return (FALSE);
3860 	return (xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_addr,
3861 	    NFS4_OPAQUE_LIMIT));
3862 }
3863 
3864 static bool_t
3865 xdr_WRITE4args(XDR *xdrs, WRITE4args *objp)
3866 {
3867 	if (xdrs->x_op != XDR_FREE) {
3868 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
3869 			return (FALSE);
3870 		if (!xdr_opaque(xdrs, objp->stateid.other, 12))
3871 			return (FALSE);
3872 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
3873 			return (FALSE);
3874 		if (!xdr_int(xdrs, (int *)&objp->stable))
3875 			return (FALSE);
3876 		if (xdrs->x_op == XDR_DECODE) {
3877 			if (xdrs->x_ops == &xdrmblk_ops) {
3878 				objp->data_val = NULL;
3879 				return (xdrmblk_getmblk(xdrs, &objp->mblk,
3880 				    &objp->data_len));
3881 			}
3882 			objp->mblk = NULL;
3883 			if (xdrs->x_ops == &xdrrdmablk_ops) {
3884 				int retval;
3885 				retval = xdrrdma_getrdmablk(xdrs,
3886 				    &objp->rlist,
3887 				    &objp->data_len,
3888 				    &objp->conn, NFS4_DATA_LIMIT);
3889 				if (retval == FALSE)
3890 					return (FALSE);
3891 				return (xdrrdma_read_from_client(objp->rlist,
3892 				    &objp->conn, objp->data_len));
3893 			}
3894 		}
3895 		/* Else fall thru for the xdr_bytes(). */
3896 		return (xdr_bytes(xdrs, (char **)&objp->data_val,
3897 		    (uint_t *)&objp->data_len, NFS4_DATA_LIMIT));
3898 	}
3899 	if (objp->rlist != NULL) {
3900 		(void) xdrrdma_free_clist(objp->conn, objp->rlist);
3901 		objp->rlist = NULL;
3902 		objp->data_val = NULL;
3903 
3904 		return (TRUE);
3905 	}
3906 
3907 	/*
3908 	 * Optimized free case
3909 	 */
3910 	if (objp->data_val != NULL)
3911 		kmem_free(objp->data_val, objp->data_len);
3912 	return (TRUE);
3913 }
3914 
3915 static bool_t
3916 xdr_WRITE4res(XDR *xdrs, WRITE4res *objp)
3917 {
3918 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
3919 		return (FALSE);
3920 	if (objp->status != NFS4_OK)
3921 		return (TRUE);
3922 	if (!xdr_u_int(xdrs, &objp->count))
3923 		return (FALSE);
3924 	if (!xdr_int(xdrs, (int *)&objp->committed))
3925 		return (FALSE);
3926 	return (xdr_u_longlong_t(xdrs,
3927 	    (u_longlong_t *)&objp->writeverf));
3928 }
3929 
3930 static bool_t
3931 xdr_snfs_argop4_free(XDR *xdrs, nfs_argop4 **arrayp, int len)
3932 {
3933 	int i;
3934 	nfs_argop4 *array = *arrayp;
3935 
3936 	/*
3937 	 * Optimized XDR_FREE only args array
3938 	 */
3939 	ASSERT(xdrs->x_op == XDR_FREE);
3940 
3941 	/*
3942 	 * Nothing to do?
3943 	 */
3944 	if (array == NULL)
3945 		return (TRUE);
3946 
3947 	for (i = 0; i < len; i++) {
3948 		/*
3949 		 * These should be ordered by frequency of use
3950 		 */
3951 		switch (array[i].argop) {
3952 		case OP_PUTFH: {
3953 			nfs_fh4 *objp = &array[i].nfs_argop4_u.opputfh.object;
3954 
3955 			if (objp->nfs_fh4_val != NULL) {
3956 				kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
3957 			}
3958 			continue;
3959 		}
3960 		case OP_GETATTR:
3961 		case OP_GETFH:
3962 			continue;
3963 		case OP_LOOKUP:
3964 			if (array[i].nfs_argop4_u.oplookup.objname.
3965 			    utf8string_val != NULL) {
3966 				kmem_free(array[i].nfs_argop4_u.oplookup.
3967 				    objname.utf8string_val,
3968 				    array[i].nfs_argop4_u.oplookup.
3969 				    objname.utf8string_len);
3970 			}
3971 			continue;
3972 		case OP_OPEN:
3973 			(void) xdr_OPEN4args(xdrs,
3974 			    &array[i].nfs_argop4_u.opopen);
3975 			continue;
3976 		case OP_CLOSE:
3977 		case OP_ACCESS:
3978 		case OP_READ:
3979 			continue;
3980 		case OP_WRITE:
3981 			(void) xdr_WRITE4args(xdrs,
3982 			    &array[i].nfs_argop4_u.opwrite);
3983 			continue;
3984 		case OP_DELEGRETURN:
3985 		case OP_LOOKUPP:
3986 		case OP_READDIR:
3987 			continue;
3988 		case OP_REMOVE:
3989 			if (array[i].nfs_argop4_u.opremove.target.
3990 			    utf8string_val != NULL) {
3991 				kmem_free(array[i].nfs_argop4_u.opremove.target.
3992 				    utf8string_val,
3993 				    array[i].nfs_argop4_u.opremove.target.
3994 				    utf8string_len);
3995 			}
3996 			continue;
3997 		case OP_COMMIT:
3998 			continue;
3999 		case OP_CREATE:
4000 			(void) xdr_CREATE4args(xdrs,
4001 			    &array[i].nfs_argop4_u.opcreate);
4002 			continue;
4003 		case OP_DELEGPURGE:
4004 			continue;
4005 		case OP_LINK:
4006 			if (array[i].nfs_argop4_u.oplink.newname.
4007 			    utf8string_val != NULL) {
4008 				kmem_free(array[i].nfs_argop4_u.oplink.newname.
4009 				    utf8string_val,
4010 				    array[i].nfs_argop4_u.oplink.newname.
4011 				    utf8string_len);
4012 			}
4013 			continue;
4014 		case OP_LOCK:
4015 			(void) xdr_LOCK4args(xdrs,
4016 			    &array[i].nfs_argop4_u.oplock);
4017 			continue;
4018 		case OP_LOCKT:
4019 			(void) xdr_LOCKT4args(xdrs,
4020 			    &array[i].nfs_argop4_u.oplockt);
4021 			continue;
4022 		case OP_LOCKU:
4023 			continue;
4024 		case OP_NVERIFY:
4025 			(void) xdr_fattr4(xdrs,
4026 			    &array[i].nfs_argop4_u.opnverify.obj_attributes);
4027 			continue;
4028 		case OP_OPENATTR:
4029 		case OP_OPEN_CONFIRM:
4030 		case OP_OPEN_DOWNGRADE:
4031 		case OP_PUTPUBFH:
4032 		case OP_PUTROOTFH:
4033 		case OP_READLINK:
4034 			continue;
4035 		case OP_RENAME:
4036 			if (array[i].nfs_argop4_u.oprename.oldname.
4037 			    utf8string_val != NULL) {
4038 				kmem_free(array[i].nfs_argop4_u.oprename.
4039 				    oldname.utf8string_val,
4040 				    array[i].nfs_argop4_u.oprename.
4041 				    oldname.utf8string_len);
4042 			}
4043 			if (array[i].nfs_argop4_u.oprename.newname.
4044 			    utf8string_val != NULL) {
4045 				kmem_free(array[i].nfs_argop4_u.oprename.
4046 				    newname.utf8string_val,
4047 				    array[i].nfs_argop4_u.oprename.
4048 				    newname.utf8string_len);
4049 			}
4050 			continue;
4051 		case OP_RENEW:
4052 		case OP_RESTOREFH:
4053 		case OP_SAVEFH:
4054 			continue;
4055 		case OP_SECINFO:
4056 			if (array[i].nfs_argop4_u.opsecinfo.name.
4057 			    utf8string_val != NULL) {
4058 				kmem_free(array[i].nfs_argop4_u.opsecinfo.name.
4059 				    utf8string_val,
4060 				    array[i].nfs_argop4_u.opsecinfo.name.
4061 				    utf8string_len);
4062 			}
4063 			continue;
4064 		case OP_SETATTR:
4065 			(void) xdr_fattr4(xdrs,
4066 			    &array[i].nfs_argop4_u.opsetattr.obj_attributes);
4067 			continue;
4068 		case OP_SETCLIENTID:
4069 			(void) xdr_SETCLIENTID4args(xdrs,
4070 			    &array[i].nfs_argop4_u.opsetclientid);
4071 			continue;
4072 		case OP_SETCLIENTID_CONFIRM:
4073 			continue;
4074 		case OP_VERIFY:
4075 			(void) xdr_fattr4(xdrs,
4076 			    &array[i].nfs_argop4_u.opverify.obj_attributes);
4077 			continue;
4078 		case OP_RELEASE_LOCKOWNER:
4079 			if (array[i].nfs_argop4_u.oprelease_lockowner.
4080 			    lock_owner.owner_val != NULL) {
4081 				kmem_free(array[i].nfs_argop4_u.
4082 				    oprelease_lockowner.lock_owner.owner_val,
4083 				    array[i].nfs_argop4_u.
4084 				    oprelease_lockowner.lock_owner.owner_len);
4085 			}
4086 			continue;
4087 		case OP_ILLEGAL:
4088 			continue;
4089 		default:
4090 			/*
4091 			 * An invalid op is a coding error, it should never
4092 			 * have been decoded.
4093 			 * Don't error because the caller cannot finish
4094 			 * freeing the residual memory of the array.
4095 			 */
4096 			continue;
4097 		}
4098 	}
4099 
4100 	kmem_free(*arrayp, len * sizeof (nfs_argop4));
4101 	*arrayp = NULL;
4102 	return (TRUE);
4103 }
4104 
4105 static bool_t
4106 xdr_nfs_argop4(XDR *xdrs, nfs_argop4 *objp)
4107 {
4108 	rdma_chunkinfo_t rci;
4109 	struct xdr_ops *xops = xdrrdma_xops();
4110 
4111 	/*
4112 	 * These should be ordered by frequency of use
4113 	 */
4114 	switch (objp->argop) {
4115 	case OP_PUTFH:
4116 		return (xdr_bytes(xdrs,
4117 		    (char **)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_val,
4118 		    (uint_t *)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_len,
4119 		    NFS4_FHSIZE));
4120 	case OP_GETATTR:
4121 		/*
4122 		 * ACLs can become relatively large ( > 8K) and the default
4123 		 * 8K reply chunk of RDMA may not suffice. Check for
4124 		 * get ACL bit and if it's RDMA, add a chunk equal the size
4125 		 * of the transfer size to the reply chunk list.
4126 		 */
4127 		if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
4128 		    (xdrs->x_op == XDR_ENCODE) &&
4129 		    (objp->nfs_argop4_u.opgetattr.attr_request &
4130 		    FATTR4_ACL_MASK)) {
4131 			rci.rci_type = RCI_REPLY_CHUNK;
4132 			rci.rci_len = objp->nfs_argop4_u.opgetattr.mi->mi_tsize;
4133 			XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
4134 
4135 			DTRACE_PROBE1(xdr__i__argop4__getattr, int,
4136 			    rci.rci_len);
4137 		}
4138 		return (xdr_bitmap4(xdrs,
4139 		    &objp->nfs_argop4_u.opgetattr.attr_request));
4140 	case OP_GETFH:
4141 		return (TRUE);
4142 	case OP_LOOKUP:
4143 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oplookup.
4144 		    objname.utf8string_val,
4145 		    (uint_t *)&objp->nfs_argop4_u.oplookup.
4146 		    objname.utf8string_len,
4147 		    NFS4_MAX_UTF8STRING));
4148 	case OP_OPEN:
4149 		return (xdr_OPEN4args(xdrs, &objp->nfs_argop4_u.opopen));
4150 	case OP_CLOSE:
4151 		return (xdr_CLOSE4args(xdrs, &objp->nfs_argop4_u.opclose));
4152 	case OP_ACCESS:
4153 		return (xdr_u_int(xdrs,
4154 		    &objp->nfs_argop4_u.opaccess.access));
4155 	case OP_READ:
4156 		return (xdr_READ4args(xdrs, &objp->nfs_argop4_u.opread));
4157 	case OP_WRITE:
4158 		return (xdr_WRITE4args(xdrs, &objp->nfs_argop4_u.opwrite));
4159 	case OP_DELEGRETURN:
4160 		if (!xdr_u_int(xdrs,
4161 		    &objp->nfs_argop4_u.opdelegreturn.deleg_stateid.seqid))
4162 			return (FALSE);
4163 		return (xdr_opaque(xdrs,
4164 		    objp->nfs_argop4_u.opdelegreturn.deleg_stateid.other, 12));
4165 	case OP_LOOKUPP:
4166 		return (TRUE);
4167 	case OP_READDIR:
4168 		return (xdr_READDIR4args(xdrs, &objp->nfs_argop4_u.opreaddir));
4169 	case OP_REMOVE:
4170 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.opremove.
4171 		    target.utf8string_val,
4172 		    (uint_t *)&objp->nfs_argop4_u.opremove.
4173 		    target.utf8string_len,
4174 		    NFS4_MAX_UTF8STRING));
4175 	case OP_COMMIT:
4176 		if (!xdr_u_longlong_t(xdrs,
4177 		    (u_longlong_t *)&objp->nfs_argop4_u.opcommit.offset))
4178 			return (FALSE);
4179 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opcommit.count));
4180 	case OP_CREATE:
4181 		return (xdr_CREATE4args(xdrs, &objp->nfs_argop4_u.opcreate));
4182 	case OP_DELEGPURGE:
4183 		return (xdr_u_longlong_t(xdrs,
4184 		    (u_longlong_t *)&objp->nfs_argop4_u.opdelegpurge.clientid));
4185 	case OP_LINK:
4186 		return (xdr_bytes(xdrs,
4187 		    (char **)&objp->nfs_argop4_u.oplink.newname.utf8string_val,
4188 		    (uint_t *)&objp->nfs_argop4_u.oplink.newname.utf8string_len,
4189 		    NFS4_MAX_UTF8STRING));
4190 	case OP_LOCK:
4191 		return (xdr_LOCK4args(xdrs, &objp->nfs_argop4_u.oplock));
4192 	case OP_LOCKT:
4193 		return (xdr_LOCKT4args(xdrs, &objp->nfs_argop4_u.oplockt));
4194 	case OP_LOCKU:
4195 		return (xdr_LOCKU4args(xdrs, &objp->nfs_argop4_u.oplocku));
4196 	case OP_NVERIFY:
4197 		return (xdr_fattr4(xdrs,
4198 		    &objp->nfs_argop4_u.opnverify.obj_attributes));
4199 	case OP_OPENATTR:
4200 		return (xdr_bool(xdrs,
4201 		    &objp->nfs_argop4_u.opopenattr.createdir));
4202 	case OP_OPEN_CONFIRM:
4203 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
4204 		    open_stateid.seqid))
4205 			return (FALSE);
4206 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opopen_confirm.
4207 		    open_stateid.other, 12))
4208 			return (FALSE);
4209 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
4210 		    seqid));
4211 	case OP_OPEN_DOWNGRADE:
4212 		return (xdr_OPEN_DOWNGRADE4args(xdrs,
4213 		    &objp->nfs_argop4_u.opopen_downgrade));
4214 	case OP_PUTPUBFH:
4215 		return (TRUE);
4216 	case OP_PUTROOTFH:
4217 		return (TRUE);
4218 	case OP_READLINK:
4219 		if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
4220 		    xdrs->x_op == XDR_ENCODE) {
4221 			rci.rci_type = RCI_REPLY_CHUNK;
4222 			rci.rci_len = MAXPATHLEN;
4223 			XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
4224 		}
4225 		return (TRUE);
4226 	case OP_RENAME:
4227 		if (!xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
4228 		    oldname.utf8string_val,
4229 		    (uint_t *)&objp->nfs_argop4_u.oprename.
4230 		    oldname.utf8string_len,
4231 		    NFS4_MAX_UTF8STRING))
4232 			return (FALSE);
4233 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
4234 		    newname.utf8string_val,
4235 		    (uint_t *)&objp->nfs_argop4_u.oprename.
4236 		    newname.utf8string_len,
4237 		    NFS4_MAX_UTF8STRING));
4238 	case OP_RENEW:
4239 		return (xdr_u_longlong_t(xdrs,
4240 		    (u_longlong_t *)&objp->nfs_argop4_u.oprenew.clientid));
4241 	case OP_RESTOREFH:
4242 		return (TRUE);
4243 	case OP_SAVEFH:
4244 		return (TRUE);
4245 	case OP_SECINFO:
4246 		return (xdr_bytes(xdrs,
4247 		    (char **)&objp->nfs_argop4_u.opsecinfo.name.utf8string_val,
4248 		    (uint_t *)&objp->nfs_argop4_u.opsecinfo.name.utf8string_len,
4249 		    NFS4_MAX_UTF8STRING));
4250 	case OP_SETATTR:
4251 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opsetattr.
4252 		    stateid.seqid))
4253 			return (FALSE);
4254 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opsetattr.
4255 		    stateid.other, 12))
4256 			return (FALSE);
4257 		return (xdr_fattr4(xdrs, &objp->nfs_argop4_u.opsetattr.
4258 		    obj_attributes));
4259 	case OP_SETCLIENTID:
4260 		return (xdr_SETCLIENTID4args(xdrs,
4261 		    &objp->nfs_argop4_u.opsetclientid));
4262 	case OP_SETCLIENTID_CONFIRM:
4263 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->nfs_argop4_u.
4264 		    opsetclientid_confirm.clientid))
4265 			return (FALSE);
4266 		return (xdr_u_longlong_t(xdrs,
4267 		    (u_longlong_t *)&objp->nfs_argop4_u.
4268 		    opsetclientid_confirm.setclientid_confirm));
4269 	case OP_VERIFY:
4270 		return (xdr_fattr4(xdrs,
4271 		    &objp->nfs_argop4_u.opverify.obj_attributes));
4272 	case OP_RELEASE_LOCKOWNER:
4273 		if (!xdr_u_longlong_t(xdrs,
4274 		    (u_longlong_t *)&objp->nfs_argop4_u.
4275 		    oprelease_lockowner.lock_owner.clientid))
4276 			return (FALSE);
4277 		return (xdr_bytes(xdrs,
4278 		    (char **)&objp->nfs_argop4_u.oprelease_lockowner.
4279 		    lock_owner.owner_val,
4280 		    (uint_t *)&objp->nfs_argop4_u.oprelease_lockowner.
4281 		    lock_owner.owner_len, NFS4_OPAQUE_LIMIT));
4282 	case OP_ILLEGAL:
4283 		return (TRUE);
4284 	}
4285 	return (FALSE);
4286 }
4287 
4288 static bool_t
4289 xdr_cnfs_argop4_wrap(XDR *xdrs, nfs_argop4 *objp)
4290 {
4291 	if (!xdr_int(xdrs, (int *)&objp->argop))
4292 		return (FALSE);
4293 
4294 	return (xdr_nfs_argop4(xdrs, objp));
4295 }
4296 
4297 static bool_t
4298 xdr_snfs_argop4(XDR *xdrs, nfs_argop4 *objp)
4299 {
4300 	if (!xdr_int(xdrs, (int *)&objp->argop))
4301 		return (FALSE);
4302 
4303 	switch (objp->argop) {
4304 	case OP_PUTFH:
4305 		return (xdr_decode_nfs_fh4(xdrs,
4306 		    &objp->nfs_argop4_u.opputfh.object));
4307 	default:
4308 		return (xdr_nfs_argop4(xdrs, objp));
4309 	}
4310 }
4311 
4312 /*
4313  * Client side encode only arg op processing
4314  */
4315 static bool_t
4316 xdr_cnfs_argop4(XDR *xdrs, nfs_argop4 *objp)
4317 {
4318 	int len;
4319 	int op;
4320 	nfs4_sharedfh_t *sfh;
4321 	mntinfo4_t *mi;
4322 	rpc_inline_t *ptr;
4323 
4324 	ASSERT(xdrs->x_op == XDR_ENCODE);
4325 
4326 	/*
4327 	 * Special case the private pseudo ops
4328 	 */
4329 	if (!(objp->argop & SUNW_PRIVATE_OP))
4330 		return (xdr_cnfs_argop4_wrap(xdrs, objp));
4331 
4332 	/*
4333 	 * These should be ordered by frequency of use
4334 	 */
4335 	switch (objp->argop) {
4336 	case OP_CPUTFH:
4337 		/*
4338 		 * We are passed in the file handle as a nfs4_sharedfh_t *
4339 		 * We need to acquire the correct locks so we can copy it out.
4340 		 */
4341 		sfh = (nfs4_sharedfh_t *)objp->nfs_argop4_u.opcputfh.sfh;
4342 		mi = sfh->sfh_mi;
4343 		(void) nfs_rw_enter_sig(&mi->mi_fh_lock, RW_READER, 0);
4344 
4345 		len = sfh->sfh_fh.nfs_fh4_len;
4346 		ASSERT(len <= NFS4_FHSIZE);
4347 
4348 		/*
4349 		 * First try and inline the copy
4350 		 * Must first be a multiple of BYTES_PER_XDR_UNIT
4351 		 */
4352 		if (!(len % BYTES_PER_XDR_UNIT) &&
4353 		    (ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + len)) !=
4354 		    NULL) {
4355 			IXDR_PUT_U_INT32(ptr, OP_PUTFH);
4356 			IXDR_PUT_U_INT32(ptr, len);
4357 			bcopy(sfh->sfh_fh.nfs_fh4_val, ptr, len);
4358 			nfs_rw_exit(&mi->mi_fh_lock);
4359 			return (TRUE);
4360 		}
4361 
4362 		op = OP_PUTFH;
4363 		if (!XDR_PUTINT32(xdrs, &op)) {
4364 			nfs_rw_exit(&mi->mi_fh_lock);
4365 			return (FALSE);
4366 		}
4367 		if (!XDR_PUTINT32(xdrs, &len)) {
4368 			nfs_rw_exit(&mi->mi_fh_lock);
4369 			return (FALSE);
4370 		}
4371 		if (!(len % BYTES_PER_XDR_UNIT)) {
4372 			if (XDR_PUTBYTES(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
4373 				nfs_rw_exit(&mi->mi_fh_lock);
4374 				return (TRUE);
4375 			}
4376 		} else if (xdr_opaque(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
4377 			nfs_rw_exit(&mi->mi_fh_lock);
4378 			return (TRUE);
4379 		}
4380 		nfs_rw_exit(&mi->mi_fh_lock);
4381 		return (FALSE);
4382 	case OP_CLOOKUP:
4383 		len = strlen(objp->nfs_argop4_u.opclookup.cname);
4384 		if (len > NFS4_MAX_UTF8STRING)
4385 			return (FALSE);
4386 		op = OP_LOOKUP;
4387 		if (XDR_PUTINT32(xdrs, &op)) {
4388 			if (XDR_PUTINT32(xdrs, &len)) {
4389 				return (xdr_opaque(xdrs,
4390 				    objp->nfs_argop4_u.opclookup.cname,
4391 				    len));
4392 			}
4393 		}
4394 		return (FALSE);
4395 	case OP_COPEN:
4396 		/* op processing inlined in xdr_OPEN4cargs */
4397 		return (xdr_OPEN4cargs(xdrs, &objp->nfs_argop4_u.opcopen));
4398 	case OP_CREMOVE:
4399 		len = strlen(objp->nfs_argop4_u.opcremove.ctarget);
4400 		if (len > NFS4_MAX_UTF8STRING)
4401 			return (FALSE);
4402 		op = OP_REMOVE;
4403 		if (XDR_PUTINT32(xdrs, &op)) {
4404 			if (XDR_PUTINT32(xdrs, &len)) {
4405 				return (xdr_opaque(xdrs,
4406 				    objp->nfs_argop4_u.opcremove.ctarget,
4407 				    len));
4408 			}
4409 		}
4410 		return (FALSE);
4411 	case OP_CCREATE:
4412 		op = OP_CREATE;
4413 		if (!XDR_PUTINT32(xdrs, &op))
4414 			return (FALSE);
4415 		return (xdr_CREATE4cargs(xdrs, &objp->nfs_argop4_u.opccreate));
4416 	case OP_CLINK:
4417 		len = strlen(objp->nfs_argop4_u.opclink.cnewname);
4418 		if (len > NFS4_MAX_UTF8STRING)
4419 			return (FALSE);
4420 		op = OP_LINK;
4421 		if (XDR_PUTINT32(xdrs, &op)) {
4422 			if (XDR_PUTINT32(xdrs, &len)) {
4423 				return (xdr_opaque(xdrs,
4424 				    objp->nfs_argop4_u.opclink.cnewname,
4425 				    len));
4426 			}
4427 		}
4428 		return (FALSE);
4429 	case OP_CRENAME:
4430 		len = strlen(objp->nfs_argop4_u.opcrename.coldname);
4431 		if (len > NFS4_MAX_UTF8STRING)
4432 			return (FALSE);
4433 		op = OP_RENAME;
4434 		if (!XDR_PUTINT32(xdrs, &op))
4435 			return (FALSE);
4436 		if (!XDR_PUTINT32(xdrs, &len))
4437 			return (FALSE);
4438 		if (!xdr_opaque(xdrs,
4439 		    objp->nfs_argop4_u.opcrename.coldname, len))
4440 			return (FALSE);
4441 		len = strlen(objp->nfs_argop4_u.opcrename.cnewname);
4442 		if (len > NFS4_MAX_UTF8STRING)
4443 			return (FALSE);
4444 		if (XDR_PUTINT32(xdrs, &len)) {
4445 			return (xdr_opaque(xdrs,
4446 			    objp->nfs_argop4_u.opcrename.cnewname, len));
4447 		}
4448 		return (FALSE);
4449 	case OP_CSECINFO:
4450 		len = strlen(objp->nfs_argop4_u.opcsecinfo.cname);
4451 		if (len > NFS4_MAX_UTF8STRING)
4452 			return (FALSE);
4453 		op = OP_SECINFO;
4454 		if (XDR_PUTINT32(xdrs, &op)) {
4455 			if (XDR_PUTINT32(xdrs, &len)) {
4456 				return (xdr_opaque(xdrs,
4457 				    objp->nfs_argop4_u.opcsecinfo.cname,
4458 				    len));
4459 			}
4460 		}
4461 		return (FALSE);
4462 	}
4463 	return (FALSE);
4464 }
4465 
4466 /*
4467  * Note that the len and decode_len will only be different in the case
4468  * of the client's use of this free function.  If the server is
4469  * freeing results, then the len/decode_len will always match.
4470  */
4471 static bool_t
4472 xdr_nfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
4473 {
4474 	int i;
4475 	nfs_resop4 *array = *arrayp;
4476 	nfs4_ga_res_t *gr;
4477 
4478 	/*
4479 	 * Optimized XDR_FREE only results array
4480 	 */
4481 	ASSERT(xdrs->x_op == XDR_FREE);
4482 
4483 	if (array == NULL)
4484 		return (TRUE);
4485 
4486 	for (i = 0; i < decode_len; i++) {
4487 		/*
4488 		 * These should be ordered by frequency of use
4489 		 */
4490 		switch (array[i].resop) {
4491 		case OP_PUTFH:
4492 			continue;
4493 		case OP_GETATTR:
4494 			if (array[i].nfs_resop4_u.opgetattr.status != NFS4_OK)
4495 				continue;
4496 
4497 			gr = &array[i].nfs_resop4_u.opgetattr.ga_res;
4498 			if (gr->n4g_ext_res) {
4499 				if (gr->n4g_resbmap & FATTR4_FS_LOCATIONS_MASK)
4500 					(void) xdr_fattr4_fs_locations(xdrs,
4501 					    &gr->n4g_ext_res->n4g_fslocations);
4502 				kmem_free(gr->n4g_ext_res,
4503 				    sizeof (struct nfs4_ga_ext_res));
4504 			}
4505 			continue;
4506 		case OP_GETFH:
4507 			if (array[i].nfs_resop4_u.opgetfh.status != NFS4_OK)
4508 				continue;
4509 			if (array[i].nfs_resop4_u.opgetfh.object.nfs_fh4_val !=
4510 			    NULL) {
4511 				kmem_free(array[i].nfs_resop4_u.opgetfh.object.
4512 				    nfs_fh4_val,
4513 				    array[i].nfs_resop4_u.opgetfh.object.
4514 				    nfs_fh4_len);
4515 			}
4516 			continue;
4517 		case OP_LOOKUP:
4518 			continue;
4519 		case OP_OPEN:
4520 			(void) xdr_OPEN4res(xdrs, &array[i].nfs_resop4_u.
4521 			    opopen);
4522 			continue;
4523 		case OP_CLOSE:
4524 		case OP_ACCESS:
4525 			continue;
4526 		case OP_READ:
4527 			(void) xdr_READ4res(xdrs,
4528 			    &array[i].nfs_resop4_u.opread);
4529 			continue;
4530 		case OP_WRITE:
4531 		case OP_DELEGRETURN:
4532 		case OP_LOOKUPP:
4533 		case OP_READDIR:
4534 		case OP_REMOVE:
4535 		case OP_COMMIT:
4536 		case OP_CREATE:
4537 		case OP_DELEGPURGE:
4538 		case OP_LINK:
4539 			continue;
4540 		case OP_LOCK:
4541 			(void) xdr_LOCK4res(xdrs, &array[i].nfs_resop4_u.
4542 			    oplock);
4543 			continue;
4544 		case OP_LOCKT:
4545 			(void) xdr_LOCKT4res(xdrs, &array[i].nfs_resop4_u.
4546 			    oplockt);
4547 			continue;
4548 		case OP_LOCKU:
4549 		case OP_NVERIFY:
4550 		case OP_OPENATTR:
4551 		case OP_OPEN_CONFIRM:
4552 		case OP_OPEN_DOWNGRADE:
4553 		case OP_PUTPUBFH:
4554 		case OP_PUTROOTFH:
4555 		case OP_RENAME:
4556 		case OP_RENEW:
4557 		case OP_RESTOREFH:
4558 		case OP_SAVEFH:
4559 			continue;
4560 		case OP_READLINK:
4561 			(void) xdr_READLINK4res(xdrs, &array[i].nfs_resop4_u.
4562 			    opreadlink);
4563 			continue;
4564 		case OP_SECINFO:
4565 			(void) xdr_array(xdrs,
4566 			    (char **)&array[i].nfs_resop4_u.opsecinfo.
4567 			    SECINFO4resok_val,
4568 			    (uint_t *)&array[i].nfs_resop4_u.opsecinfo.
4569 			    SECINFO4resok_len,
4570 			    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
4571 			    (xdrproc_t)xdr_secinfo4);
4572 			continue;
4573 		case OP_SETCLIENTID:
4574 			(void) xdr_SETCLIENTID4res(xdrs,
4575 			    &array[i].nfs_resop4_u.opsetclientid);
4576 			continue;
4577 		case OP_SETATTR:
4578 		case OP_SETCLIENTID_CONFIRM:
4579 		case OP_VERIFY:
4580 		case OP_RELEASE_LOCKOWNER:
4581 		case OP_ILLEGAL:
4582 			continue;
4583 		default:
4584 			/*
4585 			 * An invalid op is a coding error, it should never
4586 			 * have been decoded.
4587 			 * Don't error because the caller cannot finish
4588 			 * freeing the residual memory of the array.
4589 			 */
4590 			continue;
4591 		}
4592 	}
4593 
4594 	kmem_free(*arrayp, len * sizeof (nfs_resop4));
4595 	*arrayp = NULL;
4596 	return (TRUE);
4597 }
4598 
4599 static bool_t
4600 xdr_snfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
4601 {
4602 	return (xdr_nfs_resop4_free(xdrs, arrayp, len, decode_len));
4603 }
4604 
4605 static bool_t
4606 xdr_nfs_resop4(XDR *xdrs, nfs_resop4 *objp)
4607 {
4608 	/*
4609 	 * These should be ordered by frequency of use
4610 	 */
4611 	switch (objp->resop) {
4612 	case OP_PUTFH:
4613 		return (xdr_int(xdrs,
4614 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
4615 	case OP_GETATTR:
4616 		if (!xdr_int(xdrs,
4617 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
4618 			return (FALSE);
4619 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
4620 			return (TRUE);
4621 		return (xdr_fattr4(xdrs,
4622 		    &objp->nfs_resop4_u.opgetattr.obj_attributes));
4623 	case OP_GETFH:
4624 		if (!xdr_int(xdrs,
4625 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
4626 			return (FALSE);
4627 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
4628 			return (TRUE);
4629 		return (xdr_bytes(xdrs,
4630 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
4631 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
4632 		    NFS4_FHSIZE));
4633 	case OP_LOOKUP:
4634 		return (xdr_int(xdrs,
4635 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
4636 	case OP_OPEN:
4637 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
4638 	case OP_CLOSE:
4639 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
4640 	case OP_ACCESS:
4641 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
4642 	case OP_READ:
4643 		return (xdr_READ4res(xdrs, &objp->nfs_resop4_u.opread));
4644 	case OP_WRITE:
4645 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
4646 	case OP_DELEGRETURN:
4647 		return (xdr_int(xdrs,
4648 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
4649 	case OP_LOOKUPP:
4650 		return (xdr_int(xdrs,
4651 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
4652 	case OP_READDIR:
4653 		return (xdr_READDIR4res(xdrs, &objp->nfs_resop4_u.opreaddir));
4654 	case OP_REMOVE:
4655 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
4656 
4657 	case OP_COMMIT:
4658 		if (!xdr_int(xdrs,
4659 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
4660 			return (FALSE);
4661 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
4662 			return (TRUE);
4663 		return (xdr_u_longlong_t(xdrs,
4664 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
4665 		    writeverf));
4666 	case OP_CREATE:
4667 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
4668 	case OP_DELEGPURGE:
4669 		return (xdr_int(xdrs,
4670 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
4671 	case OP_LINK:
4672 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
4673 	case OP_LOCK:
4674 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
4675 	case OP_LOCKT:
4676 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
4677 	case OP_LOCKU:
4678 		if (!xdr_int(xdrs,
4679 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
4680 			return (FALSE);
4681 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
4682 			return (TRUE);
4683 		if (!xdr_u_int(xdrs,
4684 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
4685 			return (FALSE);
4686 		return (xdr_opaque(xdrs,
4687 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
4688 		    12));
4689 	case OP_NVERIFY:
4690 		return (xdr_int(xdrs,
4691 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
4692 	case OP_OPENATTR:
4693 		return (xdr_int(xdrs,
4694 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
4695 	case OP_OPEN_CONFIRM:
4696 		return (xdr_OPEN_CONFIRM4res(xdrs,
4697 		    &objp->nfs_resop4_u.opopen_confirm));
4698 	case OP_OPEN_DOWNGRADE:
4699 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
4700 		    &objp->nfs_resop4_u.opopen_downgrade));
4701 	case OP_PUTPUBFH:
4702 		return (xdr_int(xdrs,
4703 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
4704 	case OP_PUTROOTFH:
4705 		return (xdr_int(xdrs,
4706 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
4707 	case OP_READLINK:
4708 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
4709 	case OP_RENAME:
4710 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
4711 	case OP_RENEW:
4712 		return (xdr_int(xdrs,
4713 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
4714 	case OP_RESTOREFH:
4715 		return (xdr_int(xdrs,
4716 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
4717 	case OP_SAVEFH:
4718 		return (xdr_int(xdrs,
4719 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
4720 	case OP_SECINFO:
4721 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
4722 		    status))
4723 			return (FALSE);
4724 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
4725 			return (TRUE);
4726 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
4727 		    SECINFO4resok_val,
4728 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
4729 		    SECINFO4resok_len,
4730 		    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
4731 		    (xdrproc_t)xdr_secinfo4));
4732 	case OP_SETATTR:
4733 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
4734 		    status))
4735 			return (FALSE);
4736 		return (xdr_bitmap4(xdrs,
4737 		    &objp->nfs_resop4_u.opsetattr.attrsset));
4738 	case OP_SETCLIENTID:
4739 		return (xdr_SETCLIENTID4res(xdrs,
4740 		    &objp->nfs_resop4_u.opsetclientid));
4741 	case OP_SETCLIENTID_CONFIRM:
4742 		return (xdr_int(xdrs,
4743 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
4744 		    status));
4745 	case OP_VERIFY:
4746 		return (xdr_int(xdrs,
4747 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
4748 	case OP_RELEASE_LOCKOWNER:
4749 		return (xdr_int(xdrs,
4750 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
4751 	case OP_ILLEGAL:
4752 		return (xdr_int(xdrs,
4753 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
4754 	}
4755 	return (FALSE);
4756 }
4757 
4758 static bool_t
4759 xdr_snfs_resop4(XDR *xdrs, nfs_resop4 *objp)
4760 {
4761 	if (!xdr_int(xdrs, (int *)&objp->resop))
4762 		return (FALSE);
4763 
4764 	switch (objp->resop) {
4765 	case OP_GETFH:
4766 		if (!XDR_PUTINT32(xdrs,
4767 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
4768 			return (FALSE);
4769 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
4770 			return (TRUE);
4771 		return (xdr_encode_nfs_fh4(xdrs,
4772 		    &objp->nfs_resop4_u.opgetfh.object));
4773 	default:
4774 		return (xdr_nfs_resop4(xdrs, objp));
4775 	}
4776 }
4777 
4778 static bool_t
4779 xdr_nfs_resop4_clnt(XDR *xdrs, nfs_resop4 *objp, nfs_argop4 *aobjp)
4780 {
4781 	if (!xdr_int(xdrs, (int *)&objp->resop))
4782 		return (FALSE);
4783 	/*
4784 	 * These should be ordered by frequency of use
4785 	 */
4786 	switch (objp->resop) {
4787 	case OP_PUTFH:
4788 		return (xdr_int(xdrs,
4789 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
4790 	case OP_GETATTR:
4791 		if (!xdr_int(xdrs,
4792 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
4793 			return (FALSE);
4794 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
4795 			return (TRUE);
4796 		return (xdr_ga_res(xdrs,
4797 		    (GETATTR4res *)&objp->nfs_resop4_u.opgetattr,
4798 		    &aobjp->nfs_argop4_u.opgetattr));
4799 	case OP_GETFH:
4800 		if (!xdr_int(xdrs,
4801 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
4802 			return (FALSE);
4803 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
4804 			return (TRUE);
4805 		return (xdr_bytes(xdrs,
4806 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
4807 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
4808 		    NFS4_FHSIZE));
4809 	case OP_LOOKUP:
4810 		return (xdr_int(xdrs,
4811 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
4812 	case OP_NVERIFY:
4813 		return (xdr_int(xdrs,
4814 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
4815 	case OP_OPEN:
4816 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
4817 	case OP_CLOSE:
4818 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
4819 	case OP_ACCESS:
4820 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
4821 	case OP_READ:
4822 		return (xdr_READ4res_clnt(xdrs, &objp->nfs_resop4_u.opread,
4823 		    &aobjp->nfs_argop4_u.opread));
4824 	case OP_WRITE:
4825 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
4826 	case OP_DELEGRETURN:
4827 		return (xdr_int(xdrs,
4828 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
4829 	case OP_LOOKUPP:
4830 		return (xdr_int(xdrs,
4831 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
4832 	case OP_READDIR:
4833 		return (xdr_READDIR4res_clnt(xdrs,
4834 		    &objp->nfs_resop4_u.opreaddirclnt,
4835 		    &aobjp->nfs_argop4_u.opreaddir));
4836 	case OP_REMOVE:
4837 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
4838 
4839 	case OP_COMMIT:
4840 		if (!xdr_int(xdrs,
4841 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
4842 			return (FALSE);
4843 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
4844 			return (TRUE);
4845 		return (xdr_u_longlong_t(xdrs,
4846 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
4847 		    writeverf));
4848 	case OP_CREATE:
4849 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
4850 	case OP_DELEGPURGE:
4851 		return (xdr_int(xdrs,
4852 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
4853 	case OP_LINK:
4854 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
4855 	case OP_LOCK:
4856 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
4857 	case OP_LOCKT:
4858 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
4859 	case OP_LOCKU:
4860 		if (!xdr_int(xdrs,
4861 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
4862 			return (FALSE);
4863 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
4864 			return (TRUE);
4865 		if (!xdr_u_int(xdrs,
4866 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
4867 			return (FALSE);
4868 		return (xdr_opaque(xdrs,
4869 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
4870 		    12));
4871 	case OP_OPENATTR:
4872 		return (xdr_int(xdrs,
4873 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
4874 	case OP_OPEN_CONFIRM:
4875 		return (xdr_OPEN_CONFIRM4res(xdrs,
4876 		    &objp->nfs_resop4_u.opopen_confirm));
4877 	case OP_OPEN_DOWNGRADE:
4878 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
4879 		    &objp->nfs_resop4_u.opopen_downgrade));
4880 	case OP_PUTPUBFH:
4881 		return (xdr_int(xdrs,
4882 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
4883 	case OP_PUTROOTFH:
4884 		return (xdr_int(xdrs,
4885 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
4886 	case OP_READLINK:
4887 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
4888 	case OP_RENAME:
4889 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
4890 	case OP_RENEW:
4891 		return (xdr_int(xdrs,
4892 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
4893 	case OP_RESTOREFH:
4894 		return (xdr_int(xdrs,
4895 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
4896 	case OP_SAVEFH:
4897 		return (xdr_int(xdrs,
4898 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
4899 	case OP_SECINFO:
4900 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
4901 		    status))
4902 			return (FALSE);
4903 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
4904 			return (TRUE);
4905 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
4906 		    SECINFO4resok_val,
4907 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
4908 		    SECINFO4resok_len,
4909 		    ~0, sizeof (secinfo4), (xdrproc_t)xdr_secinfo4));
4910 	case OP_SETATTR:
4911 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
4912 		    status))
4913 			return (FALSE);
4914 		return (xdr_bitmap4(xdrs,
4915 		    &objp->nfs_resop4_u.opsetattr.attrsset));
4916 	case OP_SETCLIENTID:
4917 		return (xdr_SETCLIENTID4res(xdrs,
4918 		    &objp->nfs_resop4_u.opsetclientid));
4919 	case OP_SETCLIENTID_CONFIRM:
4920 		return (xdr_int(xdrs,
4921 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
4922 		    status));
4923 	case OP_VERIFY:
4924 		return (xdr_int(xdrs,
4925 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
4926 	case OP_RELEASE_LOCKOWNER:
4927 		return (xdr_int(xdrs,
4928 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
4929 	case OP_ILLEGAL:
4930 		return (xdr_int(xdrs,
4931 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
4932 	}
4933 	return (FALSE);
4934 }
4935 
4936 bool_t
4937 xdr_COMPOUND4args_clnt(XDR *xdrs, COMPOUND4args_clnt *objp)
4938 {
4939 	static int32_t twelve = 12;
4940 	static int32_t minorversion = NFS4_MINORVERSION;
4941 	uint32_t *ctagp;
4942 	rpc_inline_t *ptr;
4943 	rdma_chunkinfo_t rci;
4944 	struct xdr_ops *xops = xdrrdma_xops();
4945 
4946 	/*
4947 	 * XDR_ENCODE only
4948 	 */
4949 	if (xdrs->x_op == XDR_FREE)
4950 		return (TRUE);
4951 	if (xdrs->x_op == XDR_DECODE)
4952 		return (FALSE);
4953 
4954 	ctagp = (uint32_t *)&nfs4_ctags[objp->ctag].ct_tag;
4955 
4956 	if ((ptr = XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT)) != NULL) {
4957 		/*
4958 		 * Efficiently encode fixed length tags, could be longlongs
4959 		 * but 8 byte XDR alignment not assured
4960 		 */
4961 		IXDR_PUT_U_INT32(ptr, 12);
4962 		IXDR_PUT_U_INT32(ptr, ctagp[0]);
4963 		IXDR_PUT_U_INT32(ptr, ctagp[1]);
4964 		IXDR_PUT_U_INT32(ptr, ctagp[2]);
4965 
4966 		/*
4967 		 * Fixed minor version for now
4968 		 */
4969 		IXDR_PUT_U_INT32(ptr, NFS4_MINORVERSION);
4970 	} else {
4971 		if (!XDR_PUTINT32(xdrs, &twelve))
4972 			return (FALSE);
4973 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[0]))
4974 			return (FALSE);
4975 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[1]))
4976 			return (FALSE);
4977 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[2]))
4978 			return (FALSE);
4979 		if (!XDR_PUTINT32(xdrs, (int32_t *)&minorversion))
4980 			return (FALSE);
4981 	}
4982 	if (xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) {
4983 		rci.rci_type = RCI_REPLY_CHUNK;
4984 		rci.rci_len = MAXPATHLEN * 2;
4985 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
4986 	}
4987 
4988 	return (xdr_array(xdrs, (char **)&objp->array,
4989 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
4990 	    sizeof (nfs_argop4), (xdrproc_t)xdr_cnfs_argop4));
4991 }
4992 
4993 bool_t
4994 xdr_COMPOUND4args_srv(XDR *xdrs, COMPOUND4args *objp)
4995 {
4996 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
4997 	    (uint_t *)&objp->tag.utf8string_len,
4998 	    NFS4_MAX_UTF8STRING))
4999 		return (FALSE);
5000 	if (!xdr_u_int(xdrs, &objp->minorversion))
5001 		return (FALSE);
5002 	if (xdrs->x_op != XDR_FREE)
5003 		return (xdr_array(xdrs, (char **)&objp->array,
5004 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5005 		    sizeof (nfs_argop4), (xdrproc_t)xdr_snfs_argop4));
5006 
5007 	return (xdr_snfs_argop4_free(xdrs, &objp->array, objp->array_len));
5008 }
5009 
5010 bool_t
5011 xdr_COMPOUND4res_clnt(XDR *xdrs, COMPOUND4res_clnt *objp)
5012 {
5013 	uint32_t len;
5014 	int32_t *ptr;
5015 	nfs_argop4 *argop;
5016 	nfs_resop4 *resop;
5017 
5018 	/*
5019 	 * No XDR_ENCODE
5020 	 */
5021 	if (xdrs->x_op == XDR_ENCODE)
5022 		return (FALSE);
5023 
5024 	if (xdrs->x_op != XDR_FREE) {
5025 		if ((ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL) {
5026 			objp->status = IXDR_GET_U_INT32(ptr);
5027 			len = IXDR_GET_U_INT32(ptr);
5028 		} else {
5029 			if (!xdr_int(xdrs, (int32_t *)&objp->status))
5030 				return (FALSE);
5031 			if (!xdr_u_int(xdrs, (uint32_t *)&len))
5032 				return (FALSE);
5033 		}
5034 		if (len > NFS4_MAX_UTF8STRING)
5035 			return (FALSE);
5036 		/*
5037 		 * Ignore the tag
5038 		 */
5039 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &len))
5040 			return (FALSE);
5041 
5042 		if (!xdr_int(xdrs, (int32_t *)&objp->array_len))
5043 			return (FALSE);
5044 
5045 		if (objp->array_len > objp->argsp->array_len)
5046 			return (FALSE);
5047 
5048 		if (objp->status == NFS4_OK &&
5049 		    objp->array_len != objp->argsp->array_len)
5050 			return (FALSE);
5051 
5052 		/* Alloc the results array */
5053 		argop = objp->argsp->array;
5054 		len = objp->array_len * sizeof (nfs_resop4);
5055 		objp->decode_len = 0;
5056 		objp->array = resop = kmem_zalloc(len, KM_SLEEP);
5057 
5058 		for (len = 0; len < objp->array_len;
5059 		    len++, resop++, argop++, objp->decode_len++) {
5060 			if (!xdr_nfs_resop4_clnt(xdrs, resop, argop)) {
5061 				/*
5062 				 * Make sure to free anything that may
5063 				 * have been allocated along the way.
5064 				 */
5065 				xdrs->x_op = XDR_FREE;
5066 				(void) xdr_nfs_resop4_free(xdrs, &objp->array,
5067 				    objp->array_len,
5068 				    objp->decode_len);
5069 				return (FALSE);
5070 			}
5071 		}
5072 		return (TRUE);
5073 	}
5074 	return (xdr_nfs_resop4_free(xdrs, &objp->array,
5075 	    objp->array_len, objp->decode_len));
5076 }
5077 
5078 bool_t
5079 xdr_COMPOUND4res_srv(XDR *xdrs, COMPOUND4res *objp)
5080 {
5081 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
5082 		return (FALSE);
5083 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
5084 	    (uint_t *)&objp->tag.utf8string_len,
5085 	    NFS4_MAX_UTF8STRING))
5086 		return (FALSE);
5087 
5088 	if (xdrs->x_op != XDR_FREE)
5089 		return (xdr_array(xdrs, (char **)&objp->array,
5090 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5091 		    sizeof (nfs_resop4), (xdrproc_t)xdr_snfs_resop4));
5092 
5093 	return (xdr_snfs_resop4_free(xdrs, &objp->array,
5094 	    objp->array_len, objp->array_len));
5095 }
5096 
5097 /*
5098  * NFS server side callback, initiating the callback request so it
5099  * is the RPC client. Must convert from server's internal filehandle
5100  * format to wire format.
5101  */
5102 static bool_t
5103 xdr_snfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
5104 {
5105 	CB_GETATTR4args *gargs;
5106 	CB_RECALL4args *rargs;
5107 
5108 	ASSERT(xdrs->x_op == XDR_ENCODE);
5109 
5110 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->argop))
5111 		return (FALSE);
5112 
5113 	switch (objp->argop) {
5114 	case OP_CB_GETATTR:
5115 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
5116 
5117 		if (!xdr_encode_nfs_fh4(xdrs, &gargs->fh))
5118 			return (FALSE);
5119 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
5120 	case OP_CB_RECALL:
5121 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
5122 
5123 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->stateid.seqid))
5124 			return (FALSE);
5125 		if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
5126 			return (FALSE);
5127 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->truncate))
5128 			return (FALSE);
5129 		return (xdr_encode_nfs_fh4(xdrs, &rargs->fh));
5130 	case OP_CB_ILLEGAL:
5131 		return (TRUE);
5132 	}
5133 	return (FALSE);
5134 }
5135 
5136 /*
5137  * NFS client side callback, receiving the callback request so it
5138  * is the RPC server. Must treat the file handles as opaque.
5139  */
5140 static bool_t
5141 xdr_cnfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
5142 {
5143 	CB_GETATTR4args *gargs;
5144 	CB_RECALL4args *rargs;
5145 
5146 	ASSERT(xdrs->x_op != XDR_ENCODE);
5147 
5148 	if (!xdr_u_int(xdrs, &objp->argop))
5149 		return (FALSE);
5150 	switch (objp->argop) {
5151 	case OP_CB_GETATTR:
5152 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
5153 
5154 		if (!xdr_bytes(xdrs, (char **)&gargs->fh.nfs_fh4_val,
5155 		    (uint_t *)&gargs->fh.nfs_fh4_len, NFS4_FHSIZE))
5156 			return (FALSE);
5157 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
5158 	case OP_CB_RECALL:
5159 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
5160 
5161 		if (!xdr_u_int(xdrs, &rargs->stateid.seqid))
5162 			return (FALSE);
5163 		if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
5164 			return (FALSE);
5165 		if (!xdr_bool(xdrs, &rargs->truncate))
5166 			return (FALSE);
5167 		return (xdr_bytes(xdrs, (char **)&rargs->fh.nfs_fh4_val,
5168 		    (uint_t *)&rargs->fh.nfs_fh4_len, NFS4_FHSIZE));
5169 	case OP_CB_ILLEGAL:
5170 		return (TRUE);
5171 	}
5172 	return (FALSE);
5173 }
5174 
5175 static bool_t
5176 xdr_nfs_cb_resop4(XDR *xdrs, nfs_cb_resop4 *objp)
5177 {
5178 	if (!xdr_u_int(xdrs, &objp->resop))
5179 		return (FALSE);
5180 	switch (objp->resop) {
5181 	case OP_CB_GETATTR:
5182 		if (!xdr_int(xdrs,
5183 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbgetattr.
5184 		    status))
5185 			return (FALSE);
5186 		if (objp->nfs_cb_resop4_u.opcbgetattr.status != NFS4_OK)
5187 			return (TRUE);
5188 		return (xdr_fattr4(xdrs,
5189 		    &objp->nfs_cb_resop4_u.opcbgetattr.
5190 		    obj_attributes));
5191 	case OP_CB_RECALL:
5192 		return (xdr_int(xdrs,
5193 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbrecall.status));
5194 	case OP_CB_ILLEGAL:
5195 		return (xdr_int(xdrs,
5196 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbillegal.status));
5197 	}
5198 	return (FALSE);
5199 }
5200 
5201 /*
5202  * The NFS client side callback, RPC server
5203  */
5204 bool_t
5205 xdr_CB_COMPOUND4args_clnt(XDR *xdrs, CB_COMPOUND4args *objp)
5206 {
5207 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
5208 	    (uint_t *)&objp->tag.utf8string_len,
5209 	    NFS4_MAX_UTF8STRING))
5210 		return (FALSE);
5211 	if (!xdr_u_int(xdrs, &objp->minorversion))
5212 		return (FALSE);
5213 	if (!xdr_u_int(xdrs, &objp->callback_ident))
5214 		return (FALSE);
5215 	return (xdr_array(xdrs, (char **)&objp->array,
5216 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5217 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_cnfs_cb_argop4));
5218 }
5219 
5220 /*
5221  * The NFS server side callback, RPC client
5222  */
5223 bool_t
5224 xdr_CB_COMPOUND4args_srv(XDR *xdrs, CB_COMPOUND4args *objp)
5225 {
5226 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
5227 	    (uint_t *)&objp->tag.utf8string_len,
5228 	    NFS4_MAX_UTF8STRING))
5229 		return (FALSE);
5230 	if (!xdr_u_int(xdrs, &objp->minorversion))
5231 		return (FALSE);
5232 	if (!xdr_u_int(xdrs, &objp->callback_ident))
5233 		return (FALSE);
5234 	return (xdr_array(xdrs, (char **)&objp->array,
5235 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5236 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_snfs_cb_argop4));
5237 }
5238 
5239 bool_t
5240 xdr_CB_COMPOUND4res(XDR *xdrs, CB_COMPOUND4res *objp)
5241 {
5242 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
5243 		return (FALSE);
5244 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
5245 	    (uint_t *)&objp->tag.utf8string_len,
5246 	    NFS4_MAX_UTF8STRING))
5247 		return (FALSE);
5248 	return (xdr_array(xdrs, (char **)&objp->array,
5249 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
5250 	    sizeof (nfs_cb_resop4), (xdrproc_t)xdr_nfs_cb_resop4));
5251 }
5252