Home | History | Annotate | Download | only in nfs
      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