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