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