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