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