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