xref: /titanic_50/usr/src/uts/common/fs/nfs/nfs3_xdr.c (revision 24fe0b3bf671e123467ce1df0b67cadd3614c8e4)
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 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
28 
29 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <sys/systm.h>
32 #include <sys/user.h>
33 #include <sys/vnode.h>
34 #include <sys/file.h>
35 #include <sys/dirent.h>
36 #include <sys/vfs.h>
37 #include <sys/stream.h>
38 #include <sys/strsubr.h>
39 #include <sys/debug.h>
40 #include <sys/t_lock.h>
41 #include <sys/cmn_err.h>
42 #include <sys/dnlc.h>
43 #include <sys/cred.h>
44 #include <sys/time.h>
45 #include <sys/sdt.h>
46 
47 #include <rpc/types.h>
48 #include <rpc/xdr.h>
49 
50 #include <nfs/nfs.h>
51 #include <nfs/rnode.h>
52 #include <rpc/rpc_rdma.h>
53 
54 /*
55  * These are the XDR routines used to serialize and deserialize
56  * the various structures passed as parameters across the network
57  * between NFS clients and servers.
58  */
59 
60 /*
61  * XDR null terminated ASCII strings
62  * xdr_string3 deals with "C strings" - arrays of bytes that are
63  * terminated by a NULL character.  The parameter cpp references a
64  * pointer to storage; If the pointer is null, then the necessary
65  * storage is allocated.  The last parameter is the max allowed length
66  * of the string as allowed by the system.  The NFS Version 3 protocol
67  * does not place limits on strings, but the implementation needs to
68  * place a reasonable limit to avoid problems.
69  */
70 bool_t
71 xdr_string3(XDR *xdrs, char **cpp, uint_t maxsize)
72 {
73 	char *sp;
74 	uint_t size;
75 	uint_t nodesize;
76 	bool_t mem_alloced = FALSE;
77 
78 	/*
79 	 * first deal with the length since xdr strings are counted-strings
80 	 */
81 	sp = *cpp;
82 	switch (xdrs->x_op) {
83 	case XDR_FREE:
84 		if (sp == NULL || sp == nfs3nametoolong)
85 			return (TRUE);	/* already free */
86 		/* FALLTHROUGH */
87 
88 	case XDR_ENCODE:
89 		size = (uint_t)strlen(sp);
90 		break;
91 
92 	case XDR_DECODE:
93 		break;
94 	}
95 
96 	if (!xdr_u_int(xdrs, &size))
97 		return (FALSE);
98 
99 	/*
100 	 * now deal with the actual bytes
101 	 */
102 	switch (xdrs->x_op) {
103 	case XDR_DECODE:
104 		if (size >= maxsize) {
105 			*cpp = nfs3nametoolong;
106 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size))
107 				return (FALSE);
108 			return (TRUE);
109 		}
110 		nodesize = size + 1;
111 		if (nodesize == 0)
112 			return (TRUE);
113 		if (sp == NULL) {
114 			sp = kmem_alloc(nodesize, KM_NOSLEEP);
115 			*cpp = sp;
116 			if (sp == NULL)
117 				return (FALSE);
118 			mem_alloced = TRUE;
119 		}
120 		sp[size] = 0;
121 
122 		if (xdr_opaque(xdrs, sp, size)) {
123 			if (strlen(sp) != size) {
124 				if (mem_alloced)
125 					kmem_free(sp, nodesize);
126 				*cpp = NULL;
127 				return (FALSE);
128 			}
129 		} else {
130 			if (mem_alloced)
131 				kmem_free(sp, nodesize);
132 			*cpp = NULL;
133 			return (FALSE);
134 		}
135 		return (TRUE);
136 
137 	case XDR_ENCODE:
138 		return (xdr_opaque(xdrs, sp, size));
139 
140 	case XDR_FREE:
141 		nodesize = size + 1;
142 		kmem_free(sp, nodesize);
143 		*cpp = NULL;
144 		return (TRUE);
145 	}
146 
147 	return (FALSE);
148 }
149 
150 /*
151  * XDR_INLINE decode a filehandle.
152  */
153 bool_t
154 xdr_inline_decode_nfs_fh3(uint32_t *ptr, nfs_fh3 *fhp, uint32_t fhsize)
155 {
156 	uchar_t *bp = (uchar_t *)ptr;
157 	uchar_t *cp;
158 	uint32_t dsize;
159 	uintptr_t resid;
160 
161 	/*
162 	 * Check to see if what the client sent us is bigger or smaller
163 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
164 	 * unfortunately badly named as it is no longer the max and is
165 	 * really the min of what is sent over the wire.
166 	 */
167 	if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) +
168 	    sizeof (ushort_t) + NFS_FHMAXDATA +
169 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
170 		return (FALSE);
171 	}
172 
173 	/*
174 	 * All internal parts of a filehandle are in native byte order.
175 	 *
176 	 * Decode what should be fh3_fsid, it is aligned.
177 	 */
178 	fhp->fh3_fsid.val[0] = *(uint32_t *)bp;
179 	bp += BYTES_PER_XDR_UNIT;
180 	fhp->fh3_fsid.val[1] = *(uint32_t *)bp;
181 	bp += BYTES_PER_XDR_UNIT;
182 
183 	/*
184 	 * Decode what should be fh3_len.  fh3_len is two bytes, so we're
185 	 * unaligned now.
186 	 */
187 	cp = (uchar_t *)&fhp->fh3_len;
188 	*cp++ = *bp++;
189 	*cp++ = *bp++;
190 	fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
191 
192 	/*
193 	 * For backwards compatability, the fid length may be less than
194 	 * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
195 	 */
196 	dsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len;
197 
198 	/*
199 	 * Make sure the client isn't sending us a bogus length for fh3x_data.
200 	 */
201 	if (fhsize < dsize)
202 		return (FALSE);
203 	bcopy(bp, fhp->fh3_data, dsize);
204 	bp += dsize;
205 	fhsize -= dsize;
206 
207 	if (fhsize < sizeof (ushort_t))
208 		return (FALSE);
209 	cp = (uchar_t *)&fhp->fh3_xlen;
210 	*cp++ = *bp++;
211 	*cp++ = *bp++;
212 	fhsize -= sizeof (ushort_t);
213 
214 	dsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen;
215 
216 	/*
217 	 * Make sure the client isn't sending us a bogus length for fh3x_xdata.
218 	 */
219 	if (fhsize < dsize)
220 		return (FALSE);
221 	bcopy(bp, fhp->fh3_xdata, dsize);
222 	fhsize -= dsize;
223 	bp += dsize;
224 
225 	/*
226 	 * We realign things on purpose, so skip any padding
227 	 */
228 	resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
229 	if (resid != 0) {
230 		if (fhsize < (BYTES_PER_XDR_UNIT - resid))
231 			return (FALSE);
232 		bp += BYTES_PER_XDR_UNIT - resid;
233 		fhsize -= BYTES_PER_XDR_UNIT - resid;
234 	}
235 
236 	/*
237 	 * Make sure client didn't send extra bytes
238 	 */
239 	if (fhsize != 0)
240 		return (FALSE);
241 	return (TRUE);
242 }
243 
244 static bool_t
245 xdr_decode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
246 {
247 	uint32_t fhsize;		/* filehandle size */
248 	uint32_t bufsize;
249 	rpc_inline_t *ptr;
250 	uchar_t *bp;
251 
252 	ASSERT(xdrs->x_op == XDR_DECODE);
253 
254 	/*
255 	 * Retrieve the filehandle length.
256 	 */
257 	if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
258 		return (FALSE);
259 
260 	bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
261 	objp->fh3_length = 0;
262 
263 	/*
264 	 * Check to see if what the client sent us is bigger or smaller
265 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
266 	 * unfortunately badly named as it is no longer the max and is
267 	 * really the min of what is sent over the wire.
268 	 */
269 	if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) +
270 	    sizeof (ushort_t) + NFS_FHMAXDATA +
271 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
272 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
273 			return (FALSE);
274 		return (TRUE);
275 	}
276 
277 	/*
278 	 * bring in fhsize plus any padding
279 	 */
280 	bufsize = RNDUP(fhsize);
281 	ptr = XDR_INLINE(xdrs, bufsize);
282 	bp = (uchar_t *)ptr;
283 	if (ptr == NULL) {
284 		bp = kmem_alloc(bufsize, KM_SLEEP);
285 		if (!xdr_opaque(xdrs, (char *)bp, bufsize)) {
286 			kmem_free(bp, bufsize);
287 			return (FALSE);
288 		}
289 	}
290 
291 	objp->fh3_length = sizeof (fhandle3_t);
292 
293 	if (xdr_inline_decode_nfs_fh3((uint32_t *)bp, objp, fhsize) == FALSE) {
294 		/*
295 		 * If in the process of decoding we find the file handle
296 		 * is not correctly formed, we need to continue decoding
297 		 * and trigger an NFS layer error. Set the nfs_fh3_len to
298 		 * zero so it gets caught as a bad length.
299 		 */
300 		bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
301 		objp->fh3_length = 0;
302 	}
303 
304 	if (ptr == NULL)
305 		kmem_free(bp, bufsize);
306 	return (TRUE);
307 }
308 
309 /*
310  * XDR_INLINE encode a filehandle.
311  */
312 bool_t
313 xdr_inline_encode_nfs_fh3(uint32_t **ptrp, uint32_t *ptr_redzone,
314 	nfs_fh3 *fhp)
315 {
316 	uint32_t *ptr = *ptrp;
317 	uchar_t *cp;
318 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
319 	uint32_t padword;
320 
321 	fsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len;
322 	xsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen;
323 
324 	/*
325 	 * First get the initial and variable sized part of the filehandle.
326 	 */
327 	otw_len = sizeof (fhp->fh3_fsid) +
328 	    sizeof (fhp->fh3_len) + fsize +
329 	    sizeof (fhp->fh3_xlen) + xsize;
330 
331 	/*
332 	 * Round out to a full word.
333 	 */
334 	otw_len = RNDUP(otw_len);
335 	padword = (otw_len / BYTES_PER_XDR_UNIT);	/* includes fhlen */
336 
337 	/*
338 	 * Make sure we don't exceed our buffer.
339 	 */
340 	if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone)
341 		return (FALSE);
342 
343 	/*
344 	 * Zero out the pading.
345 	 */
346 	ptr[padword] = 0;
347 
348 	IXDR_PUT_U_INT32(ptr, otw_len);
349 
350 	/*
351 	 * The rest of the filehandle is in native byteorder
352 	 */
353 	/* fh3_fsid */
354 	*ptr++ = (uint32_t)fhp->fh3_fsid.val[0];
355 	*ptr++ = (uint32_t)fhp->fh3_fsid.val[1];
356 
357 	/*
358 	 * Since the next pieces are unaligned, we need to
359 	 * do bytewise copies.
360 	 */
361 	cp = (uchar_t *)ptr;
362 
363 	/* fh3_len + fh3_data */
364 	bcopy(&fhp->fh3_len, cp, sizeof (fhp->fh3_len) + fsize);
365 	cp += sizeof (fhp->fh3_len) + fsize;
366 
367 	/* fh3_xlen + fh3_xdata */
368 	bcopy(&fhp->fh3_xlen, cp, sizeof (fhp->fh3_xlen) + xsize);
369 	cp += sizeof (fhp->fh3_xlen) + xsize;
370 
371 	/* do necessary rounding/padding */
372 	cp = (uchar_t *)RNDUP((uintptr_t)cp);
373 	ptr = (uint32_t *)cp;
374 
375 	/*
376 	 * With the above padding, we're word aligned again.
377 	 */
378 	ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0);
379 
380 	*ptrp = ptr;
381 
382 	return (TRUE);
383 }
384 
385 static bool_t
386 xdr_encode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
387 {
388 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
389 	bool_t ret;
390 	rpc_inline_t *ptr;
391 	rpc_inline_t *buf = NULL;
392 	uint32_t *ptr_redzone;
393 
394 	ASSERT(xdrs->x_op == XDR_ENCODE);
395 
396 	fsize = objp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_len;
397 	xsize = objp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_xlen;
398 
399 	/*
400 	 * First get the over the wire size, it is the 4 bytes
401 	 * for the length, plus the combined size of the
402 	 * file handle components.
403 	 */
404 	otw_len = BYTES_PER_XDR_UNIT + sizeof (objp->fh3_fsid) +
405 	    sizeof (objp->fh3_len) + fsize +
406 	    sizeof (objp->fh3_xlen) + xsize;
407 	/*
408 	 * Round out to a full word.
409 	 */
410 	otw_len = RNDUP(otw_len);
411 
412 	/*
413 	 * Next try to inline the XDR stream, if that fails (rare)
414 	 * allocate a buffer to encode the file handle and then
415 	 * copy it using xdr_opaque and free the buffer.
416 	 */
417 	ptr = XDR_INLINE(xdrs, otw_len);
418 	if (ptr == NULL)
419 		ptr = buf = kmem_alloc(otw_len, KM_SLEEP);
420 
421 	ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT));
422 	ret = xdr_inline_encode_nfs_fh3((uint32_t **)&ptr, ptr_redzone, objp);
423 
424 	if (buf != NULL) {
425 		if (ret == TRUE)
426 			ret = xdr_opaque(xdrs, (char *)buf, otw_len);
427 		kmem_free(buf, otw_len);
428 	}
429 	return (ret);
430 }
431 
432 /*
433  * XDR a NFSv3 filehandle the naive way.
434  */
435 bool_t
436 xdr_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
437 {
438 	if (xdrs->x_op == XDR_FREE)
439 		return (TRUE);
440 
441 	if (!xdr_u_int(xdrs, &objp->fh3_length))
442 		return (FALSE);
443 
444 	if (objp->fh3_length > NFS3_FHSIZE)
445 		return (FALSE);
446 
447 	return (xdr_opaque(xdrs, objp->fh3_u.data, objp->fh3_length));
448 }
449 
450 /*
451  * XDR a NFSv3 filehandle with intelligence on the server.
452  * Encoding goes from our in-memory structure to wire format.
453  * Decoding goes from wire format to our in-memory structure.
454  */
455 bool_t
456 xdr_nfs_fh3_server(XDR *xdrs, nfs_fh3 *objp)
457 {
458 	switch (xdrs->x_op) {
459 	case XDR_ENCODE:
460 		if (objp->fh3_flags & FH_WEBNFS)
461 			return (xdr_nfs_fh3(xdrs, objp));
462 		else
463 			return (xdr_encode_nfs_fh3(xdrs, objp));
464 	case XDR_DECODE:
465 		return (xdr_decode_nfs_fh3(xdrs, objp));
466 	case XDR_FREE:
467 		if (objp->fh3_u.data != NULL)
468 			bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
469 		return (TRUE);
470 	}
471 	return (FALSE);
472 }
473 
474 bool_t
475 xdr_diropargs3(XDR *xdrs, diropargs3 *objp)
476 {
477 	switch (xdrs->x_op) {
478 	case XDR_FREE:
479 	case XDR_ENCODE:
480 		if (!xdr_nfs_fh3(xdrs, objp->dirp))
481 			return (FALSE);
482 		break;
483 	case XDR_DECODE:
484 		if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
485 			return (FALSE);
486 		break;
487 	}
488 	return (xdr_string3(xdrs, &objp->name, MAXNAMELEN));
489 }
490 
491 static bool_t
492 xdr_fattr3(XDR *xdrs, fattr3 *na)
493 {
494 	int32_t *ptr;
495 
496 	if (xdrs->x_op == XDR_FREE)
497 		return (TRUE);
498 
499 	ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
500 	if (ptr != NULL) {
501 		if (xdrs->x_op == XDR_DECODE) {
502 			na->type = IXDR_GET_ENUM(ptr, enum ftype3);
503 			na->mode = IXDR_GET_U_INT32(ptr);
504 			na->nlink = IXDR_GET_U_INT32(ptr);
505 			na->uid = IXDR_GET_U_INT32(ptr);
506 			na->gid = IXDR_GET_U_INT32(ptr);
507 			IXDR_GET_U_HYPER(ptr, na->size);
508 			IXDR_GET_U_HYPER(ptr, na->used);
509 			na->rdev.specdata1 = IXDR_GET_U_INT32(ptr);
510 			na->rdev.specdata2 = IXDR_GET_U_INT32(ptr);
511 			IXDR_GET_U_HYPER(ptr, na->fsid);
512 			IXDR_GET_U_HYPER(ptr, na->fileid);
513 			na->atime.seconds = IXDR_GET_U_INT32(ptr);
514 			na->atime.nseconds = IXDR_GET_U_INT32(ptr);
515 			na->mtime.seconds = IXDR_GET_U_INT32(ptr);
516 			na->mtime.nseconds = IXDR_GET_U_INT32(ptr);
517 			na->ctime.seconds = IXDR_GET_U_INT32(ptr);
518 			na->ctime.nseconds = IXDR_GET_U_INT32(ptr);
519 		} else {
520 			IXDR_PUT_ENUM(ptr, na->type);
521 			IXDR_PUT_U_INT32(ptr, na->mode);
522 			IXDR_PUT_U_INT32(ptr, na->nlink);
523 			IXDR_PUT_U_INT32(ptr, na->uid);
524 			IXDR_PUT_U_INT32(ptr, na->gid);
525 			IXDR_PUT_U_HYPER(ptr, na->size);
526 			IXDR_PUT_U_HYPER(ptr, na->used);
527 			IXDR_PUT_U_INT32(ptr, na->rdev.specdata1);
528 			IXDR_PUT_U_INT32(ptr, na->rdev.specdata2);
529 			IXDR_PUT_U_HYPER(ptr, na->fsid);
530 			IXDR_PUT_U_HYPER(ptr, na->fileid);
531 			IXDR_PUT_U_INT32(ptr, na->atime.seconds);
532 			IXDR_PUT_U_INT32(ptr, na->atime.nseconds);
533 			IXDR_PUT_U_INT32(ptr, na->mtime.seconds);
534 			IXDR_PUT_U_INT32(ptr, na->mtime.nseconds);
535 			IXDR_PUT_U_INT32(ptr, na->ctime.seconds);
536 			IXDR_PUT_U_INT32(ptr, na->ctime.nseconds);
537 		}
538 		return (TRUE);
539 	}
540 	if (!(xdr_enum(xdrs, (enum_t *)&na->type) &&
541 	    xdr_u_int(xdrs, &na->mode) &&
542 	    xdr_u_int(xdrs, &na->nlink) &&
543 	    xdr_u_int(xdrs, &na->uid) &&
544 	    xdr_u_int(xdrs, &na->gid) &&
545 	    xdr_u_longlong_t(xdrs, &na->size) &&
546 	    xdr_u_longlong_t(xdrs, &na->used) &&
547 	    xdr_u_int(xdrs, &na->rdev.specdata1) &&
548 	    xdr_u_int(xdrs, &na->rdev.specdata2) &&
549 	    xdr_u_longlong_t(xdrs, &na->fsid) &&
550 	    xdr_u_longlong_t(xdrs, &na->fileid) &&
551 	    xdr_u_int(xdrs, &na->atime.seconds) &&
552 	    xdr_u_int(xdrs, &na->atime.nseconds) &&
553 	    xdr_u_int(xdrs, &na->mtime.seconds) &&
554 	    xdr_u_int(xdrs, &na->mtime.nseconds) &&
555 	    xdr_u_int(xdrs, &na->ctime.seconds) &&
556 	    xdr_u_int(xdrs, &na->ctime.nseconds)))
557 			return (FALSE);
558 	return (TRUE);
559 }
560 
561 /*
562  * Fast decode of an fattr3 to a vattr
563  * Only return FALSE on decode error, all other fattr to vattr translation
564  * failures set status.
565  *
566  * Callers must catch the following errors:
567  *	EFBIG - file size will not fit in va_size
568  *	EOVERFLOW - time will not fit in va_*time
569  */
570 static bool_t
571 xdr_fattr3_to_vattr(XDR *xdrs, fattr3_res *objp)
572 {
573 	int32_t *ptr;
574 	size3 used;
575 	specdata3 rdev;
576 	uint32_t ntime;
577 	vattr_t *vap = objp->vap;
578 
579 	/*
580 	 * DECODE only
581 	 */
582 	ASSERT(xdrs->x_op == XDR_DECODE);
583 
584 	objp->status = 0;
585 	ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
586 	if (ptr != NULL) {
587 		/*
588 		 * Common case
589 		 */
590 		vap->va_type = IXDR_GET_ENUM(ptr, enum vtype);
591 		if (vap->va_type < NF3REG || vap->va_type > NF3FIFO)
592 			vap->va_type = VBAD;
593 		else
594 			vap->va_type = nf3_to_vt[vap->va_type];
595 		vap->va_mode = IXDR_GET_U_INT32(ptr);
596 		vap->va_nlink = IXDR_GET_U_INT32(ptr);
597 		vap->va_uid = (uid_t)IXDR_GET_U_INT32(ptr);
598 		if (vap->va_uid == NFS_UID_NOBODY)
599 			vap->va_uid = UID_NOBODY;
600 		vap->va_gid = (gid_t)IXDR_GET_U_INT32(ptr);
601 		if (vap->va_gid == NFS_GID_NOBODY)
602 			vap->va_gid = GID_NOBODY;
603 		IXDR_GET_U_HYPER(ptr, vap->va_size);
604 		/*
605 		 * If invalid size, stop decode, set status, and
606 		 * return TRUE, x_handy will be correct, caller must ignore vap.
607 		 */
608 		if (!NFS3_SIZE_OK(vap->va_size)) {
609 			objp->status = EFBIG;
610 			return (TRUE);
611 		}
612 		IXDR_GET_U_HYPER(ptr, used);
613 		rdev.specdata1 = IXDR_GET_U_INT32(ptr);
614 		rdev.specdata2 = IXDR_GET_U_INT32(ptr);
615 		/* fsid is ignored */
616 		ptr += 2;
617 		IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
618 
619 		/*
620 		 * nfs protocol defines times as unsigned so don't
621 		 * extend sign, unless sysadmin set nfs_allow_preepoch_time.
622 		 * The inline macros do the equivilant of NFS_TIME_T_CONVERT
623 		 */
624 		if (nfs_allow_preepoch_time) {
625 			vap->va_atime.tv_sec = IXDR_GET_INT32(ptr);
626 			vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
627 			vap->va_mtime.tv_sec = IXDR_GET_INT32(ptr);
628 			vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
629 			vap->va_ctime.tv_sec = IXDR_GET_INT32(ptr);
630 			vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
631 		} else {
632 			/*
633 			 * Check if the time would overflow on 32-bit
634 			 */
635 			ntime = IXDR_GET_U_INT32(ptr);
636 			/*CONSTCOND*/
637 			if (NFS3_TIME_OVERFLOW(ntime)) {
638 				objp->status = EOVERFLOW;
639 				return (TRUE);
640 			}
641 			vap->va_atime.tv_sec = ntime;
642 			vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
643 
644 			ntime = IXDR_GET_U_INT32(ptr);
645 			/*CONSTCOND*/
646 			if (NFS3_TIME_OVERFLOW(ntime)) {
647 				objp->status = EOVERFLOW;
648 				return (TRUE);
649 			}
650 			vap->va_mtime.tv_sec = ntime;
651 			vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
652 
653 			ntime = IXDR_GET_U_INT32(ptr);
654 			/*CONSTCOND*/
655 			if (NFS3_TIME_OVERFLOW(ntime)) {
656 				objp->status = EOVERFLOW;
657 				return (TRUE);
658 			}
659 			vap->va_ctime.tv_sec = ntime;
660 			vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
661 		}
662 
663 	} else {
664 		uint64 fsid;
665 
666 		/*
667 		 * Slow path
668 		 */
669 		if (!(xdr_enum(xdrs, (enum_t *)&vap->va_type) &&
670 		    xdr_u_int(xdrs, &vap->va_mode) &&
671 		    xdr_u_int(xdrs, &vap->va_nlink) &&
672 		    xdr_u_int(xdrs, (uint_t *)&vap->va_uid) &&
673 		    xdr_u_int(xdrs, (uint_t *)&vap->va_gid) &&
674 		    xdr_u_longlong_t(xdrs, &vap->va_size) &&
675 		    xdr_u_longlong_t(xdrs, &used) &&
676 		    xdr_u_int(xdrs, &rdev.specdata1) &&
677 		    xdr_u_int(xdrs, &rdev.specdata2) &&
678 		    xdr_u_longlong_t(xdrs, &fsid) &&	/* ignored */
679 		    xdr_u_longlong_t(xdrs, &vap->va_nodeid)))
680 				return (FALSE);
681 
682 		if (nfs_allow_preepoch_time) {
683 			if (!xdr_u_int(xdrs, &ntime))
684 				return (FALSE);
685 			vap->va_atime.tv_sec = (int32_t)ntime;
686 			if (!xdr_u_int(xdrs, &ntime))
687 				return (FALSE);
688 			vap->va_atime.tv_nsec = ntime;
689 
690 			if (!xdr_u_int(xdrs, &ntime))
691 				return (FALSE);
692 			vap->va_mtime.tv_sec = (int32_t)ntime;
693 			if (!xdr_u_int(xdrs, &ntime))
694 				return (FALSE);
695 			vap->va_mtime.tv_nsec = ntime;
696 
697 			if (!xdr_u_int(xdrs, &ntime))
698 				return (FALSE);
699 			vap->va_ctime.tv_sec = (int32_t)ntime;
700 			if (!xdr_u_int(xdrs, &ntime))
701 				return (FALSE);
702 			vap->va_ctime.tv_nsec = ntime;
703 		} else {
704 			/*
705 			 * Check if the time would overflow on 32-bit
706 			 * Set status and keep decoding stream.
707 			 */
708 			if (!xdr_u_int(xdrs, &ntime))
709 				return (FALSE);
710 			/*CONSTCOND*/
711 			if (NFS3_TIME_OVERFLOW(ntime)) {
712 				objp->status = EOVERFLOW;
713 			}
714 			vap->va_atime.tv_sec = ntime;
715 			if (!xdr_u_int(xdrs, &ntime))
716 				return (FALSE);
717 			vap->va_atime.tv_nsec = ntime;
718 
719 			if (!xdr_u_int(xdrs, &ntime))
720 				return (FALSE);
721 			/*CONSTCOND*/
722 			if (NFS3_TIME_OVERFLOW(ntime)) {
723 				objp->status = EOVERFLOW;
724 			}
725 			vap->va_mtime.tv_sec = ntime;
726 			if (!xdr_u_int(xdrs, &ntime))
727 				return (FALSE);
728 			vap->va_mtime.tv_nsec = ntime;
729 
730 			if (!xdr_u_int(xdrs, &ntime))
731 				return (FALSE);
732 			/*CONSTCOND*/
733 			if (NFS3_TIME_OVERFLOW(ntime)) {
734 				objp->status = EOVERFLOW;
735 			}
736 			vap->va_ctime.tv_sec = ntime;
737 			if (!xdr_u_int(xdrs, &ntime))
738 				return (FALSE);
739 			vap->va_ctime.tv_nsec = ntime;
740 		}
741 
742 		/*
743 		 * Fixup as needed
744 		 */
745 		if (vap->va_type < NF3REG || vap->va_type > NF3FIFO)
746 			vap->va_type = VBAD;
747 		else
748 			vap->va_type = nf3_to_vt[vap->va_type];
749 		if (vap->va_uid == NFS_UID_NOBODY)
750 			vap->va_uid = UID_NOBODY;
751 		if (vap->va_gid == NFS_GID_NOBODY)
752 			vap->va_gid = GID_NOBODY;
753 		/*
754 		 * If invalid size, set status, and
755 		 * return TRUE, caller must ignore vap.
756 		 */
757 		if (!NFS3_SIZE_OK(vap->va_size)) {
758 			objp->status = EFBIG;
759 			return (TRUE);
760 		}
761 	}
762 
763 	/*
764 	 * Fill in derived fields
765 	 */
766 	vap->va_fsid = objp->vp->v_vfsp->vfs_dev;
767 	vap->va_seq = 0;
768 
769 	/*
770 	 * Common case values
771 	 */
772 	vap->va_rdev = 0;
773 	vap->va_blksize = MAXBSIZE;
774 	vap->va_nblocks = 0;
775 
776 	switch (vap->va_type) {
777 	case VREG:
778 	case VDIR:
779 	case VLNK:
780 		vap->va_nblocks = (u_longlong_t)
781 		    ((used + (size3)DEV_BSIZE - (size3)1) /
782 		    (size3)DEV_BSIZE);
783 		break;
784 	case VBLK:
785 		vap->va_blksize = DEV_BSIZE;
786 		/* FALLTHRU */
787 	case VCHR:
788 		vap->va_rdev = makedevice(rdev.specdata1, rdev.specdata2);
789 		break;
790 	case VSOCK:
791 	case VFIFO:
792 	default:
793 		break;
794 	}
795 
796 	return (TRUE);
797 }
798 
799 static bool_t
800 xdr_post_op_vattr(XDR *xdrs, post_op_vattr *objp)
801 {
802 	/*
803 	 * DECODE only
804 	 */
805 	ASSERT(xdrs->x_op == XDR_DECODE);
806 
807 	if (!xdr_bool(xdrs, &objp->attributes))
808 		return (FALSE);
809 
810 	if (objp->attributes == FALSE)
811 		return (TRUE);
812 
813 	if (objp->attributes != TRUE)
814 		return (FALSE);
815 
816 	if (!xdr_fattr3_to_vattr(xdrs, &objp->fres))
817 		return (FALSE);
818 
819 	/*
820 	 * The file size may cause an EFBIG or the time values
821 	 * may cause EOVERFLOW, if so simply drop the attributes.
822 	 */
823 	if (objp->fres.status != NFS3_OK)
824 		objp->attributes = FALSE;
825 
826 	return (TRUE);
827 }
828 
829 bool_t
830 xdr_post_op_attr(XDR *xdrs, post_op_attr *objp)
831 {
832 	if (!xdr_bool(xdrs, &objp->attributes))
833 		return (FALSE);
834 
835 	if (objp->attributes == FALSE)
836 		return (TRUE);
837 
838 	if (objp->attributes != TRUE)
839 		return (FALSE);
840 
841 	if (!xdr_fattr3(xdrs, &objp->attr))
842 		return (FALSE);
843 
844 	/*
845 	 * Check that we don't get a file we can't handle through
846 	 *	existing interfaces (especially stat64()).
847 	 * Decode only check since on encode the data has
848 	 * been dealt with in the above call to xdr_fattr3().
849 	 */
850 	if (xdrs->x_op == XDR_DECODE) {
851 		/* Set attrs to false if invalid size or time */
852 		if (!NFS3_SIZE_OK(objp->attr.size)) {
853 			objp->attributes = FALSE;
854 			return (TRUE);
855 		}
856 #ifndef _LP64
857 		if (!NFS3_FATTR_TIME_OK(&objp->attr))
858 			objp->attributes = FALSE;
859 #endif
860 	}
861 	return (TRUE);
862 }
863 
864 static bool_t
865 xdr_wcc_data(XDR *xdrs, wcc_data *objp)
866 {
867 	int32_t *ptr;
868 	wcc_attr *attrp;
869 
870 	if (xdrs->x_op == XDR_FREE)
871 		return (TRUE);
872 
873 	if (xdrs->x_op == XDR_DECODE) {
874 		/* pre_op_attr */
875 		if (!xdr_bool(xdrs, &objp->before.attributes))
876 			return (FALSE);
877 
878 		switch (objp->before.attributes) {
879 		case TRUE:
880 			attrp = &objp->before.attr;
881 			ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
882 			if (ptr != NULL) {
883 				IXDR_GET_U_HYPER(ptr, attrp->size);
884 				attrp->mtime.seconds = IXDR_GET_U_INT32(ptr);
885 				attrp->mtime.nseconds = IXDR_GET_U_INT32(ptr);
886 				attrp->ctime.seconds = IXDR_GET_U_INT32(ptr);
887 				attrp->ctime.nseconds = IXDR_GET_U_INT32(ptr);
888 			} else {
889 				if (!xdr_u_longlong_t(xdrs, &attrp->size))
890 					return (FALSE);
891 				if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
892 					return (FALSE);
893 				if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
894 					return (FALSE);
895 				if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
896 					return (FALSE);
897 				if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
898 					return (FALSE);
899 			}
900 
901 #ifndef _LP64
902 			/*
903 			 * check time overflow.
904 			 */
905 			if (!NFS3_TIME_OK(attrp->mtime.seconds) ||
906 			    !NFS3_TIME_OK(attrp->ctime.seconds))
907 				objp->before.attributes = FALSE;
908 #endif
909 			break;
910 		case FALSE:
911 			break;
912 		default:
913 			return (FALSE);
914 		}
915 	}
916 
917 	if (xdrs->x_op == XDR_ENCODE) {
918 		/* pre_op_attr */
919 		if (!xdr_bool(xdrs, &objp->before.attributes))
920 			return (FALSE);
921 
922 		switch (objp->before.attributes) {
923 		case TRUE:
924 			attrp = &objp->before.attr;
925 
926 			ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
927 			if (ptr != NULL) {
928 				IXDR_PUT_U_HYPER(ptr, attrp->size);
929 				IXDR_PUT_U_INT32(ptr, attrp->mtime.seconds);
930 				IXDR_PUT_U_INT32(ptr, attrp->mtime.nseconds);
931 				IXDR_PUT_U_INT32(ptr, attrp->ctime.seconds);
932 				IXDR_PUT_U_INT32(ptr, attrp->ctime.nseconds);
933 			} else {
934 				if (!xdr_u_longlong_t(xdrs, &attrp->size))
935 					return (FALSE);
936 				if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
937 					return (FALSE);
938 				if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
939 					return (FALSE);
940 				if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
941 					return (FALSE);
942 				if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
943 					return (FALSE);
944 			}
945 			break;
946 		case FALSE:
947 			break;
948 		default:
949 			return (FALSE);
950 		}
951 	}
952 	return (xdr_post_op_attr(xdrs, &objp->after));
953 }
954 
955 bool_t
956 xdr_post_op_fh3(XDR *xdrs, post_op_fh3 *objp)
957 {
958 	if (!xdr_bool(xdrs, &objp->handle_follows))
959 		return (FALSE);
960 	switch (objp->handle_follows) {
961 	case TRUE:
962 		switch (xdrs->x_op) {
963 		case XDR_ENCODE:
964 			if (!xdr_nfs_fh3_server(xdrs, &objp->handle))
965 				return (FALSE);
966 			break;
967 		case XDR_FREE:
968 		case XDR_DECODE:
969 			if (!xdr_nfs_fh3(xdrs, &objp->handle))
970 				return (FALSE);
971 			break;
972 		}
973 		return (TRUE);
974 	case FALSE:
975 		return (TRUE);
976 	default:
977 		return (FALSE);
978 	}
979 }
980 
981 static bool_t
982 xdr_sattr3(XDR *xdrs, sattr3 *objp)
983 {
984 	/* set_mode3 */
985 	if (!xdr_bool(xdrs, &objp->mode.set_it))
986 		return (FALSE);
987 	if (objp->mode.set_it)
988 		if (!xdr_u_int(xdrs, &objp->mode.mode))
989 			return (FALSE);
990 	/* set_uid3 */
991 	if (!xdr_bool(xdrs, &objp->uid.set_it))
992 		return (FALSE);
993 	if (objp->uid.set_it)
994 		if (!xdr_u_int(xdrs, &objp->uid.uid))
995 			return (FALSE);
996 	/* set_gid3 */
997 	if (!xdr_bool(xdrs, &objp->gid.set_it))
998 		return (FALSE);
999 	if (objp->gid.set_it)
1000 		if (!xdr_u_int(xdrs, &objp->gid.gid))
1001 			return (FALSE);
1002 
1003 	/* set_size3 */
1004 	if (!xdr_bool(xdrs, &objp->size.set_it))
1005 		return (FALSE);
1006 	if (objp->size.set_it)
1007 		if (!xdr_u_longlong_t(xdrs, &objp->size.size))
1008 			return (FALSE);
1009 
1010 	/* set_atime */
1011 	if (!xdr_enum(xdrs, (enum_t *)&objp->atime.set_it))
1012 		return (FALSE);
1013 	if (objp->atime.set_it == SET_TO_CLIENT_TIME) {
1014 		if (!xdr_u_int(xdrs, &objp->atime.atime.seconds))
1015 			return (FALSE);
1016 		if (!xdr_u_int(xdrs, &objp->atime.atime.nseconds))
1017 			return (FALSE);
1018 	}
1019 
1020 	/* set_mtime */
1021 	if (!xdr_enum(xdrs, (enum_t *)&objp->mtime.set_it))
1022 		return (FALSE);
1023 	if (objp->mtime.set_it == SET_TO_CLIENT_TIME) {
1024 		if (!xdr_u_int(xdrs, &objp->mtime.mtime.seconds))
1025 			return (FALSE);
1026 		if (!xdr_u_int(xdrs, &objp->mtime.mtime.nseconds))
1027 			return (FALSE);
1028 	}
1029 
1030 	return (TRUE);
1031 }
1032 
1033 bool_t
1034 xdr_GETATTR3res(XDR *xdrs, GETATTR3res *objp)
1035 {
1036 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1037 		return (FALSE);
1038 	if (objp->status != NFS3_OK)
1039 		return (TRUE);
1040 	/* xdr_GETATTR3resok */
1041 	return (xdr_fattr3(xdrs, &objp->resok.obj_attributes));
1042 }
1043 
1044 bool_t
1045 xdr_GETATTR3vres(XDR *xdrs, GETATTR3vres *objp)
1046 {
1047 	/*
1048 	 * DECODE or FREE only
1049 	 */
1050 	if (xdrs->x_op == XDR_FREE)
1051 		return (TRUE);
1052 
1053 	if (xdrs->x_op != XDR_DECODE)
1054 		return (FALSE);
1055 
1056 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1057 		return (FALSE);
1058 
1059 	if (objp->status != NFS3_OK)
1060 		return (TRUE);
1061 
1062 	return (xdr_fattr3_to_vattr(xdrs, &objp->fres));
1063 }
1064 
1065 
1066 bool_t
1067 xdr_SETATTR3args(XDR *xdrs, SETATTR3args *objp)
1068 {
1069 	switch (xdrs->x_op) {
1070 	case XDR_FREE:
1071 	case XDR_ENCODE:
1072 		if (!xdr_nfs_fh3(xdrs, &objp->object))
1073 			return (FALSE);
1074 		break;
1075 	case XDR_DECODE:
1076 		if (!xdr_nfs_fh3_server(xdrs, &objp->object))
1077 			return (FALSE);
1078 		break;
1079 	}
1080 	if (!xdr_sattr3(xdrs, &objp->new_attributes))
1081 		return (FALSE);
1082 
1083 	/* sattrguard3 */
1084 	if (!xdr_bool(xdrs, &objp->guard.check))
1085 		return (FALSE);
1086 	switch (objp->guard.check) {
1087 	case TRUE:
1088 		if (!xdr_u_int(xdrs, &objp->guard.obj_ctime.seconds))
1089 			return (FALSE);
1090 		return (xdr_u_int(xdrs, &objp->guard.obj_ctime.nseconds));
1091 	case FALSE:
1092 		return (TRUE);
1093 	default:
1094 		return (FALSE);
1095 	}
1096 }
1097 
1098 bool_t
1099 xdr_SETATTR3res(XDR *xdrs, SETATTR3res *objp)
1100 {
1101 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1102 		return (FALSE);
1103 	switch (objp->status) {
1104 	case NFS3_OK:
1105 		return (xdr_wcc_data(xdrs, &objp->resok.obj_wcc));
1106 	default:
1107 		return (xdr_wcc_data(xdrs, &objp->resfail.obj_wcc));
1108 	}
1109 }
1110 
1111 bool_t
1112 xdr_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp)
1113 {
1114 	LOOKUP3resok *resokp;
1115 
1116 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1117 		return (FALSE);
1118 
1119 	if (objp->status != NFS3_OK)
1120 		return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
1121 
1122 	/* xdr_LOOKUP3resok */
1123 	resokp = &objp->resok;
1124 	switch (xdrs->x_op) {
1125 	case XDR_ENCODE:
1126 		if (!xdr_nfs_fh3_server(xdrs, &resokp->object))
1127 			return (FALSE);
1128 		break;
1129 	case XDR_FREE:
1130 	case XDR_DECODE:
1131 		if (!xdr_nfs_fh3(xdrs, &resokp->object))
1132 			return (FALSE);
1133 		break;
1134 	}
1135 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1136 		return (FALSE);
1137 	return (xdr_post_op_attr(xdrs, &resokp->dir_attributes));
1138 }
1139 
1140 bool_t
1141 xdr_LOOKUP3vres(XDR *xdrs, LOOKUP3vres *objp)
1142 {
1143 	/*
1144 	 * DECODE or FREE only
1145 	 */
1146 	if (xdrs->x_op == XDR_FREE)
1147 		return (TRUE);
1148 
1149 	if (xdrs->x_op != XDR_DECODE)
1150 		return (FALSE);
1151 
1152 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1153 		return (FALSE);
1154 
1155 	if (objp->status != NFS3_OK)
1156 		return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
1157 
1158 	if (!xdr_nfs_fh3(xdrs, &objp->object))
1159 		return (FALSE);
1160 	if (!xdr_post_op_vattr(xdrs, &objp->obj_attributes))
1161 		return (FALSE);
1162 	return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
1163 }
1164 
1165 bool_t
1166 xdr_ACCESS3args(XDR *xdrs, ACCESS3args *objp)
1167 {
1168 	switch (xdrs->x_op) {
1169 	case XDR_FREE:
1170 	case XDR_ENCODE:
1171 		if (!xdr_nfs_fh3(xdrs, &objp->object))
1172 			return (FALSE);
1173 		break;
1174 	case XDR_DECODE:
1175 		if (!xdr_nfs_fh3_server(xdrs, &objp->object))
1176 			return (FALSE);
1177 		break;
1178 	}
1179 	return (xdr_u_int(xdrs, &objp->access));
1180 }
1181 
1182 
1183 bool_t
1184 xdr_ACCESS3res(XDR *xdrs, ACCESS3res *objp)
1185 {
1186 	ACCESS3resok *resokp;
1187 
1188 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1189 		return (FALSE);
1190 	if (objp->status != NFS3_OK)
1191 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
1192 
1193 	/* xdr_ACCESS3resok */
1194 	resokp = &objp->resok;
1195 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1196 		return (FALSE);
1197 	return (xdr_u_int(xdrs, &resokp->access));
1198 }
1199 
1200 bool_t
1201 xdr_READLINK3args(XDR *xdrs,  READLINK3args *objp)
1202 {
1203 	rdma_chunkinfo_t rci;
1204 	struct xdr_ops *xops = xdrrdma_xops();
1205 
1206 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
1207 	    xdrs->x_op == XDR_ENCODE) {
1208 		rci.rci_type = RCI_REPLY_CHUNK;
1209 		rci.rci_len = MAXPATHLEN;
1210 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1211 	}
1212 	if (!xdr_nfs_fh3(xdrs, (nfs_fh3 *)objp))
1213 		return (FALSE);
1214 	return (TRUE);
1215 }
1216 
1217 bool_t
1218 xdr_READLINK3res(XDR *xdrs, READLINK3res *objp)
1219 {
1220 
1221 	READLINK3resok *resokp;
1222 
1223 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1224 		return (FALSE);
1225 	if (objp->status != NFS3_OK)
1226 		return (xdr_post_op_attr(xdrs,
1227 		    &objp->resfail.symlink_attributes));
1228 
1229 	/* xdr_READLINK3resok */
1230 	resokp = &objp->resok;
1231 	if (!xdr_post_op_attr(xdrs, &resokp->symlink_attributes))
1232 		return (FALSE);
1233 	return (xdr_string3(xdrs, &resokp->data, MAXPATHLEN));
1234 }
1235 
1236 bool_t
1237 xdr_READ3args(XDR *xdrs, READ3args *objp)
1238 {
1239 	rdma_chunkinfo_t rci;
1240 	rdma_wlist_conn_info_t rwci;
1241 	struct xdr_ops *xops = xdrrdma_xops();
1242 
1243 	switch (xdrs->x_op) {
1244 	case XDR_FREE:
1245 	case XDR_ENCODE:
1246 		if (!xdr_nfs_fh3(xdrs, &objp->file))
1247 			return (FALSE);
1248 		break;
1249 	case XDR_DECODE:
1250 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
1251 			return (FALSE);
1252 		break;
1253 	}
1254 	if (!xdr_u_longlong_t(xdrs, &objp->offset))
1255 		return (FALSE);
1256 	if (!xdr_u_int(xdrs, &objp->count))
1257 		return (FALSE);
1258 
1259 	DTRACE_PROBE1(xdr__i__read3_buf_len, int, objp->count);
1260 
1261 	objp->wlist = NULL;
1262 
1263 	/* if xdrrdma_sizeof in progress, then store the size */
1264 	if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
1265 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
1266 		rci.rci_len = objp->count;
1267 		(void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1268 	}
1269 
1270 	if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
1271 		return (TRUE);
1272 
1273 	if (xdrs->x_op == XDR_ENCODE) {
1274 
1275 		if (objp->res_uiop != NULL) {
1276 			rci.rci_type = RCI_WRITE_UIO_CHUNK;
1277 			rci.rci_a.rci_uiop = objp->res_uiop;
1278 			rci.rci_len = objp->count;
1279 			rci.rci_clpp = &objp->wlist;
1280 		} else {
1281 			rci.rci_type = RCI_WRITE_ADDR_CHUNK;
1282 			rci.rci_a.rci_addr = objp->res_data_val_alt;
1283 			rci.rci_len = objp->count;
1284 			rci.rci_clpp = &objp->wlist;
1285 		}
1286 
1287 		return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
1288 	}
1289 
1290 	/* XDR_DECODE case */
1291 	(void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
1292 	objp->wlist = rwci.rwci_wlist;
1293 	objp->conn = rwci.rwci_conn;
1294 
1295 	return (TRUE);
1296 }
1297 
1298 bool_t
1299 xdr_READ3res(XDR *xdrs, READ3res *objp)
1300 {
1301 	READ3resok *resokp;
1302 	bool_t ret;
1303 	mblk_t *mp;
1304 
1305 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1306 		return (FALSE);
1307 
1308 	if (objp->status != NFS3_OK)
1309 		return (xdr_post_op_attr(xdrs, &objp->resfail.file_attributes));
1310 
1311 	resokp = &objp->resok;
1312 
1313 	if (xdr_post_op_attr(xdrs, &resokp->file_attributes) == FALSE ||
1314 	    xdr_u_int(xdrs, &resokp->count) == FALSE ||
1315 	    xdr_bool(xdrs, &resokp->eof) == FALSE) {
1316 		return (FALSE);
1317 	}
1318 
1319 	if (xdrs->x_op == XDR_ENCODE) {
1320 		int i, rndup;
1321 
1322 		mp = resokp->data.mp;
1323 		if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
1324 			mp->b_wptr += resokp->count;
1325 			rndup = BYTES_PER_XDR_UNIT -
1326 			    (resokp->data.data_len % BYTES_PER_XDR_UNIT);
1327 			if (rndup != BYTES_PER_XDR_UNIT)
1328 				for (i = 0; i < rndup; i++)
1329 					*mp->b_wptr++ = '\0';
1330 			if (xdrmblk_putmblk(xdrs, mp, resokp->count) == TRUE) {
1331 				resokp->data.mp = NULL;
1332 				return (TRUE);
1333 			}
1334 		} else if (mp == NULL) {
1335 			if (xdr_u_int(xdrs, &resokp->count) == FALSE) {
1336 				return (FALSE);
1337 			}
1338 			/*
1339 			 * If read data sent by wlist (RDMA_WRITE), don't do
1340 			 * xdr_bytes() below.   RDMA_WRITE transfers the data.
1341 			 * Note: this is encode-only because the client code
1342 			 * uses xdr_READ3vres/xdr_READ3uiores to decode results.
1343 			 */
1344 			if (resokp->wlist) {
1345 				if (resokp->count != 0) {
1346 					return (xdrrdma_send_read_data(
1347 					    xdrs, resokp->count,
1348 					    resokp->wlist));
1349 				}
1350 				return (TRUE);
1351 			}
1352 		}
1353 		/*
1354 		 * Fall thru for the xdr_bytes()
1355 		 *
1356 		 * note: the mblk will be freed in
1357 		 * rfs3_read_free.
1358 		 */
1359 	}
1360 
1361 	/* no RDMA_WRITE transfer -- send data inline */
1362 
1363 	ret = xdr_bytes(xdrs, (char **)&resokp->data.data_val,
1364 	    &resokp->data.data_len, nfs3tsize());
1365 
1366 	return (ret);
1367 }
1368 
1369 bool_t
1370 xdr_READ3vres(XDR *xdrs, READ3vres *objp)
1371 {
1372 	count3 ocount;
1373 	/*
1374 	 * DECODE or FREE only
1375 	 */
1376 	if (xdrs->x_op == XDR_FREE)
1377 		return (TRUE);
1378 
1379 	if (xdrs->x_op != XDR_DECODE)
1380 		return (FALSE);
1381 
1382 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1383 		return (FALSE);
1384 
1385 	if (!xdr_post_op_vattr(xdrs, &objp->pov))
1386 		return (FALSE);
1387 
1388 	if (objp->status != NFS3_OK)
1389 		return (TRUE);
1390 
1391 	if (!xdr_u_int(xdrs, &objp->count))
1392 		return (FALSE);
1393 
1394 	if (!xdr_bool(xdrs, &objp->eof))
1395 		return (FALSE);
1396 
1397 	/*
1398 	 * If read data received via RDMA_WRITE, don't do xdr_bytes().
1399 	 * RDMA_WRITE already moved the data so decode length of RDMA_WRITE.
1400 	 */
1401 	if (xdrs->x_ops == &xdrrdma_ops) {
1402 		struct clist *cl;
1403 
1404 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
1405 
1406 		if (cl) {
1407 			if (!xdr_u_int(xdrs, &ocount)) {
1408 				return (FALSE);
1409 			}
1410 			if (ocount != objp->count) {
1411 				DTRACE_PROBE2(xdr__e__read3vres_fail,
1412 				    int, ocount, int, objp->count);
1413 				objp->wlist = NULL;
1414 				return (FALSE);
1415 			}
1416 
1417 			objp->wlist_len = clist_len(cl);
1418 			objp->data.data_len = ocount;
1419 
1420 			if (objp->wlist_len !=
1421 			    roundup(objp->data.data_len, BYTES_PER_XDR_UNIT)) {
1422 				DTRACE_PROBE2(
1423 				    xdr__e__read3vres_fail,
1424 				    int, ocount,
1425 				    int, objp->data.data_len);
1426 				objp->wlist = NULL;
1427 				return (FALSE);
1428 			}
1429 			return (TRUE);
1430 		}
1431 	}
1432 
1433 	return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
1434 	    &objp->data.data_len, nfs3tsize()));
1435 }
1436 
1437 bool_t
1438 xdr_READ3uiores(XDR *xdrs, READ3uiores *objp)
1439 {
1440 	count3 ocount;
1441 	bool_t attributes;
1442 	mblk_t *mp;
1443 	size_t n;
1444 	int error;
1445 	int size = (int)objp->size;
1446 	struct uio *uiop = objp->uiop;
1447 	int32_t fattr3_len = NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
1448 	int32_t *ptr;
1449 
1450 	/*
1451 	 * DECODE or FREE only
1452 	 */
1453 	if (xdrs->x_op == XDR_FREE)
1454 		return (TRUE);
1455 
1456 	if (xdrs->x_op != XDR_DECODE)
1457 		return (FALSE);
1458 
1459 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
1460 		return (FALSE);
1461 
1462 	if (!XDR_GETINT32(xdrs, (int32_t *)&attributes))
1463 		return (FALSE);
1464 
1465 	/*
1466 	 * For directio we just skip over attributes if present
1467 	 */
1468 	switch (attributes) {
1469 	case TRUE:
1470 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fattr3_len))
1471 			return (FALSE);
1472 		break;
1473 	case FALSE:
1474 		break;
1475 	default:
1476 		return (FALSE);
1477 	}
1478 
1479 	if (objp->status != NFS3_OK)
1480 		return (TRUE);
1481 
1482 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->count))
1483 		return (FALSE);
1484 
1485 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
1486 		return (FALSE);
1487 
1488 	if (xdrs->x_ops == &xdrmblk_ops) {
1489 		if (!xdrmblk_getmblk(xdrs, &mp, &objp->size))
1490 			return (FALSE);
1491 
1492 		if (objp->size == 0)
1493 			return (TRUE);
1494 
1495 		if (objp->size > size)
1496 			return (FALSE);
1497 
1498 		size = (int)objp->size;
1499 		do {
1500 			n = MIN(size, mp->b_wptr - mp->b_rptr);
1501 			if ((n = MIN(uiop->uio_resid, n)) != 0) {
1502 
1503 				error = uiomove((char *)mp->b_rptr, n, UIO_READ,
1504 				    uiop);
1505 				if (error)
1506 					return (FALSE);
1507 				mp->b_rptr += n;
1508 				size -= n;
1509 			}
1510 
1511 			while (mp && (mp->b_rptr >= mp->b_wptr))
1512 				mp = mp->b_cont;
1513 		} while (mp && size > 0 && uiop->uio_resid > 0);
1514 
1515 		return (TRUE);
1516 	}
1517 
1518 	if (xdrs->x_ops == &xdrrdma_ops) {
1519 		struct clist *cl;
1520 
1521 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
1522 
1523 		objp->wlist = cl;
1524 
1525 		if (objp->wlist) {
1526 			if (!xdr_u_int(xdrs, &ocount)) {
1527 				objp->wlist = NULL;
1528 				return (FALSE);
1529 			}
1530 
1531 			if (ocount != objp->count) {
1532 				DTRACE_PROBE2(xdr__e__read3uiores_fail,
1533 				    int, ocount, int, objp->count);
1534 				objp->wlist = NULL;
1535 				return (FALSE);
1536 			}
1537 
1538 			objp->wlist_len = clist_len(cl);
1539 
1540 			uiop->uio_resid -= objp->count;
1541 			uiop->uio_iov->iov_len -= objp->count;
1542 			uiop->uio_iov->iov_base += objp->count;
1543 			uiop->uio_loffset += objp->count;
1544 
1545 			/*
1546 			 * XXX: Assume 1 iov, needs to be changed.
1547 			 */
1548 			objp->size = objp->count;
1549 
1550 			return (TRUE);
1551 		}
1552 	}
1553 
1554 	/*
1555 	 * This isn't an xdrmblk stream nor RDMA.
1556 	 * Handle the likely case that it can be
1557 	 * inlined (ex. xdrmem).
1558 	 */
1559 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->size))
1560 		return (FALSE);
1561 
1562 	if (objp->size == 0)
1563 		return (TRUE);
1564 
1565 	if (objp->size > size)
1566 		return (FALSE);
1567 
1568 	size = (int)objp->size;
1569 	if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
1570 		return (uiomove(ptr, size, UIO_READ, uiop) ? FALSE : TRUE);
1571 
1572 	/*
1573 	 * Handle some other (unlikely) stream type that will need a copy.
1574 	 */
1575 	if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
1576 		return (FALSE);
1577 
1578 	if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
1579 		kmem_free(ptr, size);
1580 		return (FALSE);
1581 	}
1582 	error = uiomove(ptr, size, UIO_READ, uiop);
1583 	kmem_free(ptr, size);
1584 
1585 	return (error ? FALSE : TRUE);
1586 }
1587 
1588 bool_t
1589 xdr_WRITE3args(XDR *xdrs, WRITE3args *objp)
1590 {
1591 	switch (xdrs->x_op) {
1592 	case XDR_FREE:
1593 	case XDR_ENCODE:
1594 		if (!xdr_nfs_fh3(xdrs, &objp->file))
1595 			return (FALSE);
1596 		break;
1597 	case XDR_DECODE:
1598 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
1599 			return (FALSE);
1600 		break;
1601 	}
1602 	if (!xdr_u_longlong_t(xdrs, &objp->offset))
1603 		return (FALSE);
1604 	if (!xdr_u_int(xdrs, &objp->count))
1605 		return (FALSE);
1606 	if (!xdr_enum(xdrs, (enum_t *)&objp->stable))
1607 		return (FALSE);
1608 
1609 	if (xdrs->x_op == XDR_DECODE) {
1610 		if (xdrs->x_ops == &xdrmblk_ops) {
1611 			if (xdrmblk_getmblk(xdrs, &objp->mblk,
1612 			    &objp->data.data_len) == TRUE) {
1613 				objp->data.data_val = NULL;
1614 				return (TRUE);
1615 			}
1616 		}
1617 		objp->mblk = NULL;
1618 
1619 		if (xdrs->x_ops == &xdrrdmablk_ops) {
1620 			if (xdrrdma_getrdmablk(xdrs, &objp->rlist,
1621 			    &objp->data.data_len,
1622 			    &objp->conn, nfs3tsize()) == TRUE) {
1623 				objp->data.data_val = NULL;
1624 				if (xdrrdma_read_from_client(
1625 				    objp->rlist,
1626 				    &objp->conn,
1627 				    objp->count) == FALSE) {
1628 					return (FALSE);
1629 				}
1630 				return (TRUE);
1631 			}
1632 		}
1633 		objp->rlist = NULL;
1634 
1635 		/* Else fall thru for the xdr_bytes(). */
1636 	}
1637 
1638 	if (xdrs->x_op == XDR_FREE) {
1639 		if (objp->rlist != NULL) {
1640 			(void) xdrrdma_free_clist(objp->conn, objp->rlist);
1641 			objp->rlist = NULL;
1642 			objp->data.data_val = NULL;
1643 			return (TRUE);
1644 		}
1645 	}
1646 
1647 	DTRACE_PROBE1(xdr__i__write3_buf_len,
1648 	    int, objp->data.data_len);
1649 
1650 	return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
1651 	    &objp->data.data_len, nfs3tsize()));
1652 }
1653 
1654 bool_t
1655 xdr_WRITE3res(XDR *xdrs, WRITE3res *objp)
1656 {
1657 	WRITE3resok *resokp;
1658 
1659 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1660 		return (FALSE);
1661 	if (objp->status != NFS3_OK) /* xdr_WRITE3resfail */
1662 		return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
1663 
1664 	/* xdr_WRITE3resok */
1665 	resokp = &objp->resok;
1666 	if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
1667 		return (FALSE);
1668 	if (!xdr_u_int(xdrs, &resokp->count))
1669 		return (FALSE);
1670 	if (!xdr_enum(xdrs, (enum_t *)&resokp->committed))
1671 		return (FALSE);
1672 	/*
1673 	 * writeverf3 is really an opaque 8 byte
1674 	 * quantity, but we will treat it as a
1675 	 * hyper for efficiency, the cost of
1676 	 * a byteswap here saves bcopys elsewhere
1677 	 */
1678 	return (xdr_u_longlong_t(xdrs, &resokp->verf));
1679 }
1680 
1681 bool_t
1682 xdr_CREATE3args(XDR *xdrs, CREATE3args *objp)
1683 {
1684 	createhow3 *howp;
1685 
1686 	if (!xdr_diropargs3(xdrs, &objp->where))
1687 		return (FALSE);
1688 
1689 	/* xdr_createhow3 */
1690 	howp = &objp->how;
1691 
1692 	if (!xdr_enum(xdrs, (enum_t *)&howp->mode))
1693 		return (FALSE);
1694 	switch (howp->mode) {
1695 	case UNCHECKED:
1696 	case GUARDED:
1697 		return (xdr_sattr3(xdrs, &howp->createhow3_u.obj_attributes));
1698 	case EXCLUSIVE:
1699 		/*
1700 		 * createverf3 is really an opaque 8 byte
1701 		 * quantity, but we will treat it as a
1702 		 * hyper for efficiency, the cost of
1703 		 * a byteswap here saves bcopys elsewhere
1704 		 */
1705 		return (xdr_u_longlong_t(xdrs, &howp->createhow3_u.verf));
1706 	default:
1707 		return (FALSE);
1708 	}
1709 }
1710 
1711 bool_t
1712 xdr_CREATE3res(XDR *xdrs, CREATE3res *objp)
1713 {
1714 	CREATE3resok *resokp;
1715 
1716 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1717 		return (FALSE);
1718 	switch (objp->status) {
1719 	case NFS3_OK:
1720 		/* xdr_CREATE3resok */
1721 		resokp = &objp->resok;
1722 
1723 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1724 			return (FALSE);
1725 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1726 			return (FALSE);
1727 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1728 	default:
1729 		/* xdr_CREATE3resfail */
1730 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1731 	}
1732 }
1733 
1734 bool_t
1735 xdr_MKDIR3args(XDR *xdrs, MKDIR3args *objp)
1736 {
1737 	if (!xdr_diropargs3(xdrs, &objp->where))
1738 		return (FALSE);
1739 	return (xdr_sattr3(xdrs, &objp->attributes));
1740 }
1741 
1742 bool_t
1743 xdr_MKDIR3res(XDR *xdrs, MKDIR3res *objp)
1744 {
1745 	MKDIR3resok *resokp;
1746 
1747 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1748 		return (FALSE);
1749 	switch (objp->status) {
1750 	case NFS3_OK:
1751 		/* xdr_MKDIR3resok */
1752 		resokp = &objp->resok;
1753 
1754 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1755 			return (FALSE);
1756 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1757 			return (FALSE);
1758 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1759 	default:
1760 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1761 	}
1762 }
1763 
1764 bool_t
1765 xdr_SYMLINK3args(XDR *xdrs, SYMLINK3args *objp)
1766 {
1767 	if (!xdr_diropargs3(xdrs, &objp->where))
1768 		return (FALSE);
1769 	if (!xdr_sattr3(xdrs, &objp->symlink.symlink_attributes))
1770 		return (FALSE);
1771 	return (xdr_string3(xdrs, &objp->symlink.symlink_data, MAXPATHLEN));
1772 }
1773 
1774 bool_t
1775 xdr_SYMLINK3res(XDR *xdrs, SYMLINK3res *objp)
1776 {
1777 	SYMLINK3resok *resokp;
1778 
1779 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1780 		return (FALSE);
1781 	switch (objp->status) {
1782 	case NFS3_OK:
1783 		resokp = &objp->resok;
1784 		/* xdr_SYMLINK3resok */
1785 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1786 			return (FALSE);
1787 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1788 			return (FALSE);
1789 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1790 	default:
1791 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1792 	}
1793 }
1794 
1795 bool_t
1796 xdr_MKNOD3args(XDR *xdrs, MKNOD3args *objp)
1797 {
1798 	mknoddata3 *whatp;
1799 	devicedata3 *nod_objp;
1800 
1801 	if (!xdr_diropargs3(xdrs, &objp->where))
1802 		return (FALSE);
1803 
1804 	whatp = &objp->what;
1805 	if (!xdr_enum(xdrs, (enum_t *)&whatp->type))
1806 		return (FALSE);
1807 	switch (whatp->type) {
1808 	case NF3CHR:
1809 	case NF3BLK:
1810 		/* xdr_devicedata3 */
1811 		nod_objp = &whatp->mknoddata3_u.device;
1812 		if (!xdr_sattr3(xdrs, &nod_objp->dev_attributes))
1813 			return (FALSE);
1814 		if (!xdr_u_int(xdrs, &nod_objp->spec.specdata1))
1815 			return (FALSE);
1816 		return (xdr_u_int(xdrs, &nod_objp->spec.specdata2));
1817 	case NF3SOCK:
1818 	case NF3FIFO:
1819 		return (xdr_sattr3(xdrs, &whatp->mknoddata3_u.pipe_attributes));
1820 	default:
1821 		break;
1822 	}
1823 	return (TRUE);
1824 }
1825 
1826 bool_t
1827 xdr_MKNOD3res(XDR *xdrs, MKNOD3res *objp)
1828 {
1829 	MKNOD3resok *resokp;
1830 
1831 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1832 		return (FALSE);
1833 	switch (objp->status) {
1834 	case NFS3_OK:
1835 		/* xdr_MKNOD3resok */
1836 		resokp = &objp->resok;
1837 		if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1838 			return (FALSE);
1839 		if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1840 			return (FALSE);
1841 		return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1842 	default:
1843 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1844 	}
1845 }
1846 
1847 bool_t
1848 xdr_REMOVE3res(XDR *xdrs, REMOVE3res *objp)
1849 {
1850 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1851 		return (FALSE);
1852 	switch (objp->status) {
1853 	case NFS3_OK:
1854 		return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
1855 	default:
1856 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1857 	}
1858 }
1859 
1860 bool_t
1861 xdr_RMDIR3res(XDR *xdrs, RMDIR3res *objp)
1862 {
1863 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1864 		return (FALSE);
1865 	switch (objp->status) {
1866 	case NFS3_OK:
1867 		return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
1868 	default:
1869 		return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1870 	}
1871 }
1872 
1873 bool_t
1874 xdr_RENAME3args(XDR *xdrs, RENAME3args *objp)
1875 {
1876 	if (!xdr_diropargs3(xdrs, &objp->from))
1877 		return (FALSE);
1878 	return (xdr_diropargs3(xdrs, &objp->to));
1879 }
1880 
1881 bool_t
1882 xdr_RENAME3res(XDR *xdrs, RENAME3res *objp)
1883 {
1884 	RENAME3resok *resokp;
1885 	RENAME3resfail *resfailp;
1886 
1887 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1888 		return (FALSE);
1889 	switch (objp->status) {
1890 	case NFS3_OK:
1891 		/* xdr_RENAME3resok */
1892 		resokp = &objp->resok;
1893 
1894 		if (!xdr_wcc_data(xdrs, &resokp->fromdir_wcc))
1895 			return (FALSE);
1896 		return (xdr_wcc_data(xdrs, &resokp->todir_wcc));
1897 	default:
1898 		/* xdr_RENAME3resfail */
1899 		resfailp = &objp->resfail;
1900 		if (!xdr_wcc_data(xdrs, &resfailp->fromdir_wcc))
1901 			return (FALSE);
1902 		return (xdr_wcc_data(xdrs, &resfailp->todir_wcc));
1903 	}
1904 }
1905 
1906 bool_t
1907 xdr_LINK3args(XDR *xdrs, LINK3args *objp)
1908 {
1909 	switch (xdrs->x_op) {
1910 	case XDR_FREE:
1911 	case XDR_ENCODE:
1912 		if (!xdr_nfs_fh3(xdrs, &objp->file))
1913 			return (FALSE);
1914 		break;
1915 	case XDR_DECODE:
1916 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
1917 			return (FALSE);
1918 		break;
1919 	}
1920 	return (xdr_diropargs3(xdrs, &objp->link));
1921 }
1922 
1923 bool_t
1924 xdr_LINK3res(XDR *xdrs, LINK3res *objp)
1925 {
1926 	LINK3resok *resokp;
1927 	LINK3resfail *resfailp;
1928 
1929 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1930 		return (FALSE);
1931 	switch (objp->status) {
1932 	case NFS3_OK:
1933 		/* xdr_LINK3resok */
1934 		resokp = &objp->resok;
1935 		if (!xdr_post_op_attr(xdrs, &resokp->file_attributes))
1936 			return (FALSE);
1937 		return (xdr_wcc_data(xdrs, &resokp->linkdir_wcc));
1938 	default:
1939 		/* xdr_LINK3resfail */
1940 		resfailp = &objp->resfail;
1941 		if (!xdr_post_op_attr(xdrs, &resfailp->file_attributes))
1942 			return (FALSE);
1943 		return (xdr_wcc_data(xdrs, &resfailp->linkdir_wcc));
1944 	}
1945 }
1946 
1947 bool_t
1948 xdr_READDIR3args(XDR *xdrs, READDIR3args *objp)
1949 {
1950 	rdma_chunkinfo_t rci;
1951 	struct xdr_ops *xops = xdrrdma_xops();
1952 
1953 	if (xdrs->x_op == XDR_FREE)
1954 		return (TRUE);
1955 
1956 	switch (xdrs->x_op) {
1957 	case XDR_FREE:
1958 	case XDR_ENCODE:
1959 		if (!xdr_nfs_fh3(xdrs, &objp->dir))
1960 			return (FALSE);
1961 		break;
1962 	case XDR_DECODE:
1963 		if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
1964 			return (FALSE);
1965 		break;
1966 	}
1967 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
1968 	    xdrs->x_op == XDR_ENCODE) {
1969 		rci.rci_type = RCI_REPLY_CHUNK;
1970 		rci.rci_len = objp->count;
1971 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1972 	}
1973 
1974 	if (!xdr_u_longlong_t(xdrs, &objp->cookie))
1975 		return (FALSE);
1976 	/*
1977 	 * cookieverf is really an opaque 8 byte
1978 	 * quantity, but we will treat it as a
1979 	 * hyper for efficiency, the cost of
1980 	 * a byteswap here saves bcopys elsewhere
1981 	 */
1982 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
1983 		return (FALSE);
1984 	return (xdr_u_int(xdrs, &objp->count));
1985 }
1986 
1987 #ifdef	nextdp
1988 #undef	nextdp
1989 #endif
1990 #define	nextdp(dp)	((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
1991 #ifdef	roundup
1992 #undef	roundup
1993 #endif
1994 #define	roundup(x, y)	((((x) + ((y) - 1)) / (y)) * (y))
1995 
1996 /*
1997  * ENCODE ONLY
1998  */
1999 static bool_t
2000 xdr_putdirlist(XDR *xdrs, READDIR3resok *objp)
2001 {
2002 	struct dirent64 *dp;
2003 	char *name;
2004 	int size;
2005 	int bufsize;
2006 	uint_t namlen;
2007 	bool_t true = TRUE;
2008 	bool_t false = FALSE;
2009 	int entrysz;
2010 	int tofit;
2011 	fileid3 fileid;
2012 	cookie3 cookie;
2013 
2014 	if (xdrs->x_op != XDR_ENCODE)
2015 		return (FALSE);
2016 
2017 	/*
2018 	 * bufsize is used to keep track of the size of the response.
2019 	 * It is primed with:
2020 	 *	1 for the status +
2021 	 *	1 for the dir_attributes.attributes boolean +
2022 	 *	2 for the cookie verifier
2023 	 * all times BYTES_PER_XDR_UNIT to convert from XDR units
2024 	 * to bytes.  If there are directory attributes to be
2025 	 * returned, then:
2026 	 *	NFS3_SIZEOF_FATTR3 for the dir_attributes.attr fattr3
2027 	 * time BYTES_PER_XDR_UNIT is added to account for them.
2028 	 */
2029 	bufsize = (1 + 1 + 2) * BYTES_PER_XDR_UNIT;
2030 	if (objp->dir_attributes.attributes)
2031 		bufsize += NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
2032 	for (size = objp->size, dp = (struct dirent64 *)objp->reply.entries;
2033 	    size > 0;
2034 	    size -= dp->d_reclen, dp = nextdp(dp)) {
2035 		if (dp->d_reclen == 0)
2036 			return (FALSE);
2037 		if (dp->d_ino == 0)
2038 			continue;
2039 		name = dp->d_name;
2040 		namlen = (uint_t)strlen(dp->d_name);
2041 		/*
2042 		 * An entry is composed of:
2043 		 *	1 for the true/false list indicator +
2044 		 *	2 for the fileid +
2045 		 *	1 for the length of the name +
2046 		 *	2 for the cookie +
2047 		 * all times BYTES_PER_XDR_UNIT to convert from
2048 		 * XDR units to bytes, plus the length of the name
2049 		 * rounded up to the nearest BYTES_PER_XDR_UNIT.
2050 		 */
2051 		entrysz = (1 + 2 + 1 + 2) * BYTES_PER_XDR_UNIT +
2052 		    roundup(namlen, BYTES_PER_XDR_UNIT);
2053 		/*
2054 		 * We need to check to see if the number of bytes left
2055 		 * to go into the buffer will actually fit into the
2056 		 * buffer.  This is calculated as the size of this
2057 		 * entry plus:
2058 		 *	1 for the true/false list indicator +
2059 		 *	1 for the eof indicator
2060 		 * times BYTES_PER_XDR_UNIT to convert from from
2061 		 * XDR units to bytes.
2062 		 */
2063 		tofit = entrysz + (1 + 1) * BYTES_PER_XDR_UNIT;
2064 		if (bufsize + tofit > objp->count) {
2065 			objp->reply.eof = FALSE;
2066 			break;
2067 		}
2068 		fileid = (fileid3)(dp->d_ino);
2069 		cookie = (cookie3)(dp->d_off);
2070 		if (!xdr_bool(xdrs, &true) ||
2071 		    !xdr_u_longlong_t(xdrs, &fileid) ||
2072 		    !xdr_bytes(xdrs, &name, &namlen, ~0) ||
2073 		    !xdr_u_longlong_t(xdrs, &cookie)) {
2074 			return (FALSE);
2075 		}
2076 		bufsize += entrysz;
2077 	}
2078 	if (!xdr_bool(xdrs, &false))
2079 		return (FALSE);
2080 	if (!xdr_bool(xdrs, &objp->reply.eof))
2081 		return (FALSE);
2082 	return (TRUE);
2083 }
2084 
2085 bool_t
2086 xdr_READDIR3res(XDR *xdrs, READDIR3res *objp)
2087 {
2088 	READDIR3resok *resokp;
2089 
2090 	/*
2091 	 * ENCODE or FREE only
2092 	 */
2093 	if (xdrs->x_op == XDR_DECODE)
2094 		return (FALSE);
2095 
2096 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2097 		return (FALSE);
2098 	if (objp->status != NFS3_OK)
2099 		return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
2100 
2101 	/* xdr_READDIR3resok */
2102 	resokp = &objp->resok;
2103 	if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
2104 		return (FALSE);
2105 	if (xdrs->x_op != XDR_ENCODE)
2106 		return (TRUE);
2107 	/*
2108 	 * cookieverf is really an opaque 8 byte
2109 	 * quantity, but we will treat it as a
2110 	 * hyper for efficiency, the cost of
2111 	 * a byteswap here saves bcopys elsewhere
2112 	 */
2113 	if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
2114 		return (FALSE);
2115 	return (xdr_putdirlist(xdrs, resokp));
2116 }
2117 
2118 bool_t
2119 xdr_READDIR3vres(XDR *xdrs, READDIR3vres *objp)
2120 {
2121 	dirent64_t *dp;
2122 	uint_t entries_size;
2123 	int outcount = 0;
2124 
2125 	/*
2126 	 * DECODE or FREE only
2127 	 */
2128 	if (xdrs->x_op == XDR_FREE)
2129 		return (TRUE);
2130 
2131 	if (xdrs->x_op != XDR_DECODE)
2132 		return (FALSE);
2133 
2134 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2135 		return (FALSE);
2136 
2137 	if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
2138 		return (FALSE);
2139 
2140 	if (objp->status != NFS3_OK)
2141 		return (TRUE);
2142 
2143 	/*
2144 	 * cookieverf is really an opaque 8 byte
2145 	 * quantity, but we will treat it as a
2146 	 * hyper for efficiency, the cost of
2147 	 * a byteswap here saves bcopys elsewhere
2148 	 */
2149 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2150 		return (FALSE);
2151 
2152 	entries_size = objp->entries_size;
2153 	dp = objp->entries;
2154 
2155 	for (;;) {
2156 		uint_t this_reclen;
2157 		bool_t valid;
2158 		uint_t namlen;
2159 		ino64_t fileid;
2160 
2161 		if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
2162 			return (FALSE);
2163 		if (!valid) {
2164 			/*
2165 			 * We have run out of entries, decode eof.
2166 			 */
2167 			if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
2168 				return (FALSE);
2169 
2170 			break;
2171 		}
2172 
2173 		/*
2174 		 * fileid3 fileid
2175 		 */
2176 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
2177 			return (FALSE);
2178 
2179 		/*
2180 		 * filename3 name
2181 		 */
2182 		if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
2183 			return (FALSE);
2184 		this_reclen = DIRENT64_RECLEN(namlen);
2185 
2186 		/*
2187 		 * If this will overflow buffer, stop decoding
2188 		 */
2189 		if ((outcount + this_reclen) > entries_size) {
2190 			objp->eof = FALSE;
2191 			break;
2192 		}
2193 		dp->d_reclen = this_reclen;
2194 		dp->d_ino = fileid;
2195 
2196 		if (!xdr_opaque(xdrs, dp->d_name, namlen))
2197 			return (FALSE);
2198 		bzero(&dp->d_name[namlen],
2199 		    DIRENT64_NAMELEN(this_reclen) - namlen);
2200 
2201 		/*
2202 		 * cookie3 cookie
2203 		 */
2204 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
2205 			return (FALSE);
2206 		objp->loff = dp->d_off;
2207 
2208 		outcount += this_reclen;
2209 		dp = (dirent64_t *)((intptr_t)dp + this_reclen);
2210 	}
2211 
2212 	objp->size = outcount;
2213 	return (TRUE);
2214 }
2215 
2216 bool_t
2217 xdr_READDIRPLUS3args(XDR *xdrs, READDIRPLUS3args *objp)
2218 {
2219 	rdma_chunkinfo_t rci;
2220 	struct xdr_ops *xops = xdrrdma_xops();
2221 
2222 	if (xdrs->x_op == XDR_FREE)
2223 		return (TRUE);
2224 
2225 	switch (xdrs->x_op) {
2226 	case XDR_FREE:
2227 	case XDR_ENCODE:
2228 		if (!xdr_nfs_fh3(xdrs, &objp->dir))
2229 			return (FALSE);
2230 		break;
2231 	case XDR_DECODE:
2232 		if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
2233 			return (FALSE);
2234 		break;
2235 	}
2236 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
2237 	    xdrs->x_op == XDR_ENCODE) {
2238 		rci.rci_type = RCI_REPLY_CHUNK;
2239 		rci.rci_len = objp->maxcount;
2240 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
2241 	}
2242 
2243 	if (!xdr_u_longlong_t(xdrs, &objp->cookie))
2244 		return (FALSE);
2245 	/*
2246 	 * cookieverf is really an opaque 8 byte
2247 	 * quantity, but we will treat it as a
2248 	 * hyper for efficiency, the cost of
2249 	 * a byteswap here saves bcopys elsewhere
2250 	 */
2251 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2252 		return (FALSE);
2253 	if (!xdr_u_int(xdrs, &objp->dircount))
2254 		return (FALSE);
2255 	return (xdr_u_int(xdrs, &objp->maxcount));
2256 }
2257 
2258 /*
2259  * ENCODE ONLY
2260  */
2261 static bool_t
2262 xdr_putdirpluslist(XDR *xdrs, READDIRPLUS3resok *objp)
2263 {
2264 	struct dirent64 *dp;
2265 	char *name;
2266 	int nents;
2267 	bool_t true = TRUE;
2268 	bool_t false = FALSE;
2269 	fileid3 fileid;
2270 	cookie3 cookie;
2271 	entryplus3_info *infop;
2272 
2273 	if (xdrs->x_op != XDR_ENCODE)
2274 		return (FALSE);
2275 
2276 	dp = (struct dirent64 *)objp->reply.entries;
2277 	nents = objp->size;
2278 	infop = objp->infop;
2279 
2280 	while (nents > 0) {
2281 		if (dp->d_reclen == 0)
2282 			return (FALSE);
2283 		if (dp->d_ino != 0) {
2284 			name = dp->d_name;
2285 			fileid = (fileid3)(dp->d_ino);
2286 			cookie = (cookie3)(dp->d_off);
2287 			if (!xdr_bool(xdrs, &true) ||
2288 			    !xdr_u_longlong_t(xdrs, &fileid) ||
2289 			    !xdr_bytes(xdrs, &name, &infop->namelen, ~0) ||
2290 			    !xdr_u_longlong_t(xdrs, &cookie) ||
2291 			    !xdr_post_op_attr(xdrs, &infop->attr) ||
2292 			    !xdr_post_op_fh3(xdrs, &infop->fh)) {
2293 				return (FALSE);
2294 			}
2295 		}
2296 		dp = nextdp(dp);
2297 		infop++;
2298 		nents--;
2299 	}
2300 
2301 	if (!xdr_bool(xdrs, &false))
2302 		return (FALSE);
2303 	if (!xdr_bool(xdrs, &objp->reply.eof))
2304 		return (FALSE);
2305 	return (TRUE);
2306 }
2307 
2308 bool_t
2309 xdr_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
2310 {
2311 	READDIRPLUS3resok *resokp;
2312 
2313 	/*
2314 	 * ENCODE or FREE only
2315 	 */
2316 	if (xdrs->x_op == XDR_DECODE)
2317 		return (FALSE);
2318 
2319 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2320 		return (FALSE);
2321 	switch (objp->status) {
2322 	case NFS3_OK:
2323 		/* xdr_READDIRPLUS3resok */
2324 		resokp = &objp->resok;
2325 		if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
2326 			return (FALSE);
2327 		/*
2328 		 * cookieverf is really an opaque 8 byte
2329 		 * quantity, but we will treat it as a
2330 		 * hyper for efficiency, the cost of
2331 		 * a byteswap here saves bcopys elsewhere
2332 		 */
2333 		if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
2334 			return (FALSE);
2335 		if (xdrs->x_op == XDR_ENCODE) {
2336 			if (!xdr_putdirpluslist(xdrs, resokp))
2337 				return (FALSE);
2338 		}
2339 		break;
2340 	default:
2341 		return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
2342 	}
2343 	return (TRUE);
2344 }
2345 
2346 /*
2347  * Decode readdirplus directly into a dirent64_t and do the DNLC caching.
2348  */
2349 bool_t
2350 xdr_READDIRPLUS3vres(XDR *xdrs, READDIRPLUS3vres *objp)
2351 {
2352 	dirent64_t *dp;
2353 	vnode_t *dvp;
2354 	uint_t entries_size;
2355 	int outcount = 0;
2356 	vnode_t *nvp;
2357 	rnode_t *rp;
2358 	post_op_vattr pov;
2359 	vattr_t va;
2360 
2361 	/*
2362 	 * DECODE or FREE only
2363 	 */
2364 	if (xdrs->x_op == XDR_FREE)
2365 		return (TRUE);
2366 
2367 	if (xdrs->x_op != XDR_DECODE)
2368 		return (FALSE);
2369 
2370 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
2371 		return (FALSE);
2372 
2373 	if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
2374 		return (FALSE);
2375 
2376 	if (objp->status != NFS3_OK)
2377 		return (TRUE);
2378 
2379 	/*
2380 	 * cookieverf is really an opaque 8 byte
2381 	 * quantity, but we will treat it as a
2382 	 * hyper for efficiency, the cost of
2383 	 * a byteswap here saves bcopys elsewhere
2384 	 */
2385 	if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2386 		return (FALSE);
2387 
2388 	dvp = objp->dir_attributes.fres.vp;
2389 	rp = VTOR(dvp);
2390 
2391 	pov.fres.vap = &va;
2392 	pov.fres.vp = dvp;
2393 
2394 	entries_size = objp->entries_size;
2395 	dp = objp->entries;
2396 
2397 	for (;;) {
2398 		uint_t this_reclen;
2399 		bool_t valid;
2400 		uint_t namlen;
2401 		nfs_fh3 fh;
2402 		int va_valid;
2403 		int fh_valid;
2404 		ino64_t fileid;
2405 
2406 		if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
2407 			return (FALSE);
2408 		if (!valid) {
2409 			/*
2410 			 * We have run out of entries, decode eof.
2411 			 */
2412 			if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
2413 				return (FALSE);
2414 
2415 			break;
2416 		}
2417 
2418 		/*
2419 		 * fileid3 fileid
2420 		 */
2421 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
2422 			return (FALSE);
2423 
2424 		/*
2425 		 * filename3 name
2426 		 */
2427 		if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
2428 			return (FALSE);
2429 		this_reclen = DIRENT64_RECLEN(namlen);
2430 
2431 		/*
2432 		 * If this will overflow buffer, stop decoding
2433 		 */
2434 		if ((outcount + this_reclen) > entries_size) {
2435 			objp->eof = FALSE;
2436 			break;
2437 		}
2438 		dp->d_reclen = this_reclen;
2439 		dp->d_ino = fileid;
2440 
2441 		if (!xdr_opaque(xdrs, dp->d_name, namlen))
2442 			return (FALSE);
2443 		bzero(&dp->d_name[namlen],
2444 		    DIRENT64_NAMELEN(this_reclen) - namlen);
2445 
2446 		/*
2447 		 * cookie3 cookie
2448 		 */
2449 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
2450 			return (FALSE);
2451 		objp->loff = dp->d_off;
2452 
2453 		/*
2454 		 * post_op_attr name_attributes
2455 		 */
2456 		if (!xdr_post_op_vattr(xdrs, &pov))
2457 			return (FALSE);
2458 
2459 		if (pov.attributes == TRUE &&
2460 		    pov.fres.status == NFS3_OK)
2461 			va_valid = TRUE;
2462 		else
2463 			va_valid = FALSE;
2464 
2465 		/*
2466 		 * post_op_fh3 name_handle
2467 		 */
2468 		if (!XDR_GETINT32(xdrs, (int32_t *)&fh_valid))
2469 			return (FALSE);
2470 
2471 		/*
2472 		 * By definition of the standard fh_valid can be 0 (FALSE) or
2473 		 * 1 (TRUE), but we have to account for it being anything else
2474 		 * in case some other system didn't follow the standard.  Note
2475 		 * that this is why the else checks if the fh_valid variable
2476 		 * is != FALSE.
2477 		 */
2478 		if (fh_valid == TRUE) {
2479 			if (!xdr_nfs_fh3(xdrs, &fh))
2480 				return (FALSE);
2481 		} else {
2482 			if (fh_valid != FALSE)
2483 				return (FALSE);
2484 		}
2485 
2486 		/*
2487 		 * If the name is "." or there are no attributes,
2488 		 * don't polute the DNLC with "." entries or files
2489 		 * we cannot determine the type for.
2490 		 */
2491 		if (!(namlen == 1 && dp->d_name[0] == '.') &&
2492 		    va_valid && fh_valid) {
2493 
2494 			/*
2495 			 * Do the DNLC caching
2496 			 */
2497 			nvp = makenfs3node_va(&fh, &va, dvp->v_vfsp,
2498 			    objp->time, objp->credentials,
2499 			    rp->r_path, dp->d_name);
2500 			dnlc_update(dvp, dp->d_name, nvp);
2501 			VN_RELE(nvp);
2502 		}
2503 
2504 		outcount += this_reclen;
2505 		dp = (dirent64_t *)((intptr_t)dp + this_reclen);
2506 	}
2507 
2508 	objp->size = outcount;
2509 	return (TRUE);
2510 }
2511 
2512 bool_t
2513 xdr_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp)
2514 {
2515 	FSSTAT3resok *resokp;
2516 
2517 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2518 		return (FALSE);
2519 	if (objp->status != NFS3_OK)
2520 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
2521 
2522 	/* xdr_FSSTAT3resok */
2523 	resokp = &objp->resok;
2524 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
2525 		return (FALSE);
2526 	if (!xdr_u_longlong_t(xdrs, &resokp->tbytes))
2527 		return (FALSE);
2528 	if (!xdr_u_longlong_t(xdrs, &resokp->fbytes))
2529 		return (FALSE);
2530 	if (!xdr_u_longlong_t(xdrs, &resokp->abytes))
2531 		return (FALSE);
2532 	if (!xdr_u_longlong_t(xdrs, &resokp->tfiles))
2533 		return (FALSE);
2534 	if (!xdr_u_longlong_t(xdrs, &resokp->ffiles))
2535 		return (FALSE);
2536 	if (!xdr_u_longlong_t(xdrs, &resokp->afiles))
2537 		return (FALSE);
2538 	return (xdr_u_int(xdrs, &resokp->invarsec));
2539 }
2540 
2541 bool_t
2542 xdr_FSINFO3res(XDR *xdrs, FSINFO3res *objp)
2543 {
2544 	FSINFO3resok *resokp;
2545 
2546 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2547 		return (FALSE);
2548 	if (objp->status != NFS3_OK) /* xdr_FSSTAT3resfail */
2549 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
2550 
2551 	/* xdr_FSINFO3resok */
2552 	resokp = &objp->resok;
2553 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
2554 		return (FALSE);
2555 	if (!xdr_u_int(xdrs, &resokp->rtmax))
2556 		return (FALSE);
2557 	if (!xdr_u_int(xdrs, &resokp->rtpref))
2558 		return (FALSE);
2559 	if (!xdr_u_int(xdrs, &resokp->rtmult))
2560 		return (FALSE);
2561 	if (!xdr_u_int(xdrs, &resokp->wtmax))
2562 		return (FALSE);
2563 	if (!xdr_u_int(xdrs, &resokp->wtpref))
2564 		return (FALSE);
2565 	if (!xdr_u_int(xdrs, &resokp->wtmult))
2566 		return (FALSE);
2567 	if (!xdr_u_int(xdrs, &resokp->dtpref))
2568 		return (FALSE);
2569 	if (!xdr_u_longlong_t(xdrs, &resokp->maxfilesize))
2570 		return (FALSE);
2571 	if (!xdr_u_int(xdrs, &resokp->time_delta.seconds))
2572 		return (FALSE);
2573 	if (!xdr_u_int(xdrs, &resokp->time_delta.nseconds))
2574 		return (FALSE);
2575 	return (xdr_u_int(xdrs, &resokp->properties));
2576 }
2577 
2578 bool_t
2579 xdr_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp)
2580 {
2581 	PATHCONF3resok *resokp;
2582 
2583 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2584 		return (FALSE);
2585 	if (objp->status != NFS3_OK)
2586 		return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
2587 
2588 	/* xdr_PATHCONF3resok */
2589 	resokp = &objp->resok;
2590 	if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
2591 		return (FALSE);
2592 	if (!xdr_u_int(xdrs, &resokp->info.link_max))
2593 		return (FALSE);
2594 	if (!xdr_u_int(xdrs, &resokp->info.name_max))
2595 		return (FALSE);
2596 	if (!xdr_bool(xdrs, &resokp->info.no_trunc))
2597 		return (FALSE);
2598 	if (!xdr_bool(xdrs, &resokp->info.chown_restricted))
2599 		return (FALSE);
2600 	if (!xdr_bool(xdrs, &resokp->info.case_insensitive))
2601 		return (FALSE);
2602 	return (xdr_bool(xdrs, &resokp->info.case_preserving));
2603 }
2604 
2605 bool_t
2606 xdr_COMMIT3args(XDR *xdrs, COMMIT3args *objp)
2607 {
2608 	if (xdrs->x_op == XDR_FREE)
2609 		return (TRUE);
2610 
2611 	switch (xdrs->x_op) {
2612 	case XDR_FREE:
2613 	case XDR_ENCODE:
2614 		if (!xdr_nfs_fh3(xdrs, &objp->file))
2615 			return (FALSE);
2616 		break;
2617 	case XDR_DECODE:
2618 		if (!xdr_nfs_fh3_server(xdrs, &objp->file))
2619 			return (FALSE);
2620 		break;
2621 	}
2622 	if (!xdr_u_longlong_t(xdrs, &objp->offset))
2623 		return (FALSE);
2624 	return (xdr_u_int(xdrs, &objp->count));
2625 }
2626 
2627 bool_t
2628 xdr_COMMIT3res(XDR *xdrs, COMMIT3res *objp)
2629 {
2630 	COMMIT3resok *resokp;
2631 
2632 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2633 		return (FALSE);
2634 	if (objp->status != NFS3_OK)
2635 		return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
2636 
2637 	/* xdr_COMMIT3resok */
2638 	resokp = &objp->resok;
2639 	if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
2640 		return (FALSE);
2641 	/*
2642 	 * writeverf3 is really an opaque 8 byte
2643 	 * quantity, but we will treat it as a
2644 	 * hyper for efficiency, the cost of
2645 	 * a byteswap here saves bcopys elsewhere
2646 	 */
2647 	return (xdr_u_longlong_t(xdrs, &resokp->verf));
2648 }
2649