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