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 /*
     27  * A handcoded version based on the original rpcgen code.
     28  *
     29  * Note: All future NFS4 protocol changes should be added by hand
     30  * to this file.
     31  *
     32  * CAUTION: All protocol changes must also be propagated to:
     33  *     usr/src/cmd/cmd-inet/usr.sbin/snoop/nfs4_xdr.c
     34  */
     35 
     36 #include <sys/types.h>
     37 #include <sys/sunddi.h>
     38 #include <sys/dnlc.h>
     39 #include <nfs/nfs.h>
     40 #include <nfs/nfs4_kprot.h>
     41 #include <nfs/rnode4.h>
     42 #include <nfs/nfs4.h>
     43 #include <nfs/nfs4_clnt.h>
     44 #include <sys/sdt.h>
     45 #include <rpc/rpc_rdma.h>
     46 
     47 bool_t
     48 xdr_bitmap4(XDR *xdrs, bitmap4 *objp)
     49 {
     50 	int32_t len, size;
     51 
     52 	if (xdrs->x_op == XDR_FREE)
     53 		return (TRUE);
     54 
     55 	/*
     56 	 * Simplified bitmap4 processing, always encode from uint64_t
     57 	 * to 2 uint32_t's, always decode first 2 uint32_t's into a
     58 	 * uint64_t and ignore all of the rest.
     59 	 */
     60 	if (xdrs->x_op == XDR_ENCODE) {
     61 		len = 2;
     62 
     63 		if (!XDR_PUTINT32(xdrs, &len))
     64 			return (FALSE);
     65 
     66 #if defined(_LITTLE_ENDIAN)
     67 		if (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
     68 		    BYTES_PER_XDR_UNIT)) == TRUE) {
     69 			return (XDR_PUTINT32(xdrs, (int32_t *)objp));
     70 		}
     71 #elif defined(_BIG_ENDIAN)
     72 		if (XDR_PUTINT32(xdrs, (int32_t *)objp) == TRUE) {
     73 			return (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp +
     74 			    BYTES_PER_XDR_UNIT)));
     75 		}
     76 #endif
     77 		return (FALSE);
     78 	}
     79 
     80 	if (!XDR_GETINT32(xdrs, &len))
     81 		return (FALSE);
     82 
     83 	/*
     84 	 * Common fast DECODE cases
     85 	 */
     86 	if (len == 2) {
     87 #if defined(_LITTLE_ENDIAN)
     88 		if (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
     89 		    BYTES_PER_XDR_UNIT)) == TRUE) {
     90 			return (XDR_GETINT32(xdrs, (int32_t *)objp));
     91 		}
     92 #elif defined(_BIG_ENDIAN)
     93 		if (XDR_GETINT32(xdrs, (int32_t *)objp) == TRUE) {
     94 			return (XDR_GETINT32(xdrs, (int32_t *)((char *)objp +
     95 			    BYTES_PER_XDR_UNIT)));
     96 		}
     97 #endif
     98 		return (FALSE);
     99 	}
    100 
    101 	*objp = 0;
    102 	if (len == 0)
    103 		return (TRUE);
    104 
    105 	/*
    106 	 * The not so common DECODE cases, len == 1 || len > 2
    107 	 */
    108 #if defined(_LITTLE_ENDIAN)
    109 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
    110 		return (FALSE);
    111 	if (--len == 0)
    112 		return (TRUE);
    113 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
    114 		return (FALSE);
    115 #elif defined(_BIG_ENDIAN)
    116 	if (!XDR_GETINT32(xdrs, (int32_t *)objp))
    117 		return (FALSE);
    118 	if (--len == 0)
    119 		return (TRUE);
    120 	if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT)))
    121 		return (FALSE);
    122 #else
    123 	return (FALSE);
    124 #endif
    125 
    126 	if (--len == 0)
    127 		return (TRUE);
    128 
    129 	size = len * BYTES_PER_XDR_UNIT;
    130 	return (XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size));
    131 }
    132 
    133 /* Called by xdr_array, nfsid_map_xdr */
    134 bool_t
    135 xdr_utf8string(XDR *xdrs, utf8string *objp)
    136 {
    137 	if (xdrs->x_op != XDR_FREE)
    138 		return (xdr_bytes(xdrs, (char **)&objp->utf8string_val,
    139 		    (uint_t *)&objp->utf8string_len, NFS4_MAX_UTF8STRING));
    140 
    141 	if (objp->utf8string_val != NULL) {
    142 		kmem_free(objp->utf8string_val, objp->utf8string_len);
    143 		objp->utf8string_val = NULL;
    144 	}
    145 	return (TRUE);
    146 }
    147 
    148 /*
    149  * XDR_INLINE decode a filehandle.
    150  */
    151 bool_t
    152 xdr_inline_decode_nfs_fh4(uint32_t *ptr, nfs_fh4_fmt_t *fhp, uint32_t fhsize)
    153 {
    154 	uchar_t *bp = (uchar_t *)ptr;
    155 	uchar_t *cp;
    156 	uint32_t dsize;
    157 	uintptr_t resid;
    158 
    159 	/*
    160 	 * Check to see if what the client sent us is bigger or smaller
    161 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
    162 	 * unfortunately badly named as it is no longer the max and is
    163 	 * really the min of what is sent over the wire.
    164 	 */
    165 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
    166 	    sizeof (ushort_t) + NFS_FHMAXDATA +
    167 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
    168 		return (FALSE);
    169 	}
    170 
    171 	/*
    172 	 * All internal parts of a filehandle are in native byte order.
    173 	 *
    174 	 * Decode what should be fh4_fsid, it is aligned.
    175 	 */
    176 	fhp->fh4_fsid.val[0] = *(uint32_t *)bp;
    177 	bp += BYTES_PER_XDR_UNIT;
    178 	fhp->fh4_fsid.val[1] = *(uint32_t *)bp;
    179 	bp += BYTES_PER_XDR_UNIT;
    180 
    181 	/*
    182 	 * Decode what should be fh4_len.  fh4_len is two bytes, so we're
    183 	 * unaligned now.
    184 	 */
    185 	cp = (uchar_t *)&fhp->fh4_len;
    186 	*cp++ = *bp++;
    187 	*cp++ = *bp++;
    188 	fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
    189 
    190 	/*
    191 	 * For backwards compatibility, the fid length may be less than
    192 	 * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
    193 	 */
    194 	dsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
    195 
    196 	/*
    197 	 * Make sure the client isn't sending us a bogus length for fh4_data.
    198 	 */
    199 	if (fhsize < dsize)
    200 		return (FALSE);
    201 	bcopy(bp, fhp->fh4_data, dsize);
    202 	bp += dsize;
    203 	fhsize -= dsize;
    204 
    205 	if (fhsize < sizeof (ushort_t))
    206 		return (FALSE);
    207 	cp = (uchar_t *)&fhp->fh4_xlen;
    208 	*cp++ = *bp++;
    209 	*cp++ = *bp++;
    210 	fhsize -= sizeof (ushort_t);
    211 
    212 	dsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
    213 
    214 	/*
    215 	 * Make sure the client isn't sending us a bogus length for fh4_xdata.
    216 	 */
    217 	if (fhsize < dsize)
    218 		return (FALSE);
    219 	bcopy(bp, fhp->fh4_xdata, dsize);
    220 	fhsize -= dsize;
    221 	bp += dsize;
    222 
    223 	/*
    224 	 * We realign things on purpose, so skip any padding
    225 	 */
    226 	resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
    227 	if (resid != 0) {
    228 		if (fhsize < (BYTES_PER_XDR_UNIT - resid))
    229 			return (FALSE);
    230 		bp += BYTES_PER_XDR_UNIT - resid;
    231 		fhsize -= BYTES_PER_XDR_UNIT - resid;
    232 	}
    233 
    234 	if (fhsize < BYTES_PER_XDR_UNIT)
    235 		return (FALSE);
    236 	fhp->fh4_flag = *(uint32_t *)bp;
    237 	bp += BYTES_PER_XDR_UNIT;
    238 	fhsize -= BYTES_PER_XDR_UNIT;
    239 
    240 #ifdef VOLATILE_FH_TEST
    241 	if (fhsize < BYTES_PER_XDR_UNIT)
    242 		return (FALSE);
    243 	fhp->fh4_volatile_id = *(uint32_t *)bp;
    244 	bp += BYTES_PER_XDR_UNIT;
    245 	fhsize -= BYTES_PER_XDR_UNIT;
    246 #endif
    247 	/*
    248 	 * Make sure client didn't send extra bytes
    249 	 */
    250 	if (fhsize != 0)
    251 		return (FALSE);
    252 	return (TRUE);
    253 }
    254 
    255 static bool_t
    256 xdr_decode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
    257 {
    258 	uint32_t fhsize;		/* filehandle size */
    259 	uint32_t bufsize;
    260 	rpc_inline_t *ptr;
    261 	uchar_t *bp;
    262 
    263 	ASSERT(xdrs->x_op == XDR_DECODE);
    264 
    265 	/*
    266 	 * Retrieve the filehandle length.
    267 	 */
    268 	if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
    269 		return (FALSE);
    270 
    271 	objp->nfs_fh4_val = NULL;
    272 	objp->nfs_fh4_len = 0;
    273 
    274 	/*
    275 	 * Check to see if what the client sent us is bigger or smaller
    276 	 * than what we can ever possibly send out. NFS_FHMAXDATA is
    277 	 * unfortunately badly named as it is no longer the max and is
    278 	 * really the min of what is sent over the wire.
    279 	 */
    280 	if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) +
    281 	    sizeof (ushort_t) + NFS_FHMAXDATA +
    282 	    sizeof (ushort_t) + NFS_FHMAXDATA)) {
    283 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
    284 			return (FALSE);
    285 		return (TRUE);
    286 	}
    287 
    288 	/*
    289 	 * bring in fhsize plus any padding
    290 	 */
    291 	bufsize = RNDUP(fhsize);
    292 	ptr = XDR_INLINE(xdrs, bufsize);
    293 	bp = (uchar_t *)ptr;
    294 	if (ptr == NULL) {
    295 		bp = kmem_alloc(bufsize, KM_SLEEP);
    296 		if (!xdr_opaque(xdrs, (char *)bp, bufsize)) {
    297 			kmem_free(bp, bufsize);
    298 			return (FALSE);
    299 		}
    300 	}
    301 
    302 	objp->nfs_fh4_val = kmem_zalloc(sizeof (nfs_fh4_fmt_t), KM_SLEEP);
    303 	objp->nfs_fh4_len = sizeof (nfs_fh4_fmt_t);
    304 
    305 	if (xdr_inline_decode_nfs_fh4((uint32_t *)bp,
    306 	    (nfs_fh4_fmt_t *)objp->nfs_fh4_val, fhsize) == FALSE) {
    307 		/*
    308 		 * If in the process of decoding we find the file handle
    309 		 * is not correctly formed, we need to continue decoding
    310 		 * and trigger an NFS layer error. Set the nfs_fh4_len to
    311 		 * zero so it gets caught as a bad length.
    312 		 */
    313 		kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
    314 		objp->nfs_fh4_val = NULL;
    315 		objp->nfs_fh4_len = 0;
    316 	}
    317 
    318 	if (ptr == NULL)
    319 		kmem_free(bp, bufsize);
    320 	return (TRUE);
    321 }
    322 
    323 /*
    324  * XDR_INLINE encode a filehandle.
    325  */
    326 bool_t
    327 xdr_inline_encode_nfs_fh4(uint32_t **ptrp, uint32_t *ptr_redzone,
    328 	nfs_fh4_fmt_t *fhp)
    329 {
    330 	uint32_t *ptr = *ptrp;
    331 	uchar_t *cp;
    332 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
    333 	uint32_t padword;
    334 
    335 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
    336 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
    337 
    338 	/*
    339 	 * First get the initial and variable sized part of the filehandle.
    340 	 */
    341 	otw_len = sizeof (fhp->fh4_fsid) +
    342 	    sizeof (fhp->fh4_len) + fsize +
    343 	    sizeof (fhp->fh4_xlen) + xsize;
    344 
    345 	/*
    346 	 * Round out to a full word.
    347 	 */
    348 	otw_len = RNDUP(otw_len);
    349 	padword = (otw_len / BYTES_PER_XDR_UNIT);	/* includes fhlen */
    350 
    351 	/*
    352 	 * Add in the fixed sized pieces.
    353 	 */
    354 	otw_len += sizeof (fhp->fh4_flag);
    355 #ifdef VOLATILE_FH_TEST
    356 	otw_len += sizeof (fhp->fh4_volatile_id);
    357 #endif
    358 
    359 	/*
    360 	 * Make sure we don't exceed our buffer.
    361 	 */
    362 	if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone)
    363 		return (FALSE);
    364 
    365 	/*
    366 	 * Zero out the padding.
    367 	 */
    368 	ptr[padword] = 0;
    369 
    370 	IXDR_PUT_U_INT32(ptr, otw_len);
    371 
    372 	/*
    373 	 * The rest of the filehandle is in native byteorder
    374 	 */
    375 	/* fh4_fsid */
    376 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[0];
    377 	*ptr++ = (uint32_t)fhp->fh4_fsid.val[1];
    378 
    379 	/*
    380 	 * Since the next pieces are unaligned, we need to
    381 	 * do bytewise copies.
    382 	 */
    383 	cp = (uchar_t *)ptr;
    384 
    385 	/* fh4_len + fh4_data */
    386 	bcopy(&fhp->fh4_len, cp, sizeof (fhp->fh4_len) + fsize);
    387 	cp += sizeof (fhp->fh4_len) + fsize;
    388 
    389 	/* fh4_xlen + fh4_xdata */
    390 	bcopy(&fhp->fh4_xlen, cp, sizeof (fhp->fh4_xlen) + xsize);
    391 	cp += sizeof (fhp->fh4_xlen) + xsize;
    392 
    393 	/* do necessary rounding/padding */
    394 	cp = (uchar_t *)RNDUP((uintptr_t)cp);
    395 	ptr = (uint32_t *)cp;
    396 
    397 	/*
    398 	 * With the above padding, we're word aligned again.
    399 	 */
    400 	ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0);
    401 
    402 	/* fh4_flag */
    403 	*ptr++ = (uint32_t)fhp->fh4_flag;
    404 
    405 #ifdef VOLATILE_FH_TEST
    406 	/* fh4_volatile_id */
    407 	*ptr++ = (uint32_t)fhp->fh4_volatile_id;
    408 #endif
    409 	*ptrp = ptr;
    410 
    411 	return (TRUE);
    412 }
    413 
    414 static bool_t
    415 xdr_encode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
    416 {
    417 	uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
    418 	bool_t ret;
    419 	rpc_inline_t *ptr;
    420 	rpc_inline_t *buf = NULL;
    421 	uint32_t *ptr_redzone;
    422 	nfs_fh4_fmt_t *fhp;
    423 
    424 	ASSERT(xdrs->x_op == XDR_ENCODE);
    425 
    426 	fhp = (nfs_fh4_fmt_t *)objp->nfs_fh4_val;
    427 	fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len;
    428 	xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen;
    429 
    430 	/*
    431 	 * First get the over the wire size, it is the 4 bytes
    432 	 * for the length, plus the combined size of the
    433 	 * file handle components.
    434 	 */
    435 	otw_len = BYTES_PER_XDR_UNIT + sizeof (fhp->fh4_fsid) +
    436 	    sizeof (fhp->fh4_len) + fsize +
    437 	    sizeof (fhp->fh4_xlen) + xsize +
    438 	    sizeof (fhp->fh4_flag);
    439 #ifdef VOLATILE_FH_TEST
    440 	otw_len += sizeof (fhp->fh4_volatile_id);
    441 #endif
    442 	/*
    443 	 * Round out to a full word.
    444 	 */
    445 	otw_len = RNDUP(otw_len);
    446 
    447 	/*
    448 	 * Next try to inline the XDR stream, if that fails (rare)
    449 	 * allocate a buffer to encode the file handle and then
    450 	 * copy it using xdr_opaque and free the buffer.
    451 	 */
    452 	ptr = XDR_INLINE(xdrs, otw_len);
    453 	if (ptr == NULL)
    454 		ptr = buf = kmem_alloc(otw_len, KM_SLEEP);
    455 
    456 	ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT));
    457 	ret = xdr_inline_encode_nfs_fh4((uint32_t **)&ptr, ptr_redzone, fhp);
    458 
    459 	if (buf != NULL) {
    460 		if (ret == TRUE)
    461 			ret = xdr_opaque(xdrs, (char *)buf, otw_len);
    462 		kmem_free(buf, otw_len);
    463 	}
    464 	return (ret);
    465 }
    466 
    467 /*
    468  * XDR a NFSv4 filehandle.
    469  * Encoding interprets the contents (server).
    470  * Decoding the contents are opaque (client).
    471  */
    472 bool_t
    473 xdr_nfs_fh4(XDR *xdrs, nfs_fh4 *objp)
    474 {
    475 	switch (xdrs->x_op) {
    476 	case XDR_ENCODE:
    477 		return (xdr_encode_nfs_fh4(xdrs, objp));
    478 	case XDR_DECODE:
    479 		return (xdr_bytes(xdrs, (char **)&objp->nfs_fh4_val,
    480 		    (uint_t *)&objp->nfs_fh4_len, NFS4_FHSIZE));
    481 	case XDR_FREE:
    482 		if (objp->nfs_fh4_val != NULL) {
    483 			kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len);
    484 			objp->nfs_fh4_val = NULL;
    485 		}
    486 		return (TRUE);
    487 	}
    488 	return (FALSE);
    489 }
    490 
    491 /* Called by xdr_array */
    492 static bool_t
    493 xdr_fs_location4(XDR *xdrs, fs_location4 *objp)
    494 {
    495 	if (!xdr_array(xdrs, (char **)&objp->server_val,
    496 	    (uint_t *)&objp->server_len, NFS4_FS_LOCATIONS_LIMIT,
    497 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
    498 		return (FALSE);
    499 	return (xdr_array(xdrs, (char **)&objp->rootpath.pathname4_val,
    500 	    (uint_t *)&objp->rootpath.pathname4_len,
    501 	    NFS4_MAX_PATHNAME4,
    502 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string));
    503 }
    504 
    505 /* Called by xdr_array */
    506 static bool_t
    507 xdr_nfsace4(XDR *xdrs, nfsace4 *objp)
    508 {
    509 	if (xdrs->x_op != XDR_FREE) {
    510 		if (!xdr_u_int(xdrs, &objp->type))
    511 			return (FALSE);
    512 		if (!xdr_u_int(xdrs, &objp->flag))
    513 			return (FALSE);
    514 		if (!xdr_u_int(xdrs, &objp->access_mask))
    515 			return (FALSE);
    516 
    517 		if (xdrs->x_op == XDR_DECODE) {
    518 			objp->who.utf8string_val = NULL;
    519 			objp->who.utf8string_len = 0;
    520 		}
    521 
    522 		return (xdr_bytes(xdrs, (char **)&objp->who.utf8string_val,
    523 		    (uint_t *)&objp->who.utf8string_len,
    524 		    NFS4_MAX_UTF8STRING));
    525 	}
    526 
    527 	/*
    528 	 * Optimized free case
    529 	 */
    530 	if (objp->who.utf8string_val != NULL) {
    531 		kmem_free(objp->who.utf8string_val, objp->who.utf8string_len);
    532 		objp->who.utf8string_val = NULL;
    533 	}
    534 	return (TRUE);
    535 }
    536 
    537 /*
    538  * These functions are called out of nfs4_attr.c
    539  */
    540 bool_t
    541 xdr_fattr4_fsid(XDR *xdrs, fattr4_fsid *objp)
    542 {
    543 	if (xdrs->x_op == XDR_FREE)
    544 		return (TRUE);
    545 
    546 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->major))
    547 		return (FALSE);
    548 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->minor));
    549 }
    550 
    551 
    552 bool_t
    553 xdr_fattr4_acl(XDR *xdrs, fattr4_acl *objp)
    554 {
    555 	return (xdr_array(xdrs, (char **)&objp->fattr4_acl_val,
    556 	    (uint_t *)&objp->fattr4_acl_len, NFS4_ACL_LIMIT,
    557 	    sizeof (nfsace4), (xdrproc_t)xdr_nfsace4));
    558 }
    559 
    560 bool_t
    561 xdr_fattr4_fs_locations(XDR *xdrs, fattr4_fs_locations *objp)
    562 {
    563 	if (!xdr_array(xdrs, (char **)&objp->fs_root.pathname4_val,
    564 	    (uint_t *)&objp->fs_root.pathname4_len,
    565 	    NFS4_MAX_PATHNAME4,
    566 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
    567 		return (FALSE);
    568 	return (xdr_array(xdrs, (char **)&objp->locations_val,
    569 	    (uint_t *)&objp->locations_len, NFS4_FS_LOCATIONS_LIMIT,
    570 	    sizeof (fs_location4), (xdrproc_t)xdr_fs_location4));
    571 }
    572 
    573 bool_t
    574 xdr_fattr4_rawdev(XDR *xdrs, fattr4_rawdev *objp)
    575 {
    576 	if (xdrs->x_op == XDR_FREE)
    577 		return (TRUE);
    578 
    579 	if (!xdr_u_int(xdrs, &objp->specdata1))
    580 		return (FALSE);
    581 	return (xdr_u_int(xdrs, &objp->specdata2));
    582 }
    583 
    584 bool_t
    585 xdr_nfstime4(XDR *xdrs, nfstime4 *objp)
    586 {
    587 	if (xdrs->x_op == XDR_FREE)
    588 		return (TRUE);
    589 
    590 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->seconds))
    591 		return (FALSE);
    592 	return (xdr_u_int(xdrs, &objp->nseconds));
    593 }
    594 
    595 
    596 /*
    597  * structured used for calls into xdr_ga_fattr_res() as a means
    598  * to do an immediate/short-term cache of owner/group strings
    599  * for callers like the readdir processing.  In the case of readdir,
    600  * it is likely that the directory objects will be owned by the same
    601  * owner/group and if so there is no need to call into the uid/gid
    602  * mapping code.  While the uid/gid interfaces have their own cache
    603  * having one here will reduct pathlength further.
    604  */
    605 #define	MAX_OG_NAME 100
    606 typedef struct ug_cache
    607 {
    608 	uid_t	uid;
    609 	gid_t	gid;
    610 	utf8string u_curr, u_last;
    611 	utf8string g_curr, g_last;
    612 	char	u_buf1[MAX_OG_NAME];
    613 	char	u_buf2[MAX_OG_NAME];
    614 	char	g_buf1[MAX_OG_NAME];
    615 	char	g_buf2[MAX_OG_NAME];
    616 } ug_cache_t;
    617 
    618 #define	U_SWAP_CURR_LAST(ug) \
    619 	(ug)->u_last.utf8string_len = (ug)->u_curr.utf8string_len;	\
    620 	if ((ug)->u_last.utf8string_val == (ug)->u_buf1) {		\
    621 		(ug)->u_last.utf8string_val = (ug)->u_buf2;		\
    622 		(ug)->u_curr.utf8string_val = (ug)->u_buf1;		\
    623 	} else {							\
    624 		(ug)->u_last.utf8string_val = (ug)->u_buf1;		\
    625 		(ug)->u_curr.utf8string_val = (ug)->u_buf2;		\
    626 	}
    627 
    628 #define	G_SWAP_CURR_LAST(ug) \
    629 	(ug)->g_last.utf8string_len = (ug)->g_curr.utf8string_len;	\
    630 	if ((ug)->g_last.utf8string_val == (ug)->g_buf1) {		\
    631 		(ug)->g_last.utf8string_val = (ug)->g_buf2;		\
    632 		(ug)->g_curr.utf8string_val = (ug)->g_buf1;		\
    633 	} else {							\
    634 		(ug)->g_last.utf8string_val = (ug)->g_buf1;		\
    635 		(ug)->g_curr.utf8string_val = (ug)->g_buf2;		\
    636 	}
    637 
    638 static ug_cache_t *
    639 alloc_ugcache()
    640 {
    641 	ug_cache_t *pug = kmem_alloc(sizeof (ug_cache_t), KM_SLEEP);
    642 
    643 	pug->uid = pug->gid = 0;
    644 	pug->u_curr.utf8string_len = 0;
    645 	pug->u_last.utf8string_len = 0;
    646 	pug->g_curr.utf8string_len = 0;
    647 	pug->g_last.utf8string_len = 0;
    648 	pug->u_curr.utf8string_val = pug->u_buf1;
    649 	pug->u_last.utf8string_val = pug->u_buf2;
    650 	pug->g_curr.utf8string_val = pug->g_buf1;
    651 	pug->g_last.utf8string_val = pug->g_buf2;
    652 
    653 	return (pug);
    654 }
    655 
    656 static void
    657 xdr_ga_prefill_vattr(struct nfs4_ga_res *garp, struct mntinfo4 *mi)
    658 {
    659 	static vattr_t s_vattr = {
    660 		AT_ALL,		/* va_mask */
    661 		VNON,		/* va_type */
    662 		0777,		/* va_mode */
    663 		UID_NOBODY,	/* va_uid */
    664 		GID_NOBODY,	/* va_gid */
    665 		0,		/* va_fsid */
    666 		0,		/* va_nodeid */
    667 		1,		/* va_nlink */
    668 		0,		/* va_size */
    669 		{0, 0},		/* va_atime */
    670 		{0, 0},		/* va_mtime */
    671 		{0, 0},		/* va_ctime */
    672 		0,		/* va_rdev */
    673 		MAXBSIZE,	/* va_blksize */
    674 		0,		/* va_nblocks */
    675 		0		/* va_seq */
    676 	};
    677 
    678 
    679 	garp->n4g_va = s_vattr;
    680 	garp->n4g_va.va_fsid = mi->mi_vfsp->vfs_dev;
    681 	hrt2ts(gethrtime(), &garp->n4g_va.va_atime);
    682 	garp->n4g_va.va_mtime = garp->n4g_va.va_ctime = garp->n4g_va.va_atime;
    683 }
    684 
    685 static void
    686 xdr_ga_prefill_statvfs(struct nfs4_ga_ext_res *gesp, struct mntinfo4 *mi)
    687 {
    688 	static statvfs64_t s_sb = {
    689 		MAXBSIZE,	/* f_bsize */
    690 		DEV_BSIZE,	/* f_frsize */
    691 		(fsfilcnt64_t)-1, /* f_blocks */
    692 		(fsfilcnt64_t)-1, /* f_bfree */
    693 		(fsfilcnt64_t)-1, /* f_bavail */
    694 		(fsfilcnt64_t)-1, /* f_files */
    695 		(fsfilcnt64_t)-1, /* f_ffree */
    696 		(fsfilcnt64_t)-1, /* f_favail */
    697 		0,		/* f_fsid */
    698 		"\0",		/* f_basetype */
    699 		0,		/* f_flag */
    700 		MAXNAMELEN,	/* f_namemax */
    701 		"\0",		/* f_fstr */
    702 	};
    703 
    704 	gesp->n4g_sb = s_sb;
    705 	gesp->n4g_sb.f_fsid = mi->mi_vfsp->vfs_fsid.val[0];
    706 }
    707 
    708 static bool_t
    709 xdr_ga_fattr_res(XDR *xdrs, struct nfs4_ga_res *garp, bitmap4 resbmap,
    710 		bitmap4 argbmap, struct mntinfo4 *mi, ug_cache_t *pug)
    711 {
    712 	int truefalse;
    713 	struct nfs4_ga_ext_res ges, *gesp;
    714 	vattr_t *vap = &garp->n4g_va;
    715 	vsecattr_t *vsap = &garp->n4g_vsa;
    716 
    717 	ASSERT(xdrs->x_op == XDR_DECODE);
    718 
    719 	if (garp->n4g_ext_res)
    720 		gesp = garp->n4g_ext_res;
    721 	else
    722 		gesp = &ges;
    723 
    724 	vap->va_mask = 0;
    725 
    726 	/* Check to see if the vattr should be pre-filled */
    727 	if (argbmap & NFS4_VATTR_MASK)
    728 		xdr_ga_prefill_vattr(garp, mi);
    729 
    730 	if (argbmap & NFS4_STATFS_ATTR_MASK)
    731 		xdr_ga_prefill_statvfs(gesp, mi);
    732 
    733 	if (resbmap &
    734 	    (FATTR4_SUPPORTED_ATTRS_MASK |
    735 	    FATTR4_TYPE_MASK |
    736 	    FATTR4_FH_EXPIRE_TYPE_MASK |
    737 	    FATTR4_CHANGE_MASK |
    738 	    FATTR4_SIZE_MASK |
    739 	    FATTR4_LINK_SUPPORT_MASK |
    740 	    FATTR4_SYMLINK_SUPPORT_MASK |
    741 	    FATTR4_NAMED_ATTR_MASK)) {
    742 
    743 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
    744 			if (!xdr_bitmap4(xdrs, &gesp->n4g_suppattrs))
    745 				return (FALSE);
    746 		}
    747 		if (resbmap & FATTR4_TYPE_MASK) {
    748 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_type))
    749 				return (FALSE);
    750 
    751 			if (vap->va_type < NF4REG ||
    752 			    vap->va_type > NF4NAMEDATTR)
    753 				vap->va_type = VBAD;
    754 			else
    755 				vap->va_type = nf4_to_vt[vap->va_type];
    756 			if (vap->va_type == VBLK)
    757 				vap->va_blksize = DEV_BSIZE;
    758 
    759 			vap->va_mask |= AT_TYPE;
    760 		}
    761 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
    762 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_fet))
    763 				return (FALSE);
    764 		}
    765 		if (resbmap & FATTR4_CHANGE_MASK) {
    766 			if (!xdr_u_longlong_t(xdrs,
    767 			    (u_longlong_t *)&garp->n4g_change))
    768 				return (FALSE);
    769 			garp->n4g_change_valid = 1;
    770 		}
    771 		if (resbmap & FATTR4_SIZE_MASK) {
    772 			if (!xdr_u_longlong_t(xdrs,
    773 			    (u_longlong_t *)&vap->va_size))
    774 				return (FALSE);
    775 			if (!NFS4_SIZE_OK(vap->va_size)) {
    776 				garp->n4g_attrerr = EFBIG;
    777 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
    778 			} else {
    779 				vap->va_mask |= AT_SIZE;
    780 			}
    781 		}
    782 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
    783 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    784 				return (FALSE);
    785 			gesp->n4g_pc4.pc4_link_support =
    786 			    (truefalse ? TRUE : FALSE);
    787 		}
    788 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
    789 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    790 				return (FALSE);
    791 			gesp->n4g_pc4.pc4_symlink_support =
    792 			    (truefalse ? TRUE : FALSE);
    793 		}
    794 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
    795 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    796 				return (FALSE);
    797 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
    798 			gesp->n4g_pc4.pc4_xattr_exists =
    799 			    (truefalse ? TRUE : FALSE);
    800 		}
    801 	}
    802 	if (resbmap &
    803 	    (FATTR4_FSID_MASK |
    804 	    FATTR4_UNIQUE_HANDLES_MASK |
    805 	    FATTR4_LEASE_TIME_MASK |
    806 	    FATTR4_RDATTR_ERROR_MASK)) {
    807 
    808 		if (resbmap & FATTR4_FSID_MASK) {
    809 			if ((!xdr_u_longlong_t(xdrs,
    810 			    (u_longlong_t *)&garp->n4g_fsid.major)) ||
    811 			    (!xdr_u_longlong_t(xdrs,
    812 			    (u_longlong_t *)&garp->n4g_fsid.minor)))
    813 				return (FALSE);
    814 			garp->n4g_fsid_valid = 1;
    815 		}
    816 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
    817 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    818 				return (FALSE);
    819 			gesp->n4g_pc4.pc4_unique_handles =
    820 			    (truefalse ? TRUE : FALSE);
    821 		}
    822 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
    823 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_leasetime))
    824 				return (FALSE);
    825 		}
    826 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
    827 			if (!XDR_GETINT32(xdrs,
    828 			    (int *)&gesp->n4g_rdattr_error))
    829 				return (FALSE);
    830 		}
    831 	}
    832 	if (resbmap &
    833 	    (FATTR4_ACL_MASK |
    834 	    FATTR4_ACLSUPPORT_MASK |
    835 	    FATTR4_ARCHIVE_MASK |
    836 	    FATTR4_CANSETTIME_MASK)) {
    837 
    838 		if (resbmap & FATTR4_ACL_MASK) {
    839 			fattr4_acl	acl;
    840 
    841 			acl.fattr4_acl_val = NULL;
    842 			acl.fattr4_acl_len = 0;
    843 
    844 			if (!xdr_fattr4_acl(xdrs, &acl))
    845 				return (FALSE);
    846 
    847 			vsap->vsa_aclcnt = acl.fattr4_acl_len;
    848 			vsap->vsa_aclentp = acl.fattr4_acl_val;
    849 			vsap->vsa_mask = VSA_ACE | VSA_ACECNT;
    850 			vsap->vsa_aclentsz = vsap->vsa_aclcnt * sizeof (ace_t);
    851 
    852 		}
    853 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
    854 			if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_aclsupport))
    855 				return (FALSE);
    856 		}
    857 		if (resbmap & FATTR4_ARCHIVE_MASK) {
    858 			ASSERT(0);
    859 		}
    860 		if (resbmap & FATTR4_CANSETTIME_MASK) {
    861 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    862 				return (FALSE);
    863 			gesp->n4g_pc4.pc4_cansettime =
    864 			    (truefalse ? TRUE : FALSE);
    865 		}
    866 	}
    867 	if (resbmap &
    868 	    (FATTR4_CASE_INSENSITIVE_MASK |
    869 	    FATTR4_CASE_PRESERVING_MASK |
    870 	    FATTR4_CHOWN_RESTRICTED_MASK |
    871 	    FATTR4_FILEHANDLE_MASK |
    872 	    FATTR4_FILEID_MASK |
    873 	    FATTR4_FILES_AVAIL_MASK |
    874 	    FATTR4_FILES_FREE_MASK |
    875 	    FATTR4_FILES_TOTAL_MASK)) {
    876 
    877 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
    878 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    879 				return (FALSE);
    880 			gesp->n4g_pc4.pc4_case_insensitive =
    881 			    (truefalse ? TRUE : FALSE);
    882 		}
    883 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
    884 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    885 				return (FALSE);
    886 			gesp->n4g_pc4.pc4_case_preserving =
    887 			    (truefalse ? TRUE : FALSE);
    888 		}
    889 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
    890 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    891 				return (FALSE);
    892 			gesp->n4g_pc4.pc4_chown_restricted =
    893 			    (truefalse ? TRUE : FALSE);
    894 		}
    895 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
    896 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
    897 			gesp->n4g_fh_u.nfs_fh4_alt.val =
    898 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
    899 			if (!xdr_bytes(xdrs,
    900 			    (char **)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_val,
    901 			    (uint_t *)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_len,
    902 			    NFS4_FHSIZE))
    903 				return (FALSE);
    904 		}
    905 		if (resbmap & FATTR4_FILEID_MASK) {
    906 			if (!xdr_u_longlong_t(xdrs,
    907 			    (u_longlong_t *)&vap->va_nodeid))
    908 				return (FALSE);
    909 			vap->va_mask |= AT_NODEID;
    910 		}
    911 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
    912 			if (!xdr_u_longlong_t(xdrs,
    913 			    (u_longlong_t *)&gesp->n4g_sb.f_favail))
    914 				return (FALSE);
    915 		}
    916 		if (resbmap & FATTR4_FILES_FREE_MASK) {
    917 			if (!xdr_u_longlong_t(xdrs,
    918 			    (u_longlong_t *)&gesp->n4g_sb.f_ffree))
    919 				return (FALSE);
    920 		}
    921 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
    922 			if (!xdr_u_longlong_t(xdrs,
    923 			    (u_longlong_t *)&gesp->n4g_sb.f_files))
    924 				return (FALSE);
    925 		}
    926 	}
    927 	if (resbmap &
    928 	    (FATTR4_FS_LOCATIONS_MASK |
    929 	    FATTR4_HIDDEN_MASK |
    930 	    FATTR4_HOMOGENEOUS_MASK)) {
    931 
    932 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
    933 			ASSERT(0);
    934 		}
    935 		if (resbmap & FATTR4_HIDDEN_MASK) {
    936 			ASSERT(0);
    937 		}
    938 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
    939 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    940 				return (FALSE);
    941 			gesp->n4g_pc4.pc4_homogeneous =
    942 			    (truefalse ? TRUE : FALSE);
    943 		}
    944 	}
    945 	if (resbmap &
    946 	    (FATTR4_MAXFILESIZE_MASK |
    947 	    FATTR4_MAXLINK_MASK |
    948 	    FATTR4_MAXNAME_MASK |
    949 	    FATTR4_MAXREAD_MASK |
    950 	    FATTR4_MAXWRITE_MASK)) {
    951 
    952 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
    953 			if (!xdr_u_longlong_t(xdrs,
    954 			    (u_longlong_t *)&gesp->n4g_maxfilesize))
    955 				return (FALSE);
    956 		}
    957 		if (resbmap & FATTR4_MAXLINK_MASK) {
    958 			if (!XDR_GETINT32(xdrs,
    959 			    (int *)&gesp->n4g_pc4.pc4_link_max))
    960 				return (FALSE);
    961 		}
    962 		if (resbmap & FATTR4_MAXNAME_MASK) {
    963 			if (!XDR_GETINT32(xdrs,
    964 			    (int *)&gesp->n4g_pc4.pc4_name_max))
    965 				return (FALSE);
    966 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
    967 		}
    968 		if (resbmap & FATTR4_MAXREAD_MASK) {
    969 			if (!xdr_u_longlong_t(xdrs,
    970 			    (u_longlong_t *)&gesp->n4g_maxread))
    971 				return (FALSE);
    972 		}
    973 		if (resbmap & FATTR4_MAXWRITE_MASK) {
    974 			if (!xdr_u_longlong_t(xdrs,
    975 			    (u_longlong_t *)&gesp->n4g_maxwrite))
    976 				return (FALSE);
    977 		}
    978 	}
    979 	if (resbmap &
    980 	    (FATTR4_MIMETYPE_MASK |
    981 	    FATTR4_MODE_MASK |
    982 	    FATTR4_NO_TRUNC_MASK |
    983 	    FATTR4_NUMLINKS_MASK)) {
    984 
    985 		if (resbmap & FATTR4_MIMETYPE_MASK) {
    986 			ASSERT(0);
    987 		}
    988 		if (resbmap & FATTR4_MODE_MASK) {
    989 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_mode))
    990 				return (FALSE);
    991 			vap->va_mask |= AT_MODE;
    992 		}
    993 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
    994 			if (!XDR_GETINT32(xdrs, (int *)&truefalse))
    995 				return (FALSE);
    996 			gesp->n4g_pc4.pc4_no_trunc =
    997 			    (truefalse ? TRUE : FALSE);
    998 		}
    999 		if (resbmap & FATTR4_NUMLINKS_MASK) {
   1000 			if (!XDR_GETINT32(xdrs, (int *)&vap->va_nlink))
   1001 				return (FALSE);
   1002 			vap->va_mask |= AT_NLINK;
   1003 		}
   1004 	}
   1005 	if (resbmap &
   1006 	    (FATTR4_OWNER_MASK |
   1007 	    FATTR4_OWNER_GROUP_MASK |
   1008 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
   1009 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
   1010 
   1011 		if (resbmap & FATTR4_OWNER_MASK) {
   1012 			uint_t *owner_length, ol;
   1013 			char *owner_val = NULL;
   1014 			char *owner_alloc = NULL;
   1015 			utf8string ov;
   1016 			int error;
   1017 
   1018 			/* get the OWNER_LENGTH */
   1019 			if (!xdr_u_int(xdrs, &ol))
   1020 				return (FALSE);
   1021 
   1022 			/* Manage the owner length location */
   1023 			if (pug && ol <= MAX_OG_NAME) {
   1024 				owner_length = &pug->u_curr.utf8string_len;
   1025 				*owner_length = ol;
   1026 			} else {
   1027 				owner_length = &ol;
   1028 			}
   1029 
   1030 			/* find memory to store the decode */
   1031 			if (*owner_length > MAX_OG_NAME || pug == NULL)
   1032 				owner_val = owner_alloc =
   1033 				    kmem_alloc(*owner_length, KM_SLEEP);
   1034 			else
   1035 				owner_val = pug->u_curr.utf8string_val;
   1036 
   1037 			/* get the OWNER string */
   1038 			if (!xdr_opaque(xdrs, owner_val, *owner_length)) {
   1039 				if (owner_alloc)
   1040 					kmem_free(owner_alloc, *owner_length);
   1041 				return (FALSE);
   1042 			}
   1043 
   1044 			/* Optimize for matching if called for */
   1045 			if (pug &&
   1046 			    *owner_length == pug->u_last.utf8string_len &&
   1047 			    bcmp(owner_val, pug->u_last.utf8string_val,
   1048 			    *owner_length) == 0) {
   1049 				vap->va_uid = pug->uid;
   1050 				vap->va_mask |= AT_UID;
   1051 			} else {
   1052 				uid_t uid;
   1053 
   1054 				ov.utf8string_len = *owner_length;
   1055 				ov.utf8string_val = owner_val;
   1056 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
   1057 				/*
   1058 				 * String was mapped, but to nobody because
   1059 				 * we are nfsmapid, indicate it should not
   1060 				 * be cached.
   1061 				 */
   1062 				if (error == ENOTSUP) {
   1063 					error = 0;
   1064 					garp->n4g_attrwhy =
   1065 					    NFS4_GETATTR_NOCACHE_OK;
   1066 				}
   1067 
   1068 				if (error) {
   1069 					garp->n4g_attrerr = error;
   1070 					garp->n4g_attrwhy =
   1071 					    NFS4_GETATTR_ATUID_ERR;
   1072 				} else {
   1073 					vap->va_uid = uid;
   1074 					vap->va_mask |= AT_UID;
   1075 					if (pug && ol <= MAX_OG_NAME) {
   1076 						pug->uid = uid;
   1077 						U_SWAP_CURR_LAST(pug);
   1078 					}
   1079 				}
   1080 				if (owner_alloc)
   1081 					kmem_free(owner_alloc, *owner_length);
   1082 			}
   1083 		}
   1084 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
   1085 			uint_t *group_length, gl;
   1086 			char *group_val = NULL;
   1087 			char *group_alloc = NULL;
   1088 			utf8string gv;
   1089 			int error;
   1090 
   1091 			/* get the OWNER_GROUP_LENGTH */
   1092 			if (!xdr_u_int(xdrs, &gl))
   1093 				return (FALSE);
   1094 
   1095 			/* Manage the group length location */
   1096 			if (pug && gl <= MAX_OG_NAME) {
   1097 				group_length = &pug->g_curr.utf8string_len;
   1098 				*group_length = gl;
   1099 			} else {
   1100 				group_length = &gl;
   1101 			}
   1102 
   1103 			/* find memory to store the decode */
   1104 			if (*group_length > MAX_OG_NAME || pug == NULL)
   1105 				group_val = group_alloc =
   1106 				    kmem_alloc(*group_length, KM_SLEEP);
   1107 			else
   1108 				group_val = pug->g_curr.utf8string_val;
   1109 
   1110 			/* get the OWNER_GROUP string */
   1111 			if (!xdr_opaque(xdrs, group_val, *group_length)) {
   1112 				if (group_alloc)
   1113 					kmem_free(group_alloc, *group_length);
   1114 				return (FALSE);
   1115 			}
   1116 
   1117 			/* Optimize for matching if called for */
   1118 			if (pug &&
   1119 			    *group_length == pug->g_last.utf8string_len &&
   1120 			    bcmp(group_val, pug->g_last.utf8string_val,
   1121 			    *group_length) == 0) {
   1122 				vap->va_gid = pug->gid;
   1123 				vap->va_mask |= AT_GID;
   1124 			} else {
   1125 				uid_t gid;
   1126 
   1127 				gv.utf8string_len = *group_length;
   1128 				gv.utf8string_val = group_val;
   1129 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
   1130 				/*
   1131 				 * String was mapped, but to nobody because
   1132 				 * we are nfsmapid, indicate it should not
   1133 				 * be cached.
   1134 				 */
   1135 				if (error == ENOTSUP) {
   1136 					error = 0;
   1137 					garp->n4g_attrwhy =
   1138 					    NFS4_GETATTR_NOCACHE_OK;
   1139 				}
   1140 
   1141 				if (error) {
   1142 					garp->n4g_attrerr = error;
   1143 					garp->n4g_attrwhy =
   1144 					    NFS4_GETATTR_ATGID_ERR;
   1145 				} else {
   1146 					vap->va_gid = gid;
   1147 					vap->va_mask |= AT_GID;
   1148 					if (pug && gl <= MAX_OG_NAME) {
   1149 						pug->gid = gid;
   1150 						G_SWAP_CURR_LAST(pug);
   1151 					}
   1152 				}
   1153 				if (group_alloc) {
   1154 					kmem_free(group_alloc, *group_length);
   1155 				}
   1156 			}
   1157 		}
   1158 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
   1159 			ASSERT(0);
   1160 		}
   1161 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
   1162 			ASSERT(0);
   1163 		}
   1164 	}
   1165 	if (resbmap &
   1166 	    (FATTR4_QUOTA_USED_MASK |
   1167 	    FATTR4_SPACE_AVAIL_MASK |
   1168 	    FATTR4_SPACE_FREE_MASK |
   1169 	    FATTR4_SPACE_TOTAL_MASK |
   1170 	    FATTR4_SPACE_USED_MASK |
   1171 	    FATTR4_SYSTEM_MASK)) {
   1172 
   1173 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
   1174 			ASSERT(0);
   1175 		}
   1176 		if (resbmap & FATTR4_RAWDEV_MASK) {
   1177 			fattr4_rawdev rawdev;
   1178 			if (!xdr_fattr4_rawdev(xdrs, &rawdev))
   1179 				return (FALSE);
   1180 
   1181 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
   1182 				vap->va_rdev = makedevice(rawdev.specdata1,
   1183 				    rawdev.specdata2);
   1184 			} else {
   1185 				vap->va_rdev = 0;
   1186 			}
   1187 			vap->va_mask |= AT_RDEV;
   1188 		}
   1189 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
   1190 			if (!xdr_u_longlong_t(xdrs,
   1191 			    (u_longlong_t *)&gesp->n4g_sb.f_bavail))
   1192 				return (FALSE);
   1193 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
   1194 		}
   1195 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
   1196 			if (!xdr_u_longlong_t(xdrs,
   1197 			    (u_longlong_t *)&gesp->n4g_sb.f_bfree))
   1198 				return (FALSE);
   1199 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
   1200 		}
   1201 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
   1202 			if (!xdr_u_longlong_t(xdrs,
   1203 			    (u_longlong_t *)&gesp->n4g_sb.f_blocks))
   1204 				return (FALSE);
   1205 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
   1206 		}
   1207 		if (resbmap & FATTR4_SPACE_USED_MASK) {
   1208 			uint64_t space_used;
   1209 			if (!xdr_u_longlong_t(xdrs,
   1210 			    (u_longlong_t *)&space_used))
   1211 				return (FALSE);
   1212 
   1213 			/* Compute space depending on device type */
   1214 			ASSERT((vap->va_mask & AT_TYPE));
   1215 			if (vap->va_type == VREG || vap->va_type == VDIR ||
   1216 			    vap->va_type == VLNK) {
   1217 				vap->va_nblocks = (u_longlong_t)
   1218 				    ((space_used + (offset4)DEV_BSIZE -
   1219 				    (offset4)1) / (offset4)DEV_BSIZE);
   1220 			} else {
   1221 				vap->va_nblocks = 0;
   1222 			}
   1223 			vap->va_mask |= AT_NBLOCKS;
   1224 		}
   1225 		if (resbmap & FATTR4_SYSTEM_MASK) {
   1226 			ASSERT(0);
   1227 		}
   1228 	}
   1229 	if (resbmap &
   1230 	    (FATTR4_TIME_ACCESS_MASK |
   1231 	    FATTR4_TIME_ACCESS_SET_MASK |
   1232 	    FATTR4_TIME_BACKUP_MASK |
   1233 	    FATTR4_TIME_CREATE_MASK |
   1234 	    FATTR4_TIME_DELTA_MASK |
   1235 	    FATTR4_TIME_METADATA_MASK |
   1236 	    FATTR4_TIME_MODIFY_MASK |
   1237 	    FATTR4_TIME_MODIFY_SET_MASK |
   1238 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
   1239 
   1240 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
   1241 			nfstime4 atime;
   1242 			int error;
   1243 
   1244 			if (!xdr_longlong_t(xdrs,
   1245 			    (longlong_t *)&atime.seconds))
   1246 				return (FALSE);
   1247 			if (!XDR_GETINT32(xdrs, (int *)&atime.nseconds))
   1248 				return (FALSE);
   1249 			error = nfs4_time_ntov(&atime, &vap->va_atime);
   1250 			if (error) {
   1251 				garp->n4g_attrerr = error;
   1252 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
   1253 			}
   1254 			vap->va_mask |= AT_ATIME;
   1255 		}
   1256 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
   1257 			ASSERT(0);
   1258 		}
   1259 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
   1260 			ASSERT(0);
   1261 		}
   1262 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
   1263 			ASSERT(0);
   1264 		}
   1265 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
   1266 			if ((!xdr_u_longlong_t(xdrs,
   1267 			    (u_longlong_t *)&gesp->n4g_delta.seconds)) ||
   1268 			    (!xdr_u_int(xdrs, &gesp->n4g_delta.nseconds)))
   1269 				return (FALSE);
   1270 		}
   1271 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
   1272 			nfstime4 mdt;
   1273 			int error;
   1274 
   1275 			if (!xdr_longlong_t(xdrs, (longlong_t *)&mdt.seconds))
   1276 				return (FALSE);
   1277 			if (!XDR_GETINT32(xdrs, (int32_t *)&mdt.nseconds))
   1278 				return (FALSE);
   1279 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
   1280 			if (error) {
   1281 				garp->n4g_attrerr = error;
   1282 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
   1283 			}
   1284 			vap->va_mask |= AT_CTIME;
   1285 		}
   1286 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
   1287 			nfstime4 mtime;
   1288 			int error;
   1289 
   1290 			if (!xdr_longlong_t(xdrs,
   1291 			    (longlong_t *)&mtime.seconds))
   1292 				return (FALSE);
   1293 			if (!XDR_GETINT32(xdrs, (int32_t *)&mtime.nseconds))
   1294 				return (FALSE);
   1295 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
   1296 			if (error) {
   1297 				garp->n4g_attrerr = error;
   1298 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
   1299 			}
   1300 			vap->va_mask |= AT_MTIME;
   1301 		}
   1302 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
   1303 			ASSERT(0);
   1304 		}
   1305 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
   1306 			if (!xdr_u_longlong_t(xdrs,
   1307 			    (u_longlong_t *)&garp->n4g_mon_fid))
   1308 				return (FALSE);
   1309 			garp->n4g_mon_fid_valid = 1;
   1310 		}
   1311 	}
   1312 
   1313 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
   1314 		/* copy only if not provided */
   1315 		if (garp->n4g_ext_res == NULL) {
   1316 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
   1317 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
   1318 		}
   1319 	}
   1320 
   1321 	return (TRUE);
   1322 }
   1323 
   1324 /*
   1325  * Inlined version of get_bitmap4 processing
   1326  */
   1327 bitmap4
   1328 xdr_get_bitmap4_inline(uint32_t **iptr)
   1329 {
   1330 	uint32_t resbmaplen;
   1331 	bitmap4 bm;
   1332 	uint32_t *ptr = *iptr;
   1333 
   1334 	/* bitmap LENGTH */
   1335 	resbmaplen = IXDR_GET_U_INT32(ptr);
   1336 
   1337 	/* Inline the bitmap and attrlen for common case of two word map */
   1338 	if (resbmaplen == 2) {
   1339 		IXDR_GET_HYPER(ptr, bm);
   1340 		*iptr = ptr;
   1341 		return (bm);
   1342 	}
   1343 
   1344 #if defined(_LITTLE_ENDIAN)
   1345 	bm = IXDR_GET_U_INT32(ptr);
   1346 	if (--resbmaplen == 0) {
   1347 		*iptr = ptr;
   1348 		return (bm);
   1349 	}
   1350 	*((uint32_t *)&bm) |= IXDR_GET_U_INT32(ptr);
   1351 	if (--resbmaplen == 0) {
   1352 		*iptr = ptr;
   1353 		return (bm);
   1354 	}
   1355 	ptr += resbmaplen;
   1356 	*iptr = ptr;
   1357 	return (bm);
   1358 #elif defined(_BIG_ENDIAN)
   1359 	*((uint32_t *)&bm) = IXDR_GET_U_INT32(ptr);
   1360 	if (--resbmaplen == 0) {
   1361 		*iptr = ptr;
   1362 		return (bm);
   1363 	}
   1364 	bm |= IXDR_GET_U_INT32(ptr);
   1365 	if (--resbmaplen == 0) {
   1366 		*iptr = ptr;
   1367 		return (bm);
   1368 	}
   1369 	ptr += resbmaplen;
   1370 	*iptr = ptr;
   1371 	return (bm);
   1372 #else
   1373 	ASSERT(0);
   1374 	ptr += resbmaplen;
   1375 	*iptr = ptr;
   1376 	return (0);
   1377 #endif
   1378 }
   1379 
   1380 static bool_t
   1381 xdr_ga_fattr_res_inline(uint32_t *ptr, struct nfs4_ga_res *garp,
   1382 			bitmap4 resbmap, bitmap4 argbmap, struct mntinfo4 *mi,
   1383 			ug_cache_t *pug)
   1384 {
   1385 	int truefalse;
   1386 	struct nfs4_ga_ext_res ges, *gesp;
   1387 	vattr_t *vap = &garp->n4g_va;
   1388 
   1389 	if (garp->n4g_ext_res)
   1390 		gesp = garp->n4g_ext_res;
   1391 	else
   1392 		gesp = &ges;
   1393 
   1394 	vap->va_mask = 0;
   1395 
   1396 	/* Check to see if the vattr should be pre-filled */
   1397 	if (argbmap & NFS4_VATTR_MASK)
   1398 		xdr_ga_prefill_vattr(garp, mi);
   1399 
   1400 	if (argbmap & NFS4_STATFS_ATTR_MASK)
   1401 		xdr_ga_prefill_statvfs(gesp, mi);
   1402 
   1403 	if (resbmap &
   1404 	    (FATTR4_SUPPORTED_ATTRS_MASK |
   1405 	    FATTR4_TYPE_MASK |
   1406 	    FATTR4_FH_EXPIRE_TYPE_MASK |
   1407 	    FATTR4_CHANGE_MASK |
   1408 	    FATTR4_SIZE_MASK |
   1409 	    FATTR4_LINK_SUPPORT_MASK |
   1410 	    FATTR4_SYMLINK_SUPPORT_MASK |
   1411 	    FATTR4_NAMED_ATTR_MASK)) {
   1412 
   1413 		if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) {
   1414 			gesp->n4g_suppattrs = xdr_get_bitmap4_inline(&ptr);
   1415 		}
   1416 		if (resbmap & FATTR4_TYPE_MASK) {
   1417 			vap->va_type = IXDR_GET_U_INT32(ptr);
   1418 
   1419 			if (vap->va_type < NF4REG ||
   1420 			    vap->va_type > NF4NAMEDATTR)
   1421 				vap->va_type = VBAD;
   1422 			else
   1423 				vap->va_type = nf4_to_vt[vap->va_type];
   1424 			if (vap->va_type == VBLK)
   1425 				vap->va_blksize = DEV_BSIZE;
   1426 
   1427 			vap->va_mask |= AT_TYPE;
   1428 		}
   1429 		if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) {
   1430 			gesp->n4g_fet = IXDR_GET_U_INT32(ptr);
   1431 		}
   1432 		if (resbmap & FATTR4_CHANGE_MASK) {
   1433 			IXDR_GET_U_HYPER(ptr, garp->n4g_change);
   1434 			garp->n4g_change_valid = 1;
   1435 		}
   1436 		if (resbmap & FATTR4_SIZE_MASK) {
   1437 			IXDR_GET_U_HYPER(ptr, vap->va_size);
   1438 
   1439 			if (!NFS4_SIZE_OK(vap->va_size)) {
   1440 				garp->n4g_attrerr = EFBIG;
   1441 				garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR;
   1442 			} else {
   1443 				vap->va_mask |= AT_SIZE;
   1444 			}
   1445 		}
   1446 		if (resbmap & FATTR4_LINK_SUPPORT_MASK) {
   1447 			truefalse = IXDR_GET_U_INT32(ptr);
   1448 			gesp->n4g_pc4.pc4_link_support =
   1449 			    (truefalse ? TRUE : FALSE);
   1450 		}
   1451 		if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) {
   1452 			truefalse = IXDR_GET_U_INT32(ptr);
   1453 			gesp->n4g_pc4.pc4_symlink_support =
   1454 			    (truefalse ? TRUE : FALSE);
   1455 		}
   1456 		if (resbmap & FATTR4_NAMED_ATTR_MASK) {
   1457 			truefalse = IXDR_GET_U_INT32(ptr);
   1458 			gesp->n4g_pc4.pc4_xattr_exists = TRUE;
   1459 			gesp->n4g_pc4.pc4_xattr_exists =
   1460 			    (truefalse ? TRUE : FALSE);
   1461 		}
   1462 	}
   1463 	if (resbmap &
   1464 	    (FATTR4_FSID_MASK |
   1465 	    FATTR4_UNIQUE_HANDLES_MASK |
   1466 	    FATTR4_LEASE_TIME_MASK |
   1467 	    FATTR4_RDATTR_ERROR_MASK)) {
   1468 
   1469 		if (resbmap & FATTR4_FSID_MASK) {
   1470 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.major);
   1471 			IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.minor);
   1472 			garp->n4g_fsid_valid = 1;
   1473 		}
   1474 		if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) {
   1475 			truefalse = IXDR_GET_U_INT32(ptr);
   1476 			gesp->n4g_pc4.pc4_unique_handles =
   1477 			    (truefalse ? TRUE : FALSE);
   1478 		}
   1479 		if (resbmap & FATTR4_LEASE_TIME_MASK) {
   1480 			gesp->n4g_leasetime = IXDR_GET_U_INT32(ptr);
   1481 		}
   1482 		if (resbmap & FATTR4_RDATTR_ERROR_MASK) {
   1483 			gesp->n4g_rdattr_error = IXDR_GET_U_INT32(ptr);
   1484 		}
   1485 	}
   1486 	if (resbmap &
   1487 	    (FATTR4_ACL_MASK |
   1488 	    FATTR4_ACLSUPPORT_MASK |
   1489 	    FATTR4_ARCHIVE_MASK |
   1490 	    FATTR4_CANSETTIME_MASK)) {
   1491 
   1492 		if (resbmap & FATTR4_ACL_MASK) {
   1493 			ASSERT(0);
   1494 		}
   1495 		if (resbmap & FATTR4_ACLSUPPORT_MASK) {
   1496 			gesp->n4g_aclsupport = IXDR_GET_U_INT32(ptr);
   1497 		}
   1498 		if (resbmap & FATTR4_ARCHIVE_MASK) {
   1499 			ASSERT(0);
   1500 		}
   1501 		if (resbmap & FATTR4_CANSETTIME_MASK) {
   1502 			truefalse = IXDR_GET_U_INT32(ptr);
   1503 			gesp->n4g_pc4.pc4_cansettime =
   1504 			    (truefalse ? TRUE : FALSE);
   1505 		}
   1506 	}
   1507 	if (resbmap &
   1508 	    (FATTR4_CASE_INSENSITIVE_MASK |
   1509 	    FATTR4_CASE_PRESERVING_MASK |
   1510 	    FATTR4_CHOWN_RESTRICTED_MASK |
   1511 	    FATTR4_FILEHANDLE_MASK |
   1512 	    FATTR4_FILEID_MASK |
   1513 	    FATTR4_FILES_AVAIL_MASK |
   1514 	    FATTR4_FILES_FREE_MASK |
   1515 	    FATTR4_FILES_TOTAL_MASK)) {
   1516 
   1517 		if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) {
   1518 			truefalse = IXDR_GET_U_INT32(ptr);
   1519 			gesp->n4g_pc4.pc4_case_insensitive =
   1520 			    (truefalse ? TRUE : FALSE);
   1521 		}
   1522 		if (resbmap & FATTR4_CASE_PRESERVING_MASK) {
   1523 			truefalse = IXDR_GET_U_INT32(ptr);
   1524 			gesp->n4g_pc4.pc4_case_preserving =
   1525 			    (truefalse ? TRUE : FALSE);
   1526 		}
   1527 		if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) {
   1528 			truefalse = IXDR_GET_U_INT32(ptr);
   1529 			gesp->n4g_pc4.pc4_chown_restricted =
   1530 			    (truefalse ? TRUE : FALSE);
   1531 		}
   1532 		if (resbmap & FATTR4_FILEHANDLE_MASK) {
   1533 			int len = IXDR_GET_U_INT32(ptr);
   1534 
   1535 			gesp->n4g_fh_u.nfs_fh4_alt.len = 0;
   1536 			gesp->n4g_fh_u.nfs_fh4_alt.val =
   1537 			    gesp->n4g_fh_u.nfs_fh4_alt.data;
   1538 			gesp->n4g_fh_u.n4g_fh.nfs_fh4_len = len;
   1539 
   1540 			bcopy(ptr, gesp->n4g_fh_u.n4g_fh.nfs_fh4_val, len);
   1541 
   1542 			ptr += RNDUP(len) / BYTES_PER_XDR_UNIT;
   1543 		}
   1544 		if (resbmap & FATTR4_FILEID_MASK) {
   1545 			IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
   1546 			vap->va_mask |= AT_NODEID;
   1547 		}
   1548 		if (resbmap & FATTR4_FILES_AVAIL_MASK) {
   1549 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_favail);
   1550 		}
   1551 		if (resbmap & FATTR4_FILES_FREE_MASK) {
   1552 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_ffree);
   1553 		}
   1554 		if (resbmap & FATTR4_FILES_TOTAL_MASK) {
   1555 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_files);
   1556 		}
   1557 	}
   1558 	if (resbmap &
   1559 	    (FATTR4_FS_LOCATIONS_MASK |
   1560 	    FATTR4_HIDDEN_MASK |
   1561 	    FATTR4_HOMOGENEOUS_MASK)) {
   1562 
   1563 		if (resbmap & FATTR4_FS_LOCATIONS_MASK) {
   1564 			ASSERT(0);
   1565 		}
   1566 		if (resbmap & FATTR4_HIDDEN_MASK) {
   1567 			ASSERT(0);
   1568 		}
   1569 		if (resbmap & FATTR4_HOMOGENEOUS_MASK) {
   1570 			truefalse = IXDR_GET_U_INT32(ptr);
   1571 			gesp->n4g_pc4.pc4_homogeneous =
   1572 			    (truefalse ? TRUE : FALSE);
   1573 		}
   1574 	}
   1575 	if (resbmap &
   1576 	    (FATTR4_MAXFILESIZE_MASK |
   1577 	    FATTR4_MAXLINK_MASK |
   1578 	    FATTR4_MAXNAME_MASK |
   1579 	    FATTR4_MAXREAD_MASK |
   1580 	    FATTR4_MAXWRITE_MASK)) {
   1581 
   1582 		if (resbmap & FATTR4_MAXFILESIZE_MASK) {
   1583 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxfilesize);
   1584 		}
   1585 		if (resbmap & FATTR4_MAXLINK_MASK) {
   1586 			gesp->n4g_pc4.pc4_link_max = IXDR_GET_U_INT32(ptr);
   1587 		}
   1588 		if (resbmap & FATTR4_MAXNAME_MASK) {
   1589 			gesp->n4g_pc4.pc4_name_max = IXDR_GET_U_INT32(ptr);
   1590 			gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max;
   1591 		}
   1592 		if (resbmap & FATTR4_MAXREAD_MASK) {
   1593 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxread);
   1594 		}
   1595 		if (resbmap & FATTR4_MAXWRITE_MASK) {
   1596 			IXDR_GET_U_HYPER(ptr, gesp->n4g_maxwrite);
   1597 		}
   1598 	}
   1599 	if (resbmap &
   1600 	    (FATTR4_MIMETYPE_MASK |
   1601 	    FATTR4_MODE_MASK |
   1602 	    FATTR4_NO_TRUNC_MASK |
   1603 	    FATTR4_NUMLINKS_MASK)) {
   1604 
   1605 		if (resbmap & FATTR4_MIMETYPE_MASK) {
   1606 			ASSERT(0);
   1607 		}
   1608 		if (resbmap & FATTR4_MODE_MASK) {
   1609 			vap->va_mode = IXDR_GET_U_INT32(ptr);
   1610 			vap->va_mask |= AT_MODE;
   1611 		}
   1612 		if (resbmap & FATTR4_NO_TRUNC_MASK) {
   1613 			truefalse = IXDR_GET_U_INT32(ptr);
   1614 			gesp->n4g_pc4.pc4_no_trunc =
   1615 			    (truefalse ? TRUE : FALSE);
   1616 		}
   1617 		if (resbmap & FATTR4_NUMLINKS_MASK) {
   1618 			vap->va_nlink = IXDR_GET_U_INT32(ptr);
   1619 			vap->va_mask |= AT_NLINK;
   1620 		}
   1621 	}
   1622 	if (resbmap &
   1623 	    (FATTR4_OWNER_MASK |
   1624 	    FATTR4_OWNER_GROUP_MASK |
   1625 	    FATTR4_QUOTA_AVAIL_HARD_MASK |
   1626 	    FATTR4_QUOTA_AVAIL_SOFT_MASK)) {
   1627 
   1628 		if (resbmap & FATTR4_OWNER_MASK) {
   1629 			uint_t *owner_length, ol;
   1630 			char *owner_val = NULL;
   1631 			utf8string ov;
   1632 			int error;
   1633 
   1634 			/* get the OWNER_LENGTH */
   1635 			ol = IXDR_GET_U_INT32(ptr);
   1636 
   1637 			/* Manage the owner length location */
   1638 			if (pug && ol <= MAX_OG_NAME) {
   1639 				owner_length = &pug->u_curr.utf8string_len;
   1640 				*owner_length = ol;
   1641 			} else {
   1642 				owner_length = &ol;
   1643 			}
   1644 
   1645 			/* find memory to store the decode */
   1646 			if (*owner_length > MAX_OG_NAME || pug == NULL)
   1647 				owner_val = (char *)ptr;
   1648 			else
   1649 				owner_val = (char *)ptr;
   1650 
   1651 			/* Optimize for matching if called for */
   1652 			if (pug &&
   1653 			    *owner_length == pug->u_last.utf8string_len &&
   1654 			    bcmp(owner_val, pug->u_last.utf8string_val,
   1655 			    *owner_length) == 0) {
   1656 				vap->va_uid = pug->uid;
   1657 				vap->va_mask |= AT_UID;
   1658 			} else {
   1659 				uid_t uid;
   1660 
   1661 				ov.utf8string_len = *owner_length;
   1662 				ov.utf8string_val = owner_val;
   1663 				error = nfs_idmap_str_uid(&ov, &uid, FALSE);
   1664 				/*
   1665 				 * String was mapped, but to nobody because
   1666 				 * we are nfsmapid, indicate it should not
   1667 				 * be cached.
   1668 				 */
   1669 				if (error == ENOTSUP) {
   1670 					error = 0;
   1671 					garp->n4g_attrwhy =
   1672 					    NFS4_GETATTR_NOCACHE_OK;
   1673 				}
   1674 
   1675 				if (error) {
   1676 					garp->n4g_attrerr = error;
   1677 					garp->n4g_attrwhy =
   1678 					    NFS4_GETATTR_ATUID_ERR;
   1679 				} else {
   1680 					vap->va_uid = uid;
   1681 					vap->va_mask |= AT_UID;
   1682 					/* save the results for next time */
   1683 					if (pug && ol <= MAX_OG_NAME) {
   1684 						pug->uid = uid;
   1685 						pug->u_curr.utf8string_len =
   1686 						    ov.utf8string_len;
   1687 						bcopy(owner_val,
   1688 						    pug->u_curr.utf8string_val,
   1689 						    ol);
   1690 						U_SWAP_CURR_LAST(pug);
   1691 					}
   1692 				}
   1693 			}
   1694 			ptr += RNDUP(ol) / BYTES_PER_XDR_UNIT;
   1695 		}
   1696 		if (resbmap & FATTR4_OWNER_GROUP_MASK) {
   1697 			uint_t *group_length, gl;
   1698 			char *group_val = NULL;
   1699 			utf8string gv;
   1700 			int error;
   1701 
   1702 			/* get the OWNER_GROUP_LENGTH */
   1703 			gl = IXDR_GET_U_INT32(ptr);
   1704 
   1705 			/* Manage the group length location */
   1706 			if (pug && gl <= MAX_OG_NAME) {
   1707 				group_length = &pug->g_curr.utf8string_len;
   1708 				*group_length = gl;
   1709 			} else {
   1710 				group_length = &gl;
   1711 			}
   1712 
   1713 			/* find memory to store the decode */
   1714 			if (*group_length > MAX_OG_NAME || pug == NULL)
   1715 				group_val = (char *)ptr;
   1716 			else
   1717 				group_val = (char *)ptr;
   1718 
   1719 			/* Optimize for matching if called for */
   1720 			if (pug &&
   1721 			    *group_length == pug->g_last.utf8string_len &&
   1722 			    bcmp(group_val, pug->g_last.utf8string_val,
   1723 			    *group_length) == 0) {
   1724 				vap->va_gid = pug->gid;
   1725 				vap->va_mask |= AT_GID;
   1726 			} else {
   1727 				uid_t gid;
   1728 
   1729 				gv.utf8string_len = *group_length;
   1730 				gv.utf8string_val = group_val;
   1731 				error = nfs_idmap_str_gid(&gv, &gid, FALSE);
   1732 				/*
   1733 				 * String was mapped, but to nobody because
   1734 				 * we are nfsmapid, indicate it should not
   1735 				 * be cached.
   1736 				 */
   1737 				if (error == ENOTSUP) {
   1738 					error = 0;
   1739 					garp->n4g_attrwhy =
   1740 					    NFS4_GETATTR_NOCACHE_OK;
   1741 				}
   1742 
   1743 				if (error) {
   1744 					garp->n4g_attrerr = error;
   1745 					garp->n4g_attrwhy =
   1746 					    NFS4_GETATTR_ATGID_ERR;
   1747 				} else {
   1748 					vap->va_gid = gid;
   1749 					vap->va_mask |= AT_GID;
   1750 					if (pug && gl <= MAX_OG_NAME) {
   1751 						pug->gid = gid;
   1752 						pug->g_curr.utf8string_len =
   1753 						    gv.utf8string_len;
   1754 						bcopy(group_val,
   1755 						    pug->g_curr.utf8string_val,
   1756 						    gl);
   1757 						G_SWAP_CURR_LAST(pug);
   1758 					}
   1759 				}
   1760 			}
   1761 			ptr += RNDUP(gl) / BYTES_PER_XDR_UNIT;
   1762 		}
   1763 		if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) {
   1764 			ASSERT(0);
   1765 		}
   1766 		if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) {
   1767 			ASSERT(0);
   1768 		}
   1769 	}
   1770 	if (resbmap &
   1771 	    (FATTR4_QUOTA_USED_MASK |
   1772 	    FATTR4_SPACE_AVAIL_MASK |
   1773 	    FATTR4_SPACE_FREE_MASK |
   1774 	    FATTR4_SPACE_TOTAL_MASK |
   1775 	    FATTR4_SPACE_USED_MASK |
   1776 	    FATTR4_SYSTEM_MASK)) {
   1777 
   1778 		if (resbmap & FATTR4_QUOTA_USED_MASK) {
   1779 			ASSERT(0);
   1780 		}
   1781 		if (resbmap & FATTR4_RAWDEV_MASK) {
   1782 			fattr4_rawdev rawdev;
   1783 
   1784 			rawdev.specdata1 = IXDR_GET_U_INT32(ptr);
   1785 			rawdev.specdata2 = IXDR_GET_U_INT32(ptr);
   1786 
   1787 			if (vap->va_type == VCHR || vap->va_type == VBLK) {
   1788 				vap->va_rdev = makedevice(rawdev.specdata1,
   1789 				    rawdev.specdata2);
   1790 			} else {
   1791 				vap->va_rdev = 0;
   1792 			}
   1793 			vap->va_mask |= AT_RDEV;
   1794 		}
   1795 		if (resbmap & FATTR4_SPACE_AVAIL_MASK) {
   1796 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bavail);
   1797 			gesp->n4g_sb.f_bavail /= DEV_BSIZE;
   1798 		}
   1799 		if (resbmap & FATTR4_SPACE_FREE_MASK) {
   1800 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bfree);
   1801 			gesp->n4g_sb.f_bfree /= DEV_BSIZE;
   1802 		}
   1803 		if (resbmap & FATTR4_SPACE_TOTAL_MASK) {
   1804 			IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_blocks);
   1805 			gesp->n4g_sb.f_blocks /= DEV_BSIZE;
   1806 		}
   1807 		if (resbmap & FATTR4_SPACE_USED_MASK) {
   1808 			uint64_t space_used;
   1809 			IXDR_GET_U_HYPER(ptr, space_used);
   1810 
   1811 			/* Compute space depending on device type */
   1812 			ASSERT((vap->va_mask & AT_TYPE));
   1813 			if (vap->va_type == VREG || vap->va_type == VDIR ||
   1814 			    vap->va_type == VLNK) {
   1815 				vap->va_nblocks = (u_longlong_t)
   1816 				    ((space_used + (offset4)DEV_BSIZE -
   1817 				    (offset4)1) / (offset4)DEV_BSIZE);
   1818 			} else {
   1819 				vap->va_nblocks = 0;
   1820 			}
   1821 			vap->va_mask |= AT_NBLOCKS;
   1822 		}
   1823 		if (resbmap & FATTR4_SYSTEM_MASK) {
   1824 			ASSERT(0);
   1825 		}
   1826 	}
   1827 	if (resbmap &
   1828 	    (FATTR4_TIME_ACCESS_MASK |
   1829 	    FATTR4_TIME_ACCESS_SET_MASK |
   1830 	    FATTR4_TIME_BACKUP_MASK |
   1831 	    FATTR4_TIME_CREATE_MASK |
   1832 	    FATTR4_TIME_DELTA_MASK |
   1833 	    FATTR4_TIME_METADATA_MASK |
   1834 	    FATTR4_TIME_MODIFY_MASK |
   1835 	    FATTR4_TIME_MODIFY_SET_MASK |
   1836 	    FATTR4_MOUNTED_ON_FILEID_MASK)) {
   1837 
   1838 		if (resbmap & FATTR4_TIME_ACCESS_MASK) {
   1839 			nfstime4 atime;
   1840 			int error;
   1841 
   1842 			IXDR_GET_U_HYPER(ptr, atime.seconds);
   1843 			atime.nseconds = IXDR_GET_U_INT32(ptr);
   1844 
   1845 			error = nfs4_time_ntov(&atime, &vap->va_atime);
   1846 			if (error) {
   1847 				garp->n4g_attrerr = error;
   1848 				garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR;
   1849 			}
   1850 			vap->va_mask |= AT_ATIME;
   1851 		}
   1852 		if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) {
   1853 			ASSERT(0);
   1854 		}
   1855 		if (resbmap & FATTR4_TIME_BACKUP_MASK) {
   1856 			ASSERT(0);
   1857 		}
   1858 		if (resbmap & FATTR4_TIME_CREATE_MASK) {
   1859 			ASSERT(0);
   1860 		}
   1861 		if (resbmap & FATTR4_TIME_DELTA_MASK) {
   1862 			IXDR_GET_U_HYPER(ptr, gesp->n4g_delta.seconds);
   1863 			gesp->n4g_delta.nseconds = IXDR_GET_U_INT32(ptr);
   1864 		}
   1865 		if (resbmap & FATTR4_TIME_METADATA_MASK) {
   1866 			nfstime4 mdt;
   1867 			int error;
   1868 
   1869 			IXDR_GET_U_HYPER(ptr, mdt.seconds);
   1870 			mdt.nseconds = IXDR_GET_U_INT32(ptr);
   1871 
   1872 			error = nfs4_time_ntov(&mdt, &vap->va_ctime);
   1873 			if (error) {
   1874 				garp->n4g_attrerr = error;
   1875 				garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR;
   1876 			}
   1877 			vap->va_mask |= AT_CTIME;
   1878 		}
   1879 		if (resbmap & FATTR4_TIME_MODIFY_MASK) {
   1880 			nfstime4 mtime;
   1881 			int error;
   1882 
   1883 			IXDR_GET_U_HYPER(ptr, mtime.seconds);
   1884 			mtime.nseconds = IXDR_GET_U_INT32(ptr);
   1885 
   1886 			error = nfs4_time_ntov(&mtime, &vap->va_mtime);
   1887 			if (error) {
   1888 				garp->n4g_attrerr = error;
   1889 				garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR;
   1890 			}
   1891 			vap->va_mask |= AT_MTIME;
   1892 		}
   1893 		if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) {
   1894 			ASSERT(0);
   1895 		}
   1896 		if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) {
   1897 			IXDR_GET_U_HYPER(ptr, garp->n4g_mon_fid);
   1898 			garp->n4g_mon_fid_valid = 1;
   1899 		}
   1900 	}
   1901 
   1902 	/*
   1903 	 * FATTR4_ACL_MASK is not yet supported by this function, but
   1904 	 * we check against it anyway, in case it ever is.
   1905 	 */
   1906 	if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) {
   1907 		/* copy only if not provided */
   1908 		if (garp->n4g_ext_res == NULL) {
   1909 			garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP);
   1910 			bcopy(&ges, garp->n4g_ext_res, sizeof (ges));
   1911 		}
   1912 	}
   1913 
   1914 	return (TRUE);
   1915 }
   1916 
   1917 
   1918 /*
   1919  * "." and ".." buffers for filling in on read and readdir
   1920  * calls. Intialize the first time and fill in on every
   1921  * call to to readdir.
   1922  */
   1923 char	*nfs4_dot_entries;
   1924 char	*nfs4_dot_dot_entry;
   1925 
   1926 /*
   1927  * Create the "." or ".." and pad the buffer once so they are
   1928  * copied out as required into the user supplied buffer everytime.
   1929  * DIRENT64_RECLEN(sizeof (".") - 1) = DIRENT64_RECLEN(1)
   1930  * DIRENT64_RECLEN(sizeof ("..") - 1) = DIRENT64_RECLEN(2)
   1931  */
   1932 void
   1933 nfs4_init_dot_entries()
   1934 {
   1935 	struct dirent64 *odp;
   1936 
   1937 	/*
   1938 	 * zalloc it so it zeros the buffer out. Need
   1939 	 * to just do it once.
   1940 	 */
   1941 	nfs4_dot_entries = kmem_zalloc(DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2),
   1942 	    KM_SLEEP);
   1943 
   1944 	odp = (struct dirent64 *)nfs4_dot_entries;
   1945 	odp->d_off = 1; /* magic cookie for "." entry */
   1946 	odp->d_reclen = DIRENT64_RECLEN(1);
   1947 	odp->d_name[0] = '.';
   1948 	odp->d_name[1] = '\0';
   1949 
   1950 	nfs4_dot_dot_entry = nfs4_dot_entries + DIRENT64_RECLEN(1);
   1951 	odp = (struct dirent64 *)nfs4_dot_dot_entry;
   1952 
   1953 	odp->d_off = 2;
   1954 	odp->d_reclen = DIRENT64_RECLEN(2);
   1955 	odp->d_name[0] = '.';
   1956 	odp->d_name[1] = '.';
   1957 	odp->d_name[2] = '\0';
   1958 }
   1959 
   1960 void
   1961 nfs4_destroy_dot_entries()
   1962 {
   1963 	if (nfs4_dot_entries)
   1964 		kmem_free(nfs4_dot_entries, DIRENT64_RECLEN(1) +
   1965 		    DIRENT64_RECLEN(2));
   1966 
   1967 	nfs4_dot_entries = nfs4_dot_dot_entry = NULL;
   1968 }
   1969 
   1970 bool_t
   1971 xdr_READDIR4res_clnt(XDR *xdrs, READDIR4res_clnt *objp, READDIR4args *aobjp)
   1972 {
   1973 	bool_t more_data;
   1974 	rddir4_cache *rdc = aobjp->rdc;
   1975 	dirent64_t *dp = NULL;
   1976 	int entry_length = 0;
   1977 	int space_left = 0;
   1978 	bitmap4 resbmap;
   1979 	uint32_t attrlen;
   1980 	nfs4_ga_res_t gar;
   1981 	struct nfs4_ga_ext_res ges;
   1982 	uint64_t last_cookie = 0;
   1983 	int skip_to_end;
   1984 	ug_cache_t *pug = NULL;
   1985 
   1986 	ASSERT(xdrs->x_op == XDR_DECODE);
   1987 	ASSERT(rdc->entries == NULL);
   1988 	ASSERT(aobjp->dircount > 0);
   1989 
   1990 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   1991 		return (FALSE);
   1992 	if (objp->status != NFS4_OK)
   1993 		return (TRUE);
   1994 
   1995 	gar.n4g_va.va_mask = 0;
   1996 	gar.n4g_change_valid = 0;
   1997 	gar.n4g_mon_fid_valid = 0;
   1998 	gar.n4g_fsid_valid = 0;
   1999 	gar.n4g_vsa.vsa_mask = 0;
   2000 	gar.n4g_attrwhy = NFS4_GETATTR_OP_OK;
   2001 	ges.n4g_pc4.pc4_cache_valid = 0;
   2002 	ges.n4g_pc4.pc4_xattr_valid = 0;
   2003 	gar.n4g_ext_res = &ges;
   2004 
   2005 	/* READDIR4res_clnt_free needs to kmem_free this buffer */
   2006 	rdc->entries = kmem_alloc(aobjp->dircount, KM_SLEEP);
   2007 
   2008 	dp = (dirent64_t *)rdc->entries;
   2009 	rdc->entlen = rdc->buflen = space_left = aobjp->dircount;
   2010 
   2011 	/* Fill in dot and dot-dot if needed */
   2012 	if (rdc->nfs4_cookie == (nfs_cookie4) 0 ||
   2013 	    rdc->nfs4_cookie == (nfs_cookie4) 1) {
   2014 
   2015 		if (rdc->nfs4_cookie == (nfs_cookie4)0) {
   2016 			bcopy(nfs4_dot_entries, rdc->entries,
   2017 			    DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2));
   2018 			objp->dotp = dp;
   2019 			dp = (struct dirent64 *)(((char *)dp) +
   2020 			    DIRENT64_RECLEN(1));
   2021 			objp->dotdotp = dp;
   2022 			dp = (struct dirent64 *)(((char *)dp) +
   2023 			    DIRENT64_RECLEN(2));
   2024 			space_left -= DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2);
   2025 
   2026 		} else	{	/* for ".." entry */
   2027 			bcopy(nfs4_dot_dot_entry, rdc->entries,
   2028 			    DIRENT64_RECLEN(2));
   2029 			objp->dotp = NULL;
   2030 			objp->dotdotp = dp;
   2031 			dp = (struct dirent64 *)(((char *)dp) +
   2032 			    DIRENT64_RECLEN(2));
   2033 			space_left -= DIRENT64_RECLEN(2);
   2034 		}
   2035 		/* Magic NFSv4 number for entry after start */
   2036 		last_cookie = 2;
   2037 	}
   2038 
   2039 	/* Get the cookie VERIFIER */
   2040 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
   2041 		goto noentries;
   2042 
   2043 	/* Get the do-we-have-a-next-entry BOOL */
   2044 	if (!xdr_bool(xdrs, &more_data))
   2045 		goto noentries;
   2046 
   2047 	if (aobjp->attr_request & (FATTR4_OWNER_MASK | FATTR4_OWNER_GROUP_MASK))
   2048 		pug = alloc_ugcache();
   2049 
   2050 	skip_to_end = 0;
   2051 	while (more_data) {
   2052 		uint_t namelen;
   2053 		uint64_t cookie;
   2054 
   2055 		/* Get the COOKIE */
   2056 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&cookie))
   2057 			goto noentries;
   2058 
   2059 		/* Get the LENGTH of the entry name */
   2060 		if (!xdr_u_int(xdrs, &namelen))
   2061 			goto noentries;
   2062 
   2063 		if (!skip_to_end) {
   2064 			/*
   2065 			 * With the length of the directory entry name
   2066 			 * in hand, figure out if there is room left
   2067 			 * to encode it for the requestor.  If not,
   2068 			 * that is okay, but the rest of the readdir
   2069 			 * operation result must be decoded in the
   2070 			 * case there are following operations
   2071 			 * in the compound request.  Therefore, mark
   2072 			 * the rest of the response as "skip" and
   2073 			 * decode or skip the remaining data
   2074 			 */
   2075 			entry_length = DIRENT64_RECLEN(namelen);
   2076 			if (space_left < entry_length)
   2077 				skip_to_end = 1;
   2078 		}
   2079 
   2080 		/* Get the NAME of the entry */
   2081 		if (!skip_to_end) {
   2082 			if (!xdr_opaque(xdrs, dp->d_name, namelen))
   2083 				goto noentries;
   2084 			bzero(&dp->d_name[namelen],
   2085 			    DIRENT64_NAMELEN(entry_length) - namelen);
   2086 			dp->d_off = last_cookie = cookie;
   2087 			dp->d_reclen = entry_length;
   2088 		} else {
   2089 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &namelen))
   2090 				goto noentries;
   2091 		}
   2092 
   2093 		/* Get the attribute BITMAP */
   2094 		if (!xdr_bitmap4(xdrs, &resbmap))
   2095 			goto noentries;
   2096 		/* Get the LENGTH of the attributes */
   2097 		if (!xdr_u_int(xdrs, (uint_t *)&attrlen))
   2098 			goto noentries;
   2099 
   2100 		/* Get the ATTRIBUTES */
   2101 		if (!skip_to_end) {
   2102 			uint32_t *ptr;
   2103 
   2104 			if (!(resbmap & FATTR4_ACL_MASK) &&
   2105 			    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen))
   2106 			    != NULL) {
   2107 				if (!xdr_ga_fattr_res_inline(ptr, &gar, resbmap,
   2108 				    aobjp->attr_request, aobjp->mi, pug))
   2109 					goto noentries;
   2110 			} else {
   2111 				if (!xdr_ga_fattr_res(xdrs, &gar, resbmap,
   2112 				    aobjp->attr_request, aobjp->mi, pug))
   2113 					goto noentries;
   2114 			}
   2115 
   2116 			/* Fill in the d_ino per the server's fid values */
   2117 			/*
   2118 			 * Important to note that the mounted on fileid
   2119 			 * is returned in d_ino if supported.  This is
   2120 			 * expected, readdir returns the mounted on fileid
   2121 			 * while stat() returns the fileid of the object
   2122 			 * on "top" of the mount.
   2123 			 */
   2124 			if (gar.n4g_mon_fid_valid)
   2125 				dp->d_ino = gar.n4g_mon_fid;
   2126 			else if (gar.n4g_va.va_mask & AT_NODEID)
   2127 				dp->d_ino = gar.n4g_va.va_nodeid;
   2128 			else
   2129 				dp->d_ino = 0;
   2130 
   2131 			/* See about creating an rnode for this entry */
   2132 			if ((resbmap &
   2133 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) ==
   2134 			    (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) {
   2135 				nfs4_sharedfh_t *sfhp;
   2136 				vnode_t *vp;
   2137 
   2138 				sfhp = sfh4_put(&ges.n4g_fh_u.n4g_fh,
   2139 				    aobjp->mi, NULL);
   2140 				vp = makenfs4node(sfhp, &gar,
   2141 				    aobjp->dvp->v_vfsp,
   2142 				    aobjp->t,
   2143 				    aobjp->cr,
   2144 				    aobjp->dvp,
   2145 				    fn_get(VTOSV(aobjp->dvp)->sv_name,
   2146 				    dp->d_name, sfhp));
   2147 				sfh4_rele(&sfhp);
   2148 				dnlc_update(aobjp->dvp, dp->d_name, vp);
   2149 				VN_RELE(vp);
   2150 			}
   2151 
   2152 			dp = (struct dirent64 *)(((caddr_t)dp) + dp->d_reclen);
   2153 
   2154 			space_left -= entry_length;
   2155 
   2156 		} else {
   2157 			if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &attrlen))
   2158 				goto noentries;
   2159 		}
   2160 
   2161 		/* Get the do-we-have-a-next-entry BOOL */
   2162 		if (!xdr_bool(xdrs, &more_data))
   2163 			goto noentries;
   2164 	}
   2165 
   2166 	if (pug) {
   2167 		kmem_free(pug, sizeof (ug_cache_t));
   2168 		pug = NULL;
   2169 	}
   2170 
   2171 	/*
   2172 	 * Finish up the rddir cache
   2173 	 * If no entries were returned, free up buffer &
   2174 	 * set ncookie to the starting cookie for this
   2175 	 * readdir request so that the direof caching
   2176 	 * will work properly.
   2177 	 */
   2178 	ASSERT(rdc->entries);
   2179 	if (last_cookie == 0) {
   2180 		kmem_free(rdc->entries, rdc->entlen);
   2181 		rdc->entries = NULL;
   2182 		last_cookie = rdc->nfs4_cookie;
   2183 	}
   2184 
   2185 	rdc->actlen = rdc->entlen - space_left;
   2186 	rdc->nfs4_ncookie = last_cookie;
   2187 
   2188 	/* Get the EOF marker */
   2189 	if (!xdr_bool(xdrs, &objp->eof))
   2190 		goto noentries;
   2191 
   2192 	/*
   2193 	 * If the server returns eof and there were no
   2194 	 * skipped entries, set eof
   2195 	 */
   2196 	rdc->eof = (objp->eof && !skip_to_end) ? TRUE : FALSE;
   2197 
   2198 	/*
   2199 	 * If we encoded entries we are done
   2200 	 */
   2201 	if (rdc->entries) {
   2202 		rdc->error = 0;
   2203 		return (TRUE);
   2204 	}
   2205 
   2206 	/*
   2207 	 * If there were no entries and we skipped because
   2208 	 * there was not enough space, return EINVAL
   2209 	 */
   2210 	if (skip_to_end) {
   2211 		rdc->error = EINVAL;
   2212 		return (TRUE);
   2213 	}
   2214 
   2215 	/*
   2216 	 * No entries, nothing skipped, and EOF, return OK.
   2217 	 */
   2218 	if (objp->eof == TRUE) {
   2219 		rdc->error = 0;
   2220 		return (TRUE);
   2221 	}
   2222 
   2223 	/*
   2224 	 * No entries, nothing skipped, and not EOF
   2225 	 * probably a bad cookie, return ENOENT.
   2226 	 */
   2227 	rdc->error = ENOENT;
   2228 	return (TRUE);
   2229 
   2230 noentries:
   2231 	if (rdc->entries) {
   2232 		kmem_free(rdc->entries, rdc->entlen);
   2233 		rdc->entries = NULL;
   2234 	}
   2235 	if (pug)
   2236 		kmem_free(pug, sizeof (ug_cache_t));
   2237 	rdc->error = EIO;
   2238 	return (FALSE);
   2239 }
   2240 
   2241 /*
   2242  * xdr_ga_res
   2243  *
   2244  * Returns: FALSE on raw data processing errors, TRUE otherwise.
   2245  *
   2246  * This function pre-processes the OP_GETATTR response, and then
   2247  * calls common routines to process the GETATTR fattr4 results into
   2248  * vnode attributes and other components that the client is interested
   2249  * in. If an error other than an RPC error is encountered, the details
   2250  * of the error are filled into objp, although the result of the
   2251  * processing is set to TRUE.
   2252  */
   2253 static bool_t
   2254 xdr_ga_res(XDR *xdrs, GETATTR4res *objp, GETATTR4args *aobjp)
   2255 {
   2256 	uint32_t *ptr;
   2257 	bitmap4 resbmap;
   2258 	uint32_t attrlen;
   2259 
   2260 	ASSERT(xdrs->x_op == XDR_DECODE);
   2261 
   2262 	/* Initialize objp attribute error values */
   2263 	objp->ga_res.n4g_attrerr =
   2264 	    objp->ga_res.n4g_attrwhy = NFS4_GETATTR_OP_OK;
   2265 
   2266 	if (!xdr_bitmap4(xdrs, &resbmap))
   2267 		return (FALSE);
   2268 
   2269 	/* save the response bitmap for the caller */
   2270 	objp->ga_res.n4g_resbmap = resbmap;
   2271 
   2272 	/* attrlen */
   2273 	if (!XDR_GETINT32(xdrs, (int32_t *)&attrlen))
   2274 		return (FALSE);
   2275 
   2276 	/*
   2277 	 * Handle case where request and response bitmaps don't match.
   2278 	 */
   2279 	if (aobjp->attr_request && aobjp->attr_request != resbmap) {
   2280 		bitmap4 deltabmap;
   2281 
   2282 		/*
   2283 		 * Return error for case where server sent extra attributes
   2284 		 * because the "unknown" attributes may be anywhere in the
   2285 		 * xdr stream and can't be properly processed.
   2286 		 */
   2287 		deltabmap = ((aobjp->attr_request ^ resbmap) & resbmap);
   2288 		if (deltabmap) {
   2289 			objp->ga_res.n4g_attrerr = EINVAL;
   2290 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_BITMAP_ERR;
   2291 			return (TRUE);
   2292 		}
   2293 
   2294 		/*
   2295 		 * Return error for case where there is a mandatory
   2296 		 * attribute missing in the server response. Note that
   2297 		 * missing recommended attributes are evaluated in the
   2298 		 * specific routines that decode the server response.
   2299 		 */
   2300 		deltabmap = ((aobjp->attr_request ^ resbmap)
   2301 		    & aobjp->attr_request);
   2302 		if ((deltabmap & FATTR4_MANDATTR_MASK)) {
   2303 			objp->ga_res.n4g_attrerr = EINVAL;
   2304 			objp->ga_res.n4g_attrwhy = NFS4_GETATTR_MANDATTR_ERR;
   2305 			return (TRUE);
   2306 		}
   2307 	}
   2308 
   2309 	/* Check to see if the attrs can be inlined and go for it if so */
   2310 	if (!(resbmap & FATTR4_ACL_MASK) &&
   2311 	    (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen)) != NULL)
   2312 		return (xdr_ga_fattr_res_inline(ptr, &objp->ga_res,
   2313 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
   2314 	else
   2315 		return (xdr_ga_fattr_res(xdrs, &objp->ga_res,
   2316 		    resbmap, aobjp->attr_request, aobjp->mi, NULL));
   2317 }
   2318 
   2319 #if defined(DEBUG) && !defined(lint)
   2320 /*
   2321  * We assume that an enum is a 32-bit value, check it once
   2322  */
   2323 static enum szchk { SZVAL } szchkvar;
   2324 #endif
   2325 
   2326 bool_t
   2327 xdr_settime4(XDR *xdrs, settime4 *objp)
   2328 {
   2329 #if defined(DEBUG) && !defined(lint)
   2330 	ASSERT(sizeof (szchkvar) == sizeof (int32_t));
   2331 #endif
   2332 	if (xdrs->x_op == XDR_FREE)
   2333 		return (TRUE);
   2334 
   2335 	if (!xdr_int(xdrs, (int *)&objp->set_it))
   2336 		return (FALSE);
   2337 	if (objp->set_it != SET_TO_CLIENT_TIME4)
   2338 		return (TRUE);
   2339 	/* xdr_nfstime4 */
   2340 	if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->time.seconds))
   2341 		return (FALSE);
   2342 	return (xdr_u_int(xdrs, &objp->time.nseconds));
   2343 }
   2344 
   2345 static bool_t
   2346 xdr_fattr4(XDR *xdrs, fattr4 *objp)
   2347 {
   2348 	if (xdrs->x_op != XDR_FREE) {
   2349 		if (!xdr_bitmap4(xdrs, &objp->attrmask))
   2350 			return (FALSE);
   2351 		return (xdr_bytes(xdrs, (char **)&objp->attrlist4,
   2352 		    (uint_t *)&objp->attrlist4_len, NFS4_FATTR4_LIMIT));
   2353 	}
   2354 
   2355 	/*
   2356 	 * Optimized free case
   2357 	 */
   2358 	if (objp->attrlist4 != NULL)
   2359 		kmem_free(objp->attrlist4, objp->attrlist4_len);
   2360 	return (TRUE);
   2361 }
   2362 
   2363 static bool_t
   2364 xdr_ACCESS4res(XDR *xdrs, ACCESS4res *objp)
   2365 {
   2366 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   2367 		return (FALSE);
   2368 	if (objp->status != NFS4_OK)
   2369 		return (TRUE);
   2370 	if (!xdr_u_int(xdrs, &objp->supported))
   2371 		return (FALSE);
   2372 	return (xdr_u_int(xdrs, &objp->access));
   2373 }
   2374 
   2375 static bool_t
   2376 xdr_CLOSE4args(XDR *xdrs, CLOSE4args *objp)
   2377 {
   2378 	if (!xdr_u_int(xdrs, &objp->seqid))
   2379 		return (FALSE);
   2380 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
   2381 		return (FALSE);
   2382 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
   2383 }
   2384 
   2385 static bool_t
   2386 xdr_CLOSE4res(XDR *xdrs, CLOSE4res *objp)
   2387 {
   2388 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   2389 		return (FALSE);
   2390 	if (objp->status != NFS4_OK)
   2391 		return (TRUE);
   2392 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
   2393 		return (FALSE);
   2394 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
   2395 }
   2396 
   2397 static bool_t
   2398 xdr_CREATE4args(XDR *xdrs, CREATE4args *objp)
   2399 {
   2400 	if (xdrs->x_op != XDR_FREE) {
   2401 		if (!xdr_int(xdrs, (int32_t *)&objp->type))
   2402 			return (FALSE);
   2403 		switch (objp->type) {
   2404 		case NF4LNK:
   2405 			if (!xdr_bytes(xdrs,
   2406 			    (char **)&objp->ftype4_u.linkdata.utf8string_val,
   2407 			    (uint_t *)&objp->ftype4_u.linkdata.utf8string_len,
   2408 			    NFS4_MAX_UTF8STRING))
   2409 				return (FALSE);
   2410 			break;
   2411 		case NF4BLK:
   2412 		case NF4CHR:
   2413 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata1))
   2414 				return (FALSE);
   2415 			if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata2))
   2416 				return (FALSE);
   2417 			break;
   2418 		case NF4SOCK:
   2419 		case NF4FIFO:
   2420 		case NF4DIR:
   2421 		default:
   2422 			break;	/* server should return NFS4ERR_BADTYPE */
   2423 		}
   2424 		if (!xdr_bytes(xdrs, (char **)&objp->objname.utf8string_val,
   2425 		    (uint_t *)&objp->objname.utf8string_len,
   2426 		    NFS4_MAX_UTF8STRING))
   2427 			return (FALSE);
   2428 		return (xdr_fattr4(xdrs, &objp->createattrs));
   2429 	}
   2430 
   2431 	/*
   2432 	 * Optimized free case
   2433 	 */
   2434 	if (objp->type == NF4LNK) {
   2435 		if (objp->ftype4_u.linkdata.utf8string_val != NULL)
   2436 			kmem_free(objp->ftype4_u.linkdata.utf8string_val,
   2437 			    objp->ftype4_u.linkdata.utf8string_len);
   2438 	}
   2439 	if (objp->objname.utf8string_val != NULL)
   2440 		kmem_free(objp->objname.utf8string_val,
   2441 		    objp->objname.utf8string_len);
   2442 	return (xdr_fattr4(xdrs, &objp->createattrs));
   2443 }
   2444 
   2445 static bool_t
   2446 xdr_CREATE4cargs(XDR *xdrs, CREATE4cargs *objp)
   2447 {
   2448 	int len;
   2449 
   2450 	ASSERT(xdrs->x_op == XDR_ENCODE);
   2451 
   2452 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->type))
   2453 		return (FALSE);
   2454 	switch (objp->type) {
   2455 	case NF4LNK:
   2456 		len = strlen(objp->ftype4_u.clinkdata);
   2457 		if (len > NFS4_MAX_UTF8STRING)
   2458 			return (FALSE);
   2459 		if (!XDR_PUTINT32(xdrs, &len))
   2460 			return (FALSE);
   2461 		if (!xdr_opaque(xdrs, objp->ftype4_u.clinkdata, len))
   2462 			return (FALSE);
   2463 		break;
   2464 	case NF4BLK:
   2465 	case NF4CHR:
   2466 		if (!XDR_PUTINT32(xdrs,
   2467 		    (int32_t *)&objp->ftype4_u.devdata.specdata1))
   2468 			return (FALSE);
   2469 		if (!XDR_PUTINT32(xdrs,
   2470 		    (int32_t *)&objp->ftype4_u.devdata.specdata2))
   2471 			return (FALSE);
   2472 		break;
   2473 	case NF4SOCK:
   2474 	case NF4FIFO:
   2475 	case NF4DIR:
   2476 	default:
   2477 		break;	/* server should return NFS4ERR_BADTYPE */
   2478 	}
   2479 
   2480 	len = strlen(objp->cname);
   2481 	if (len > NFS4_MAX_UTF8STRING)
   2482 		return (FALSE);
   2483 	if (!XDR_PUTINT32(xdrs, &len))
   2484 		return (FALSE);
   2485 	if (!xdr_opaque(xdrs, objp->cname, len))
   2486 		return (FALSE);
   2487 
   2488 	return (xdr_fattr4(xdrs, &objp->createattrs));
   2489 }
   2490 
   2491 static bool_t
   2492 xdr_CREATE4res(XDR *xdrs, CREATE4res *objp)
   2493 {
   2494 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   2495 		return (FALSE);
   2496 	if (objp->status != NFS4_OK)
   2497 		return (TRUE);
   2498 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
   2499 		return (FALSE);
   2500 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
   2501 		return (FALSE);
   2502 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
   2503 		return (FALSE);
   2504 	return (xdr_bitmap4(xdrs, &objp->attrset));
   2505 }
   2506 
   2507 static bool_t
   2508 xdr_LINK4res(XDR *xdrs, LINK4res *objp)
   2509 {
   2510 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   2511 		return (FALSE);
   2512 	if (objp->status != NFS4_OK)
   2513 		return (TRUE);
   2514 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
   2515 		return (FALSE);
   2516 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
   2517 		return (FALSE);
   2518 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after));
   2519 }
   2520 
   2521 static bool_t
   2522 xdr_LOCK4args(XDR *xdrs, LOCK4args *objp)
   2523 {
   2524 	if (xdrs->x_op != XDR_FREE) {
   2525 		if (!xdr_int(xdrs, (int *)&objp->locktype))
   2526 			return (FALSE);
   2527 		if (!xdr_bool(xdrs, &objp->reclaim))
   2528 			return (FALSE);
   2529 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
   2530 			return (FALSE);
   2531 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
   2532 			return (FALSE);
   2533 		if (!xdr_bool(xdrs, &objp->locker.new_lock_owner))
   2534 			return (FALSE);
   2535 		if (objp->locker.new_lock_owner == TRUE) {
   2536 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
   2537 			    open_seqid))
   2538 				return (FALSE);
   2539 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
   2540 			    open_stateid.seqid))
   2541 				return (FALSE);
   2542 			if (!xdr_opaque(xdrs, objp->locker.locker4_u.open_owner.
   2543 			    open_stateid.other, 12))
   2544 				return (FALSE);
   2545 			if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner.
   2546 			    lock_seqid))
   2547 				return (FALSE);
   2548 			if (!xdr_u_longlong_t(xdrs,
   2549 			    (u_longlong_t *)&objp->locker.locker4_u.
   2550 			    open_owner.lock_owner.clientid))
   2551 				return (FALSE);
   2552 			return (xdr_bytes(xdrs,
   2553 			    (char **)&objp->locker.locker4_u.open_owner.
   2554 			    lock_owner.owner_val,
   2555 			    (uint_t *)&objp->locker.locker4_u.open_owner.
   2556 			    lock_owner.owner_len,
   2557 			    NFS4_OPAQUE_LIMIT));
   2558 		}
   2559 
   2560 		if (objp->locker.new_lock_owner != FALSE)
   2561 			return (FALSE);
   2562 
   2563 		if (!xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
   2564 		    lock_stateid.seqid))
   2565 			return (FALSE);
   2566 		if (!xdr_opaque(xdrs, objp->locker.locker4_u.lock_owner.
   2567 		    lock_stateid.other, 12))
   2568 			return (FALSE);
   2569 		return (xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner.
   2570 		    lock_seqid));
   2571 	}
   2572 
   2573 	/*
   2574 	 * Optimized free case
   2575 	 */
   2576 	if (objp->locker.new_lock_owner == TRUE) {
   2577 		if (objp->locker.locker4_u.open_owner.lock_owner.owner_val !=
   2578 		    NULL) {
   2579 			kmem_free(objp->locker.locker4_u.open_owner.lock_owner.
   2580 			    owner_val,
   2581 			    objp->locker.locker4_u.open_owner.lock_owner.
   2582 			    owner_len);
   2583 		}
   2584 	}
   2585 
   2586 	return (TRUE);
   2587 }
   2588 
   2589 static bool_t
   2590 xdr_LOCK4res(XDR *xdrs, LOCK4res *objp)
   2591 {
   2592 	if (xdrs->x_op != XDR_FREE) {
   2593 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
   2594 			return (FALSE);
   2595 		if (objp->status == NFS4_OK) {
   2596 			if (!xdr_u_int(xdrs,
   2597 			    &objp->LOCK4res_u.lock_stateid.seqid))
   2598 				return (FALSE);
   2599 			return (xdr_opaque(xdrs,
   2600 			    objp->LOCK4res_u.lock_stateid.other, 12));
   2601 		}
   2602 		if (objp->status != NFS4ERR_DENIED)
   2603 			return (TRUE);
   2604 
   2605 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
   2606 		    denied.offset))
   2607 			return (FALSE);
   2608 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
   2609 		    denied.length))
   2610 			return (FALSE);
   2611 		if (!xdr_int(xdrs, (int *)&objp->LOCK4res_u.denied.locktype))
   2612 			return (FALSE);
   2613 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u.
   2614 		    denied.owner.clientid))
   2615 			return (FALSE);
   2616 		return (xdr_bytes(xdrs,
   2617 		    (char **)&objp->LOCK4res_u.denied.owner.owner_val,
   2618 		    (uint_t *)&objp->LOCK4res_u.denied.owner.owner_len,
   2619 		    NFS4_OPAQUE_LIMIT));
   2620 	}
   2621 
   2622 	/*
   2623 	 * Optimized free case
   2624 	 */
   2625 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
   2626 		return (TRUE);
   2627 
   2628 	if (objp->LOCK4res_u.denied.owner.owner_val != NULL)
   2629 		kmem_free(objp->LOCK4res_u.denied.owner.owner_val,
   2630 		    objp->LOCK4res_u.denied.owner.owner_len);
   2631 	return (TRUE);
   2632 }
   2633 
   2634 static bool_t
   2635 xdr_LOCKT4args(XDR *xdrs, LOCKT4args *objp)
   2636 {
   2637 	if (xdrs->x_op != XDR_FREE) {
   2638 		if (!xdr_int(xdrs, (int *)&objp->locktype))
   2639 			return (FALSE);
   2640 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
   2641 			return (FALSE);
   2642 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length))
   2643 			return (FALSE);
   2644 		if (!xdr_u_longlong_t(xdrs,
   2645 		    (u_longlong_t *)&objp->owner.clientid))
   2646 			return (FALSE);
   2647 		return (xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
   2648 		    (uint_t *)&objp->owner.owner_len,
   2649 		    NFS4_OPAQUE_LIMIT));
   2650 	}
   2651 
   2652 	/*
   2653 	 * Optimized free case
   2654 	 */
   2655 	if (objp->owner.owner_val != NULL)
   2656 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
   2657 	return (TRUE);
   2658 }
   2659 
   2660 static bool_t
   2661 xdr_LOCKT4res(XDR *xdrs, LOCKT4res *objp)
   2662 {
   2663 	if (xdrs->x_op != XDR_FREE) {
   2664 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
   2665 			return (FALSE);
   2666 		if (objp->status == NFS4_OK)
   2667 			return (TRUE);
   2668 		if (objp->status != NFS4ERR_DENIED)
   2669 			return (TRUE);
   2670 		/* xdr_LOCK4denied */
   2671 		if (!xdr_u_longlong_t(xdrs,
   2672 		    (u_longlong_t *)&objp->denied.offset))
   2673 			return (FALSE);
   2674 		if (!xdr_u_longlong_t(xdrs,
   2675 		    (u_longlong_t *)&objp->denied.length))
   2676 			return (FALSE);
   2677 		if (!xdr_int(xdrs, (int *)&objp->denied.locktype))
   2678 			return (FALSE);
   2679 		if (!xdr_u_longlong_t(xdrs,
   2680 		    (u_longlong_t *)&objp->denied.owner.clientid))
   2681 			return (FALSE);
   2682 		return (xdr_bytes(xdrs,
   2683 		    (char **)&objp->denied.owner.owner_val,
   2684 		    (uint_t *)&objp->denied.owner.owner_len,
   2685 		    NFS4_OPAQUE_LIMIT));
   2686 	}
   2687 
   2688 	/*
   2689 	 * Optimized free case
   2690 	 */
   2691 	if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED)
   2692 		return (TRUE);
   2693 	if (objp->denied.owner.owner_val != NULL)
   2694 		kmem_free(objp->denied.owner.owner_val,
   2695 		    objp->denied.owner.owner_len);
   2696 	return (TRUE);
   2697 }
   2698 
   2699 static bool_t
   2700 xdr_LOCKU4args(XDR *xdrs, LOCKU4args *objp)
   2701 {
   2702 	if (!xdr_int(xdrs, (int *)&objp->locktype))
   2703 		return (FALSE);
   2704 	if (!xdr_u_int(xdrs, &objp->seqid))
   2705 		return (FALSE);
   2706 	if (!xdr_u_int(xdrs, &objp->lock_stateid.seqid))
   2707 		return (FALSE);
   2708 	if (!xdr_opaque(xdrs, objp->lock_stateid.other, 12))
   2709 		return (FALSE);
   2710 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
   2711 		return (FALSE);
   2712 	return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length));
   2713 }
   2714 
   2715 static bool_t
   2716 xdr_OPEN4args(XDR *xdrs, OPEN4args *objp)
   2717 {
   2718 	if (xdrs->x_op != XDR_FREE) {
   2719 		if (!xdr_u_int(xdrs, &objp->seqid))
   2720 			return (FALSE);
   2721 		if (!xdr_u_int(xdrs, &objp->share_access))
   2722 			return (FALSE);
   2723 		if (!xdr_u_int(xdrs, &objp->share_deny))
   2724 			return (FALSE);
   2725 
   2726 		/* xdr_open_owner4 */
   2727 		if (!xdr_u_longlong_t(xdrs,
   2728 		    (u_longlong_t *)&objp->owner.clientid))
   2729 			return (FALSE);
   2730 		if (!xdr_bytes(xdrs, (char **)&objp->owner.owner_val,
   2731 		    (uint_t *)&objp->owner.owner_len,
   2732 		    NFS4_OPAQUE_LIMIT))
   2733 			return (FALSE);
   2734 
   2735 		/* xdr_openflag4 */
   2736 		if (!xdr_int(xdrs, (int *)&objp->opentype))
   2737 			return (FALSE);
   2738 		if (objp->opentype == OPEN4_CREATE) {
   2739 
   2740 			/* xdr_createhow4 */
   2741 			if (!xdr_int(xdrs, (int *)&objp->mode))
   2742 				return (FALSE);
   2743 			switch (objp->mode) {
   2744 			case UNCHECKED4:
   2745 			case GUARDED4:
   2746 				if (!xdr_fattr4(xdrs,
   2747 				    &objp->createhow4_u.createattrs))
   2748 					return (FALSE);
   2749 				break;
   2750 			case EXCLUSIVE4:
   2751 				if (!xdr_u_longlong_t(xdrs,
   2752 				    (u_longlong_t *)&objp->createhow4_u.
   2753 				    createverf))
   2754 					return (FALSE);
   2755 				break;
   2756 			default:
   2757 				return (FALSE);
   2758 			}
   2759 		}
   2760 
   2761 		/* xdr_open_claim4 */
   2762 		if (!xdr_int(xdrs, (int *)&objp->claim))
   2763 			return (FALSE);
   2764 
   2765 		switch (objp->claim) {
   2766 		case CLAIM_NULL:
   2767 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
   2768 			    file.utf8string_val,
   2769 			    (uint_t *)&objp->open_claim4_u.file.
   2770 			    utf8string_len,
   2771 			    NFS4_MAX_UTF8STRING));
   2772 		case CLAIM_PREVIOUS:
   2773 			return (xdr_int(xdrs,
   2774 			    (int *)&objp->open_claim4_u.delegate_type));
   2775 		case CLAIM_DELEGATE_CUR:
   2776 			if (!xdr_u_int(xdrs, (uint_t *)&objp->open_claim4_u.
   2777 			    delegate_cur_info.delegate_stateid.seqid))
   2778 				return (FALSE);
   2779 			if (!xdr_opaque(xdrs, objp->open_claim4_u.
   2780 			    delegate_cur_info.delegate_stateid.other,
   2781 			    12))
   2782 				return (FALSE);
   2783 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
   2784 			    delegate_cur_info.file.utf8string_val,
   2785 			    (uint_t *)&objp->open_claim4_u.
   2786 			    delegate_cur_info.file.utf8string_len,
   2787 			    NFS4_MAX_UTF8STRING));
   2788 		case CLAIM_DELEGATE_PREV:
   2789 			return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u.
   2790 			    file_delegate_prev.utf8string_val,
   2791 			    (uint_t *)&objp->open_claim4_u.
   2792 			    file_delegate_prev.utf8string_len,
   2793 			    NFS4_MAX_UTF8STRING));
   2794 		default:
   2795 			return (FALSE);
   2796 		}
   2797 	}
   2798 
   2799 	/*
   2800 	 * Optimized free case
   2801 	 */
   2802 	if (objp->owner.owner_val != NULL)
   2803 		kmem_free(objp->owner.owner_val, objp->owner.owner_len);
   2804 
   2805 	if (objp->opentype == OPEN4_CREATE) {
   2806 		switch (objp->mode) {
   2807 		case UNCHECKED4:
   2808 		case GUARDED4:
   2809 			(void) xdr_fattr4(xdrs,
   2810 			    &objp->createhow4_u.createattrs);
   2811 			break;
   2812 		case EXCLUSIVE4:
   2813 		default:
   2814 			break;
   2815 		}
   2816 	}
   2817 
   2818 	switch (objp->claim) {
   2819 	case CLAIM_NULL:
   2820 		if (objp->open_claim4_u.file.utf8string_val != NULL)
   2821 			kmem_free(objp->open_claim4_u.file.utf8string_val,
   2822 			    objp->open_claim4_u.file.utf8string_len);
   2823 		return (TRUE);
   2824 	case CLAIM_PREVIOUS:
   2825 		return (TRUE);
   2826 	case CLAIM_DELEGATE_CUR:
   2827 		if (objp->open_claim4_u.delegate_cur_info.file.utf8string_val !=
   2828 		    NULL) {
   2829 			kmem_free(objp->open_claim4_u.delegate_cur_info.file.
   2830 			    utf8string_val,
   2831 			    objp->open_claim4_u.delegate_cur_info.file.
   2832 			    utf8string_len);
   2833 		}
   2834 		return (TRUE);
   2835 	case CLAIM_DELEGATE_PREV:
   2836 		if (objp->open_claim4_u.file_delegate_prev.utf8string_val !=
   2837 		    NULL) {
   2838 			kmem_free(objp->open_claim4_u.file_delegate_prev.
   2839 			    utf8string_val,
   2840 			    objp->open_claim4_u.file_delegate_prev.
   2841 			    utf8string_len);
   2842 		}
   2843 		return (TRUE);
   2844 	default:
   2845 		return (TRUE);
   2846 	}
   2847 }
   2848 
   2849 static bool_t
   2850 xdr_OPEN4cargs(XDR *xdrs, OPEN4cargs *objp)
   2851 {
   2852 	int op;
   2853 	int len;
   2854 	rpc_inline_t *ptr;
   2855 
   2856 	ASSERT(xdrs->x_op == XDR_ENCODE);
   2857 
   2858 	/*
   2859 	 * We must always define the client's open_owner to be
   2860 	 * 4 byte aligned and sized.
   2861 	 */
   2862 	ASSERT(objp->owner.owner_len <= NFS4_OPAQUE_LIMIT);
   2863 	ASSERT(!(objp->owner.owner_len % BYTES_PER_XDR_UNIT));
   2864 
   2865 	len = objp->owner.owner_len;
   2866 	if ((ptr = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + len)) != NULL) {
   2867 		int i;
   2868 		int32_t *ip;
   2869 
   2870 		IXDR_PUT_U_INT32(ptr, OP_OPEN);
   2871 		IXDR_PUT_U_INT32(ptr, objp->seqid);
   2872 		IXDR_PUT_U_INT32(ptr, objp->share_access);
   2873 		IXDR_PUT_U_INT32(ptr, objp->share_deny);
   2874 
   2875 		/* xdr_open_owner4 */
   2876 		IXDR_PUT_HYPER(ptr, objp->owner.clientid);
   2877 		IXDR_PUT_U_INT32(ptr, objp->owner.owner_len);
   2878 		/* We know this is very short so don't bcopy */
   2879 		ip = (int32_t *)objp->owner.owner_val;
   2880 		len /= BYTES_PER_XDR_UNIT;
   2881 		for (i = 0; i < len; i++)
   2882 			*ptr++ = *ip++;
   2883 
   2884 		/* xdr_openflag4 */
   2885 		IXDR_PUT_U_INT32(ptr, objp->opentype);
   2886 	} else {
   2887 		op = OP_OPEN;
   2888 		if (!XDR_PUTINT32(xdrs, (int32_t *)&op))
   2889 			return (FALSE);
   2890 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->seqid))
   2891 			return (FALSE);
   2892 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_access))
   2893 			return (FALSE);
   2894 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_deny))
   2895 			return (FALSE);
   2896 
   2897 		/* xdr_open_owner4 */
   2898 		if (!xdr_u_longlong_t(xdrs,
   2899 		    (u_longlong_t *)&objp->owner.clientid))
   2900 			return (FALSE);
   2901 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->owner.owner_len))
   2902 			return (FALSE);
   2903 		if (!xdr_opaque(xdrs, objp->owner.owner_val,
   2904 		    objp->owner.owner_len))
   2905 			return (FALSE);
   2906 
   2907 		/* xdr_openflag4 */
   2908 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->opentype))
   2909 			return (FALSE);
   2910 	}
   2911 
   2912 	if (objp->opentype == OPEN4_CREATE) {
   2913 		/* xdr_createhow4 */
   2914 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->mode))
   2915 			return (FALSE);
   2916 		switch (objp->mode) {
   2917 		case UNCHECKED4:
   2918 		case GUARDED4:
   2919 			if (!xdr_fattr4(xdrs,
   2920 			    &objp->createhow4_u.createattrs))
   2921 				return (FALSE);
   2922 			break;
   2923 		case EXCLUSIVE4:
   2924 			if (!xdr_u_longlong_t(xdrs,
   2925 			    (u_longlong_t *)&objp->createhow4_u.
   2926 			    createverf))
   2927 				return (FALSE);
   2928 			break;
   2929 		default:
   2930 			return (FALSE);
   2931 		}
   2932 	}
   2933 
   2934 	/* xdr_open_claim4 */
   2935 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->claim))
   2936 		return (FALSE);
   2937 
   2938 	switch (objp->claim) {
   2939 	case CLAIM_NULL:
   2940 		len = strlen(objp->open_claim4_u.cfile);
   2941 		if (len > NFS4_MAX_UTF8STRING)
   2942 			return (FALSE);
   2943 		if (XDR_PUTINT32(xdrs, &len)) {
   2944 			return (xdr_opaque(xdrs,
   2945 			    objp->open_claim4_u.cfile, len));
   2946 		}
   2947 		return (FALSE);
   2948 	case CLAIM_PREVIOUS:
   2949 		return (XDR_PUTINT32(xdrs,
   2950 		    (int32_t *)&objp->open_claim4_u.delegate_type));
   2951 	case CLAIM_DELEGATE_CUR:
   2952 		if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->open_claim4_u.
   2953 		    delegate_cur_info.delegate_stateid.seqid))
   2954 			return (FALSE);
   2955 		if (!xdr_opaque(xdrs, objp->open_claim4_u.
   2956 		    delegate_cur_info.delegate_stateid.other,
   2957 		    12))
   2958 			return (FALSE);
   2959 		len = strlen(objp->open_claim4_u.delegate_cur_info.cfile);
   2960 		if (len > NFS4_MAX_UTF8STRING)
   2961 			return (FALSE);
   2962 		if (XDR_PUTINT32(xdrs, &len)) {
   2963 			return (xdr_opaque(xdrs,
   2964 			    objp->open_claim4_u.delegate_cur_info.cfile,
   2965 			    len));
   2966 		}
   2967 		return (FALSE);
   2968 	case CLAIM_DELEGATE_PREV:
   2969 		len = strlen(objp->open_claim4_u.cfile_delegate_prev);
   2970 		if (len > NFS4_MAX_UTF8STRING)
   2971 			return (FALSE);
   2972 		if (XDR_PUTINT32(xdrs, &len)) {
   2973 			return (xdr_opaque(xdrs,
   2974 			    objp->open_claim4_u.cfile_delegate_prev, len));
   2975 		}
   2976 		return (FALSE);
   2977 	default:
   2978 		return (FALSE);
   2979 	}
   2980 }
   2981 
   2982 static bool_t
   2983 xdr_OPEN4res(XDR *xdrs, OPEN4res *objp)
   2984 {
   2985 	if (xdrs->x_op != XDR_FREE) {
   2986 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
   2987 			return (FALSE);
   2988 		if (objp->status != NFS4_OK)
   2989 			return (TRUE);
   2990 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
   2991 			return (FALSE);
   2992 		if (!xdr_opaque(xdrs, objp->stateid.other, 12))
   2993 			return (FALSE);
   2994 		if (!xdr_bool(xdrs, &objp->cinfo.atomic))
   2995 			return (FALSE);
   2996 		if (!xdr_u_longlong_t(xdrs,
   2997 		    (u_longlong_t *)&objp->cinfo.before))
   2998 			return (FALSE);
   2999 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after))
   3000 			return (FALSE);
   3001 		if (!xdr_u_int(xdrs, &objp->rflags))
   3002 			return (FALSE);
   3003 		if (!xdr_bitmap4(xdrs, &objp->attrset))
   3004 			return (FALSE);
   3005 		if (!xdr_int(xdrs,
   3006 		    (int *)&objp->delegation.delegation_type))
   3007 			return (FALSE);
   3008 		switch (objp->delegation.delegation_type) {
   3009 		case OPEN_DELEGATE_NONE:
   3010 			return (TRUE);
   3011 		case OPEN_DELEGATE_READ:
   3012 			if (!xdr_u_int(xdrs, &objp->delegation.
   3013 			    open_delegation4_u.read.stateid.seqid))
   3014 				return (FALSE);
   3015 			if (!xdr_opaque(xdrs, objp->delegation.
   3016 			    open_delegation4_u.read.stateid.other,
   3017 			    12))
   3018 				return (FALSE);
   3019 			if (!xdr_bool(xdrs, &objp->delegation.
   3020 			    open_delegation4_u.read.recall))
   3021 				return (FALSE);
   3022 			return (xdr_nfsace4(xdrs, &objp->delegation.
   3023 			    open_delegation4_u.read.permissions));
   3024 		case OPEN_DELEGATE_WRITE:
   3025 			if (!xdr_u_int(xdrs, &objp->delegation.
   3026 			    open_delegation4_u.write.stateid.seqid))
   3027 				return (FALSE);
   3028 			if (!xdr_opaque(xdrs, objp->delegation.
   3029 			    open_delegation4_u.write.stateid.other,
   3030 			    12))
   3031 				return (FALSE);
   3032 			if (!xdr_bool(xdrs, &objp->delegation.
   3033 			    open_delegation4_u.write.recall))
   3034 				return (FALSE);
   3035 			if (!xdr_int(xdrs, (int *)&objp->delegation.
   3036 			    open_delegation4_u.write.space_limit.
   3037 			    limitby))
   3038 				return (FALSE);
   3039 			switch (objp->delegation.
   3040 			    open_delegation4_u.write.space_limit.
   3041 			    limitby) {
   3042 			case NFS_LIMIT_SIZE:
   3043 				if (!xdr_u_longlong_t(xdrs,
   3044 				    (u_longlong_t *)&objp->delegation.
   3045 				    open_delegation4_u.write.space_limit.
   3046 				    nfs_space_limit4_u.filesize))
   3047 					return (FALSE);
   3048 				break;
   3049 			case NFS_LIMIT_BLOCKS:
   3050 				if (!xdr_u_int(xdrs,
   3051 				    &objp->delegation.open_delegation4_u.write.
   3052 				    space_limit.nfs_space_limit4_u.
   3053 				    mod_blocks.num_blocks))
   3054 					return (FALSE);
   3055 				if (!xdr_u_int(xdrs, &objp->delegation.
   3056 				    open_delegation4_u.write.space_limit.
   3057 				    nfs_space_limit4_u.mod_blocks.
   3058 				    bytes_per_block))
   3059 					return (FALSE);
   3060 				break;
   3061 			default:
   3062 				return (FALSE);
   3063 			}
   3064 			return (xdr_nfsace4(xdrs, &objp->delegation.
   3065 			    open_delegation4_u.write.permissions));
   3066 		}
   3067 		return (FALSE);
   3068 	}
   3069 
   3070 	/*
   3071 	 * Optimized free case
   3072 	 */
   3073 	if (objp->status != NFS4_OK)
   3074 		return (TRUE);
   3075 
   3076 	switch (objp->delegation.delegation_type) {
   3077 	case OPEN_DELEGATE_NONE:
   3078 		return (TRUE);
   3079 	case OPEN_DELEGATE_READ:
   3080 		return (xdr_nfsace4(xdrs, &objp->delegation.
   3081 		    open_delegation4_u.read.permissions));
   3082 	case OPEN_DELEGATE_WRITE:
   3083 		switch (objp->delegation.
   3084 		    open_delegation4_u.write.space_limit.limitby) {
   3085 		case NFS_LIMIT_SIZE:
   3086 		case NFS_LIMIT_BLOCKS:
   3087 			break;
   3088 		default:
   3089 			return (FALSE);
   3090 		}
   3091 		return (xdr_nfsace4(xdrs, &objp->delegation.
   3092 		    open_delegation4_u.write.permissions));
   3093 	}
   3094 	return (FALSE);
   3095 }
   3096 
   3097 static bool_t
   3098 xdr_OPEN_CONFIRM4res(XDR *xdrs, OPEN_CONFIRM4res *objp)
   3099 {
   3100 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   3101 		return (FALSE);
   3102 	if (objp->status != NFS4_OK)
   3103 		return (TRUE);
   3104 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
   3105 		return (FALSE);
   3106 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
   3107 }
   3108 
   3109 static bool_t
   3110 xdr_OPEN_DOWNGRADE4args(XDR *xdrs, OPEN_DOWNGRADE4args *objp)
   3111 {
   3112 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
   3113 		return (FALSE);
   3114 	if (!xdr_opaque(xdrs, objp->open_stateid.other, 12))
   3115 		return (FALSE);
   3116 	if (!xdr_u_int(xdrs, &objp->seqid))
   3117 		return (FALSE);
   3118 	if (!xdr_u_int(xdrs, &objp->share_access))
   3119 		return (FALSE);
   3120 	return (xdr_u_int(xdrs, &objp->share_deny));
   3121 }
   3122 
   3123 static bool_t
   3124 xdr_OPEN_DOWNGRADE4res(XDR *xdrs, OPEN_DOWNGRADE4res *objp)
   3125 {
   3126 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   3127 		return (FALSE);
   3128 	if (objp->status != NFS4_OK)
   3129 		return (TRUE);
   3130 	if (!xdr_u_int(xdrs, &objp->open_stateid.seqid))
   3131 		return (FALSE);
   3132 	return (xdr_opaque(xdrs, objp->open_stateid.other, 12));
   3133 }
   3134 
   3135 static bool_t
   3136 xdr_READ4args(XDR *xdrs, READ4args *objp)
   3137 {
   3138 	rdma_chunkinfo_t rci;
   3139 	rdma_wlist_conn_info_t rwci;
   3140 	struct xdr_ops *xops = xdrrdma_xops();
   3141 
   3142 	if (!xdr_u_int(xdrs, &objp->stateid.seqid))
   3143 		return (FALSE);
   3144 	if (!xdr_opaque(xdrs, objp->stateid.other, 12))
   3145 		return (FALSE);
   3146 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
   3147 		return (FALSE);
   3148 	if (!xdr_u_int(xdrs, &objp->count))
   3149 		return (FALSE);
   3150 
   3151 	DTRACE_PROBE1(xdr__i__read4args_buf_len,
   3152 	    int, objp->count);
   3153 
   3154 	objp->wlist = NULL;
   3155 
   3156 	if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
   3157 		rci.rci_type = RCI_WRITE_ADDR_CHUNK;
   3158 		rci.rci_len = objp->count;
   3159 		(void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
   3160 	}
   3161 
   3162 	if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
   3163 		return (TRUE);
   3164 
   3165 	if (xdrs->x_op == XDR_ENCODE) {
   3166 		if (objp->res_uiop != NULL) {
   3167 			rci.rci_type = RCI_WRITE_UIO_CHUNK;
   3168 			rci.rci_a.rci_uiop = objp->res_uiop;
   3169 			rci.rci_len = objp->count;
   3170 			rci.rci_clpp = &objp->wlist;
   3171 		} else {
   3172 			rci.rci_type = RCI_WRITE_ADDR_CHUNK;
   3173 			rci.rci_a.rci_addr = objp->res_data_val_alt;
   3174 			rci.rci_len = objp->count;
   3175 			rci.rci_clpp = &objp->wlist;
   3176 		}
   3177 
   3178 		return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
   3179 	}
   3180 
   3181 	/* XDR_DECODE case */
   3182 	(void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
   3183 	objp->wlist = rwci.rwci_wlist;
   3184 	objp->conn = rwci.rwci_conn;
   3185 
   3186 	return (TRUE);
   3187 }
   3188 
   3189 static bool_t
   3190 xdr_READ4res(XDR *xdrs, READ4res *objp)
   3191 {
   3192 	int i, rndup;
   3193 	mblk_t *mp;
   3194 
   3195 	if (xdrs->x_op == XDR_DECODE)
   3196 		return (FALSE);
   3197 
   3198 	if (xdrs->x_op == XDR_FREE) {
   3199 		/*
   3200 		 * Optimized free case
   3201 		 */
   3202 		if (objp->status != NFS4_OK)
   3203 			return (TRUE);
   3204 		if (objp->data_val != NULL)
   3205 			kmem_free(objp->data_val, objp->data_len);
   3206 		return (TRUE);
   3207 	}
   3208 
   3209 	/* on with ENCODE paths */
   3210 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->status))
   3211 		return (FALSE);
   3212 	if (objp->status != NFS4_OK)
   3213 		return (TRUE);
   3214 
   3215 	if (!XDR_PUTINT32(xdrs, &objp->eof))
   3216 		return (FALSE);
   3217 
   3218 	mp = objp->mblk;
   3219 	if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
   3220 		mp->b_wptr += objp->data_len;
   3221 		rndup = BYTES_PER_XDR_UNIT -
   3222 		    (objp->data_len % BYTES_PER_XDR_UNIT);
   3223 		if (rndup != BYTES_PER_XDR_UNIT)
   3224 			for (i = 0; i < rndup; i++)
   3225 				*mp->b_wptr++ = '\0';
   3226 		if (xdrmblk_putmblk(xdrs, mp, objp->data_len) == TRUE) {
   3227 			objp->mblk = NULL;
   3228 			return (TRUE);
   3229 		}
   3230 	} else if (mp == NULL) {
   3231 		if (xdr_u_int(xdrs, &objp->data_len) == FALSE) {
   3232 			return (FALSE);
   3233 		}
   3234 		/*
   3235 		 * If read data sent by wlist (RDMA_WRITE), don't do
   3236 		 * xdr_bytes() below.   RDMA_WRITE transfers the data.
   3237 		 * Note: this is encode-only because the client code
   3238 		 * uses xdr_READ4res_clnt to decode results.
   3239 		 */
   3240 		if (objp->wlist) {
   3241 			if (objp->data_len != 0) {
   3242 				return (xdrrdma_send_read_data(
   3243 				    xdrs, objp->data_len, objp->wlist));
   3244 			}
   3245 			return (TRUE);
   3246 		}
   3247 	}
   3248 
   3249 	return (xdr_bytes(xdrs, (char **)&objp->data_val,
   3250 	    (uint_t *)&objp->data_len,
   3251 	    objp->data_len));
   3252 }
   3253 
   3254 static bool_t
   3255 xdr_READ4res_clnt(XDR *xdrs, READ4res *objp, READ4args *aobjp)
   3256 {
   3257 	mblk_t *mp;
   3258 	size_t n;
   3259 	int error;
   3260 	uint_t size = aobjp->res_maxsize;
   3261 	count4 ocount;
   3262 
   3263 	if (xdrs->x_op == XDR_ENCODE)
   3264 		return (FALSE);
   3265 
   3266 	if (xdrs->x_op == XDR_FREE) {
   3267 		/*
   3268 		 * Optimized free case
   3269 		 */
   3270 		if (objp->status != NFS4_OK)
   3271 			return (TRUE);
   3272 		if (objp->data_val != NULL)
   3273 			kmem_free(objp->data_val, objp->data_len);
   3274 		return (TRUE);
   3275 	}
   3276 
   3277 	if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
   3278 		return (FALSE);
   3279 	if (objp->status != NFS4_OK)
   3280 		return (TRUE);
   3281 
   3282 	if (!XDR_GETINT32(xdrs, &objp->eof))
   3283 		return (FALSE);
   3284 
   3285 
   3286 	/*
   3287 	 * This is a special case such that the caller is providing a
   3288 	 * uio as a guide to eventual data location; this is used for
   3289 	 * handling DIRECTIO reads.
   3290 	 */
   3291 	if (aobjp->res_uiop != NULL) {
   3292 		struct uio *uiop = aobjp->res_uiop;
   3293 		int32_t *ptr;
   3294 
   3295 		if (xdrs->x_ops == &xdrmblk_ops) {
   3296 			if (!xdrmblk_getmblk(xdrs, &mp, &objp->data_len))
   3297 				return (FALSE);
   3298 
   3299 			if (objp->data_len == 0)
   3300 				return (TRUE);
   3301 
   3302 			if (objp->data_len > size)
   3303 				return (FALSE);
   3304 
   3305 			size = objp->data_len;
   3306 			do {
   3307 				n = MIN(size, mp->b_wptr - mp->b_rptr);
   3308 				if ((n = MIN(uiop->uio_resid, n)) != 0) {
   3309 
   3310 					error =	uiomove((char *)mp->b_rptr, n,
   3311 					    UIO_READ, uiop);
   3312 					if (error)
   3313 						return (FALSE);
   3314 					mp->b_rptr += n;
   3315 					size -= n;
   3316 				}
   3317 
   3318 				while (mp && (mp->b_rptr >= mp->b_wptr))
   3319 					mp = mp->b_cont;
   3320 			} while (mp && size > 0 && uiop->uio_resid > 0);
   3321 
   3322 			return (TRUE);
   3323 		}
   3324 
   3325 		if (xdrs->x_ops == &xdrrdma_ops) {
   3326 			struct clist *cl;
   3327 
   3328 			XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
   3329 
   3330 			objp->wlist = cl;
   3331 
   3332 			if (objp->wlist) {
   3333 				/* opaque count */
   3334 				if (!xdr_u_int(xdrs, &ocount)) {
   3335 					objp->wlist = NULL;
   3336 					return (FALSE);
   3337 				}
   3338 
   3339 				objp->wlist_len = clist_len(cl);
   3340 				objp->data_len = ocount;
   3341 
   3342 				if (objp->wlist_len !=
   3343 				    roundup(
   3344 				    objp->data_len, BYTES_PER_XDR_UNIT)) {
   3345 					DTRACE_PROBE2(
   3346 					    xdr__e__read4resuio_clnt_fail,
   3347 					    int, ocount,
   3348 					    int, objp->data_len);
   3349 					objp->wlist = NULL;
   3350 					return (FALSE);
   3351 				}
   3352 
   3353 				uiop->uio_resid -= objp->data_len;
   3354 				uiop->uio_iov->iov_len -= objp->data_len;
   3355 				uiop->uio_iov->iov_base += objp->data_len;
   3356 				uiop->uio_loffset += objp->data_len;
   3357 
   3358 				objp->wlist = NULL;
   3359 				return (TRUE);
   3360 			}
   3361 		}
   3362 
   3363 		/*
   3364 		 * This isn't an xdrmblk stream nor RDMA.
   3365 		 * Handle the likely case that it can be
   3366 		 * inlined (ex. xdrmem).
   3367 		 */
   3368 		if (!XDR_GETINT32(xdrs, (int32_t *)&objp->data_len))
   3369 			return (FALSE);
   3370 
   3371 		if (objp->data_len == 0)
   3372 			return (TRUE);
   3373 
   3374 		if (objp->data_len > size)
   3375 			return (FALSE);
   3376 
   3377 		size = (int)objp->data_len;
   3378 		if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
   3379 			return (uiomove(ptr, size, UIO_READ, uiop) ?
   3380 			    FALSE : TRUE);
   3381 
   3382 		/*
   3383 		 * Handle some other (unlikely) stream type that will
   3384 		 * need a copy.
   3385 		 */
   3386 		if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
   3387 			return (FALSE);
   3388 
   3389 		if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
   3390 			kmem_free(ptr, size);
   3391 			return (FALSE);
   3392 		}
   3393 		error = uiomove(ptr, size, UIO_READ, uiop);
   3394 		kmem_free(ptr, size);
   3395 
   3396 		return (error ? FALSE : TRUE);
   3397 	}
   3398 
   3399 	/*
   3400 	 * Check for the other special case of the caller providing
   3401 	 * the target area for the data.
   3402 	 */
   3403 	if (aobjp->res_data_val_alt == NULL)
   3404 		return (FALSE);
   3405 
   3406 	/*
   3407 	 * If read data received via RDMA_WRITE, don't do xdr_bytes().
   3408 	 * RDMA_WRITE already moved the data so decode length of
   3409 	 * RDMA_WRITE.
   3410 	 */
   3411 	if (xdrs->x_ops == &xdrrdma_ops) {
   3412 		struct clist *cl;
   3413 
   3414 		XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
   3415 
   3416 		objp->wlist = cl;
   3417 
   3418 		/*
   3419 		 * Data transferred through inline if
   3420 		 * objp->wlist == NULL
   3421 		 */
   3422 		if (objp->wlist) {
   3423 			/* opaque count */
   3424 			if (!xdr_u_int(xdrs, &ocount)) {
   3425 				objp->wlist = NULL;
   3426 				return (FALSE);
   3427 			}
   3428 
   3429 			objp->wlist_len = clist_len(cl);
   3430 			objp->data_len = ocount;
   3431 
   3432 			if (objp->wlist_len !=
   3433 			    roundup(
   3434 			    objp->data_len, BYTES_PER_XDR_UNIT)) {
   3435 				DTRACE_PROBE2(
   3436 				    xdr__e__read4res_clnt_fail,
   3437 				    int, ocount,
   3438 				    int, objp->data_len);
   3439 				objp->wlist = NULL;
   3440 				return (FALSE);
   3441 			}
   3442 
   3443 			objp->wlist = NULL;
   3444 			return (TRUE);
   3445 		}
   3446 	}
   3447 
   3448 	return (xdr_bytes(xdrs, (char **)&aobjp->res_data_val_alt,
   3449 	    (uint_t *)&objp->data_len,
   3450 	    aobjp->res_maxsize));
   3451 }
   3452 
   3453 static bool_t
   3454 xdr_READDIR4args(XDR *xdrs, READDIR4args *objp)
   3455 {
   3456 	rdma_chunkinfo_t rci;
   3457 	struct xdr_ops *xops = xdrrdma_xops();
   3458 
   3459 	if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
   3460 	    xdrs->x_op == XDR_ENCODE) {
   3461 		rci.rci_type = RCI_REPLY_CHUNK;
   3462 		rci.rci_len = objp->maxcount;
   3463 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
   3464 	}
   3465 
   3466 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookie))
   3467 		return (FALSE);
   3468 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf))
   3469 		return (FALSE);
   3470 	if (!xdr_u_int(xdrs, &objp->dircount))
   3471 		return (FALSE);
   3472 	if (!xdr_u_int(xdrs, &objp->maxcount))
   3473 		return (FALSE);
   3474 	return (xdr_bitmap4(xdrs, &objp->attr_request));
   3475 }
   3476 
   3477 /* ARGSUSED */
   3478 static bool_t
   3479 xdrmblk_putmblk_rd(XDR *xdrs, mblk_t *m)
   3480 {
   3481 	if (((m->b_wptr - m->b_rptr) % BYTES_PER_XDR_UNIT) != 0)
   3482 		return (FALSE);
   3483 
   3484 	/* LINTED pointer alignment */
   3485 	((mblk_t *)xdrs->x_base)->b_cont = m;
   3486 	xdrs->x_base = (caddr_t)m;
   3487 	xdrs->x_handy = 0;
   3488 	return (TRUE);
   3489 }
   3490 
   3491 bool_t
   3492 xdr_READDIR4res(XDR *xdrs, READDIR4res *objp)
   3493 {
   3494 	mblk_t *mp = objp->mblk;
   3495 	bool_t ret_val;
   3496 	uint_t flags = 0;
   3497 
   3498 	ASSERT(xdrs->x_op == XDR_ENCODE);
   3499 
   3500 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   3501 		return (FALSE);
   3502 	if (objp->status != NFS4_OK)
   3503 		return (TRUE);
   3504 	if (mp == NULL)
   3505 		return (FALSE);
   3506 
   3507 	if (xdrs->x_ops == &xdrmblk_ops) {
   3508 		if (xdrmblk_putmblk_rd(xdrs, mp)
   3509 		    == TRUE) {
   3510 			/* mblk successfully inserted into outgoing chain */
   3511 			objp->mblk = NULL;
   3512 			return (TRUE);
   3513 		}
   3514 	}
   3515 
   3516 	ASSERT(mp->b_cont == NULL);
   3517 
   3518 	/*
   3519 	 * If transport is RDMA, the pre-encoded m_blk needs to be moved
   3520 	 * without being chunked.
   3521 	 * Check if chunking is enabled for the xdr stream.
   3522 	 * If it is enabled, disable it temporarily for this op,
   3523 	 * then re-enable.
   3524 	 */
   3525 	XDR_CONTROL(xdrs, XDR_RDMA_GET_FLAGS, &flags);
   3526 
   3527 	if (!(flags & XDR_RDMA_CHUNK))
   3528 		return (xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len));
   3529 
   3530 	flags &= ~XDR_RDMA_CHUNK;
   3531 
   3532 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
   3533 
   3534 	ret_val = xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len);
   3535 
   3536 	flags |= XDR_RDMA_CHUNK;
   3537 
   3538 	(void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags);
   3539 
   3540 	return (ret_val);
   3541 }
   3542 
   3543 static bool_t
   3544 xdr_READLINK4res(XDR *xdrs, READLINK4res *objp)
   3545 {
   3546 	if (xdrs->x_op != XDR_FREE) {
   3547 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
   3548 			return (FALSE);
   3549 		if (objp->status != NFS4_OK)
   3550 			return (TRUE);
   3551 		return (xdr_bytes(xdrs, (char **)&objp->link.utf8string_val,
   3552 		    (uint_t *)&objp->link.utf8string_len,
   3553 		    NFS4_MAX_UTF8STRING));
   3554 	}
   3555 
   3556 	/*
   3557 	 * Optimized free case
   3558 	 */
   3559 	if (objp->status != NFS4_OK)
   3560 		return (TRUE);
   3561 	if (objp->link.utf8string_val != NULL)
   3562 		kmem_free(objp->link.utf8string_val, objp->link.utf8string_len);
   3563 	return (TRUE);
   3564 }
   3565 
   3566 static bool_t
   3567 xdr_REMOVE4res(XDR *xdrs, REMOVE4res *objp)
   3568 {
   3569 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   3570 		return (FALSE);
   3571 	if (objp->status != NFS4_OK)
   3572 		return (TRUE);
   3573 	if (!xdr_bool(xdrs, &objp->cinfo.atomic))
   3574 		return (FALSE);
   3575 	if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before))
   3576 		return (FALSE);
   3577 	return (xdr_u_longlong_t(xdrs,
   3578 	    (u_longlong_t *)&objp->cinfo.after));
   3579 }
   3580 
   3581 static bool_t
   3582 xdr_RENAME4res(XDR *xdrs, RENAME4res *objp)
   3583 {
   3584 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   3585 		return (FALSE);
   3586 	if (objp->status != NFS4_OK)
   3587 		return (TRUE);
   3588 	if (!xdr_bool(xdrs, &objp->source_cinfo.atomic))
   3589 		return (FALSE);
   3590 	if (!xdr_u_longlong_t(xdrs,
   3591 	    (u_longlong_t *)&objp->source_cinfo.before))
   3592 		return (FALSE);
   3593 	if (!xdr_u_longlong_t(xdrs,
   3594 	    (u_longlong_t *)&objp->source_cinfo.after))
   3595 		return (FALSE);
   3596 	if (!xdr_bool(xdrs, &objp->target_cinfo.atomic))
   3597 		return (FALSE);
   3598 	if (!xdr_u_longlong_t(xdrs,
   3599 	    (u_longlong_t *)&objp->target_cinfo.before))
   3600 		return (FALSE);
   3601 	return (xdr_u_longlong_t(xdrs,
   3602 	    (u_longlong_t *)&objp->target_cinfo.after));
   3603 }
   3604 
   3605 static bool_t
   3606 xdr_secinfo4(XDR *xdrs, secinfo4 *objp)
   3607 {
   3608 	if (xdrs->x_op != XDR_FREE) {
   3609 		if (!xdr_u_int(xdrs, &objp->flavor))
   3610 			return (FALSE);
   3611 		if (objp->flavor != RPCSEC_GSS)
   3612 			return (TRUE);
   3613 		if (!xdr_bytes(xdrs,
   3614 		    (char **)&objp->flavor_info.oid.sec_oid4_val,
   3615 		    (uint_t *)&objp->flavor_info.oid.sec_oid4_len,
   3616 		    NFS4_MAX_SECOID4))
   3617 			return (FALSE);
   3618 		if (!xdr_u_int(xdrs, &objp->flavor_info.qop))
   3619 			return (FALSE);
   3620 		return (xdr_int(xdrs, (int *)&objp->flavor_info.service));
   3621 	}
   3622 
   3623 	/*
   3624 	 * Optimized free path
   3625 	 */
   3626 	if (objp->flavor != RPCSEC_GSS)
   3627 		return (TRUE);
   3628 
   3629 	if (objp->flavor_info.oid.sec_oid4_val != NULL)
   3630 		kmem_free(objp->flavor_info.oid.sec_oid4_val,
   3631 		    objp->flavor_info.oid.sec_oid4_len);
   3632 	return (TRUE);
   3633 }
   3634 
   3635 static bool_t
   3636 xdr_SETCLIENTID4args(XDR *xdrs, SETCLIENTID4args *objp)
   3637 {
   3638 	if (xdrs->x_op != XDR_FREE) {
   3639 		if (!xdr_u_longlong_t(xdrs,
   3640 		    (u_longlong_t *)&objp->client.verifier))
   3641 			return (FALSE);
   3642 		if (!xdr_bytes(xdrs, (char **)&objp->client.id_val,
   3643 		    (uint_t *)&objp->client.id_len, NFS4_OPAQUE_LIMIT))
   3644 			return (FALSE);
   3645 		if (!xdr_u_int(xdrs, &objp->callback.cb_program))
   3646 			return (FALSE);
   3647 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_netid,
   3648 		    NFS4_OPAQUE_LIMIT))
   3649 			return (FALSE);
   3650 		if (!xdr_string(xdrs, &objp->callback.cb_location.r_addr,
   3651 		    NFS4_OPAQUE_LIMIT))
   3652 			return (FALSE);
   3653 		return (xdr_u_int(xdrs, &objp->callback_ident));
   3654 	}
   3655 
   3656 	/*
   3657 	 * Optimized free case
   3658 	 */
   3659 	if (objp->client.id_val != NULL)
   3660 		kmem_free(objp->client.id_val, objp->client.id_len);
   3661 	(void) xdr_string(xdrs, &objp->callback.cb_location.r_netid,
   3662 	    NFS4_OPAQUE_LIMIT);
   3663 	return (xdr_string(xdrs, &objp->callback.cb_location.r_addr,
   3664 	    NFS4_OPAQUE_LIMIT));
   3665 }
   3666 
   3667 static bool_t
   3668 xdr_SETCLIENTID4res(XDR *xdrs, SETCLIENTID4res *objp)
   3669 {
   3670 	if (xdrs->x_op != XDR_FREE) {
   3671 		if (!xdr_int(xdrs, (int32_t *)&objp->status))
   3672 			return (FALSE);
   3673 		switch (objp->status) {
   3674 		case NFS4_OK:
   3675 			if (!xdr_u_longlong_t(xdrs,
   3676 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.resok4.
   3677 			    clientid))
   3678 				return (FALSE);
   3679 			return (xdr_u_longlong_t(xdrs,
   3680 			    (u_longlong_t *)&objp->SETCLIENTID4res_u.
   3681 			    resok4.setclientid_confirm));
   3682 		case NFS4ERR_CLID_INUSE:
   3683 			if (!xdr_string(xdrs,
   3684 			    &objp->SETCLIENTID4res_u.client_using.
   3685 			    r_netid, NFS4_OPAQUE_LIMIT))
   3686 				return (FALSE);
   3687 			return (xdr_string(xdrs,
   3688 			    &objp->SETCLIENTID4res_u.client_using.
   3689 			    r_addr, NFS4_OPAQUE_LIMIT));
   3690 		}
   3691 		return (TRUE);
   3692 	}
   3693 
   3694 	/*
   3695 	 * Optimized free case
   3696 	 */
   3697 	if (objp->status != NFS4ERR_CLID_INUSE)
   3698 		return (TRUE);
   3699 
   3700 	if (!xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_netid,
   3701 	    NFS4_OPAQUE_LIMIT))
   3702 		return (FALSE);
   3703 	return (xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_addr,
   3704 	    NFS4_OPAQUE_LIMIT));
   3705 }
   3706 
   3707 static bool_t
   3708 xdr_WRITE4args(XDR *xdrs, WRITE4args *objp)
   3709 {
   3710 	if (xdrs->x_op != XDR_FREE) {
   3711 		if (!xdr_u_int(xdrs, &objp->stateid.seqid))
   3712 			return (FALSE);
   3713 		if (!xdr_opaque(xdrs, objp->stateid.other, 12))
   3714 			return (FALSE);
   3715 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset))
   3716 			return (FALSE);
   3717 		if (!xdr_int(xdrs, (int *)&objp->stable))
   3718 			return (FALSE);
   3719 		if (xdrs->x_op == XDR_DECODE) {
   3720 			if (xdrs->x_ops == &xdrmblk_ops) {
   3721 				objp->data_val = NULL;
   3722 				return (xdrmblk_getmblk(xdrs, &objp->mblk,
   3723 				    &objp->data_len));
   3724 			}
   3725 			objp->mblk = NULL;
   3726 			if (xdrs->x_ops == &xdrrdmablk_ops) {
   3727 				int retval;
   3728 				retval = xdrrdma_getrdmablk(xdrs,
   3729 				    &objp->rlist,
   3730 				    &objp->data_len,
   3731 				    &objp->conn, NFS4_DATA_LIMIT);
   3732 				if (retval == FALSE)
   3733 					return (FALSE);
   3734 				return (xdrrdma_read_from_client(objp->rlist,
   3735 				    &objp->conn, objp->data_len));
   3736 			}
   3737 		}
   3738 		/* Else fall thru for the xdr_bytes(). */
   3739 		return (xdr_bytes(xdrs, (char **)&objp->data_val,
   3740 		    (uint_t *)&objp->data_len, NFS4_DATA_LIMIT));
   3741 	}
   3742 	if (objp->rlist != NULL) {
   3743 		(void) xdrrdma_free_clist(objp->conn, objp->rlist);
   3744 		objp->rlist = NULL;
   3745 		objp->data_val = NULL;
   3746 
   3747 		return (TRUE);
   3748 	}
   3749 
   3750 	/*
   3751 	 * Optimized free case
   3752 	 */
   3753 	if (objp->data_val != NULL)
   3754 		kmem_free(objp->data_val, objp->data_len);
   3755 	return (TRUE);
   3756 }
   3757 
   3758 static bool_t
   3759 xdr_WRITE4res(XDR *xdrs, WRITE4res *objp)
   3760 {
   3761 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   3762 		return (FALSE);
   3763 	if (objp->status != NFS4_OK)
   3764 		return (TRUE);
   3765 	if (!xdr_u_int(xdrs, &objp->count))
   3766 		return (FALSE);
   3767 	if (!xdr_int(xdrs, (int *)&objp->committed))
   3768 		return (FALSE);
   3769 	return (xdr_u_longlong_t(xdrs,
   3770 	    (u_longlong_t *)&objp->writeverf));
   3771 }
   3772 
   3773 static bool_t
   3774 xdr_snfs_argop4_free(XDR *xdrs, nfs_argop4 **arrayp, int len)
   3775 {
   3776 	int i;
   3777 	nfs_argop4 *array = *arrayp;
   3778 
   3779 	/*
   3780 	 * Optimized XDR_FREE only args array
   3781 	 */
   3782 	ASSERT(xdrs->x_op == XDR_FREE);
   3783 
   3784 	/*
   3785 	 * Nothing to do?
   3786 	 */
   3787 	if (array == NULL)
   3788 		return (TRUE);
   3789 
   3790 	for (i = 0; i < len; i++) {
   3791 		/*
   3792 		 * These should be ordered by frequency of use
   3793 		 */
   3794 		switch (array[i].argop) {
   3795 		case OP_PUTFH:
   3796 			if (array[i].nfs_argop4_u.opputfh.object.nfs_fh4_val !=
   3797 			    NULL) {
   3798 				kmem_free(array[i].nfs_argop4_u.opputfh.object.
   3799 				    nfs_fh4_val,
   3800 				    array[i].nfs_argop4_u.opputfh.object.
   3801 				    nfs_fh4_len);
   3802 			}
   3803 			continue;
   3804 		case OP_GETATTR:
   3805 		case OP_GETFH:
   3806 			continue;
   3807 		case OP_LOOKUP:
   3808 			if (array[i].nfs_argop4_u.oplookup.objname.
   3809 			    utf8string_val != NULL) {
   3810 				kmem_free(array[i].nfs_argop4_u.oplookup.
   3811 				    objname.utf8string_val,
   3812 				    array[i].nfs_argop4_u.oplookup.
   3813 				    objname.utf8string_len);
   3814 			}
   3815 			continue;
   3816 		case OP_OPEN:
   3817 			(void) xdr_OPEN4args(xdrs,
   3818 			    &array[i].nfs_argop4_u.opopen);
   3819 			continue;
   3820 		case OP_CLOSE:
   3821 		case OP_ACCESS:
   3822 		case OP_READ:
   3823 			continue;
   3824 		case OP_WRITE:
   3825 			(void) xdr_WRITE4args(xdrs,
   3826 			    &array[i].nfs_argop4_u.opwrite);
   3827 			continue;
   3828 		case OP_DELEGRETURN:
   3829 		case OP_LOOKUPP:
   3830 		case OP_READDIR:
   3831 			continue;
   3832 		case OP_REMOVE:
   3833 			if (array[i].nfs_argop4_u.opremove.target.
   3834 			    utf8string_val != NULL) {
   3835 				kmem_free(array[i].nfs_argop4_u.opremove.target.
   3836 				    utf8string_val,
   3837 				    array[i].nfs_argop4_u.opremove.target.
   3838 				    utf8string_len);
   3839 			}
   3840 			continue;
   3841 		case OP_COMMIT:
   3842 			continue;
   3843 		case OP_CREATE:
   3844 			(void) xdr_CREATE4args(xdrs,
   3845 			    &array[i].nfs_argop4_u.opcreate);
   3846 			continue;
   3847 		case OP_DELEGPURGE:
   3848 			continue;
   3849 		case OP_LINK:
   3850 			if (array[i].nfs_argop4_u.oplink.newname.
   3851 			    utf8string_val != NULL) {
   3852 				kmem_free(array[i].nfs_argop4_u.oplink.newname.
   3853 				    utf8string_val,
   3854 				    array[i].nfs_argop4_u.oplink.newname.
   3855 				    utf8string_len);
   3856 			}
   3857 			continue;
   3858 		case OP_LOCK:
   3859 			(void) xdr_LOCK4args(xdrs,
   3860 			    &array[i].nfs_argop4_u.oplock);
   3861 			continue;
   3862 		case OP_LOCKT:
   3863 			(void) xdr_LOCKT4args(xdrs,
   3864 			    &array[i].nfs_argop4_u.oplockt);
   3865 			continue;
   3866 		case OP_LOCKU:
   3867 			continue;
   3868 		case OP_NVERIFY:
   3869 			(void) xdr_fattr4(xdrs,
   3870 			    &array[i].nfs_argop4_u.opnverify.obj_attributes);
   3871 			continue;
   3872 		case OP_OPENATTR:
   3873 		case OP_OPEN_CONFIRM:
   3874 		case OP_OPEN_DOWNGRADE:
   3875 		case OP_PUTPUBFH:
   3876 		case OP_PUTROOTFH:
   3877 		case OP_READLINK:
   3878 			continue;
   3879 		case OP_RENAME:
   3880 			if (array[i].nfs_argop4_u.oprename.oldname.
   3881 			    utf8string_val != NULL) {
   3882 				kmem_free(array[i].nfs_argop4_u.oprename.
   3883 				    oldname.utf8string_val,
   3884 				    array[i].nfs_argop4_u.oprename.
   3885 				    oldname.utf8string_len);
   3886 			}
   3887 			if (array[i].nfs_argop4_u.oprename.newname.
   3888 			    utf8string_val != NULL) {
   3889 				kmem_free(array[i].nfs_argop4_u.oprename.
   3890 				    newname.utf8string_val,
   3891 				    array[i].nfs_argop4_u.oprename.
   3892 				    newname.utf8string_len);
   3893 			}
   3894 			continue;
   3895 		case OP_RENEW:
   3896 		case OP_RESTOREFH:
   3897 		case OP_SAVEFH:
   3898 			continue;
   3899 		case OP_SECINFO:
   3900 			if (array[i].nfs_argop4_u.opsecinfo.name.
   3901 			    utf8string_val != NULL) {
   3902 				kmem_free(array[i].nfs_argop4_u.opsecinfo.name.
   3903 				    utf8string_val,
   3904 				    array[i].nfs_argop4_u.opsecinfo.name.
   3905 				    utf8string_len);
   3906 			}
   3907 			continue;
   3908 		case OP_SETATTR:
   3909 			(void) xdr_fattr4(xdrs,
   3910 			    &array[i].nfs_argop4_u.opsetattr.obj_attributes);
   3911 			continue;
   3912 		case OP_SETCLIENTID:
   3913 			(void) xdr_SETCLIENTID4args(xdrs,
   3914 			    &array[i].nfs_argop4_u.opsetclientid);
   3915 			continue;
   3916 		case OP_SETCLIENTID_CONFIRM:
   3917 			continue;
   3918 		case OP_VERIFY:
   3919 			(void) xdr_fattr4(xdrs,
   3920 			    &array[i].nfs_argop4_u.opverify.obj_attributes);
   3921 			continue;
   3922 		case OP_RELEASE_LOCKOWNER:
   3923 			if (array[i].nfs_argop4_u.oprelease_lockowner.
   3924 			    lock_owner.owner_val != NULL) {
   3925 				kmem_free(array[i].nfs_argop4_u.
   3926 				    oprelease_lockowner.lock_owner.owner_val,
   3927 				    array[i].nfs_argop4_u.
   3928 				    oprelease_lockowner.lock_owner.owner_len);
   3929 			}
   3930 			continue;
   3931 		case OP_ILLEGAL:
   3932 			continue;
   3933 		default:
   3934 			/*
   3935 			 * An invalid op is a coding error, it should never
   3936 			 * have been decoded.
   3937 			 * Don't error because the caller cannot finish
   3938 			 * freeing the residual memory of the array.
   3939 			 */
   3940 			continue;
   3941 		}
   3942 	}
   3943 
   3944 	kmem_free(*arrayp, len * sizeof (nfs_argop4));
   3945 	*arrayp = NULL;
   3946 	return (TRUE);
   3947 }
   3948 
   3949 static bool_t
   3950 xdr_nfs_argop4(XDR *xdrs, nfs_argop4 *objp)
   3951 {
   3952 	rdma_chunkinfo_t rci;
   3953 	struct xdr_ops *xops = xdrrdma_xops();
   3954 
   3955 	/*
   3956 	 * These should be ordered by frequency of use
   3957 	 */
   3958 	switch (objp->argop) {
   3959 	case OP_PUTFH:
   3960 		return (xdr_bytes(xdrs,
   3961 		    (char **)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_val,
   3962 		    (uint_t *)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_len,
   3963 		    NFS4_FHSIZE));
   3964 	case OP_GETATTR:
   3965 		return (xdr_bitmap4(xdrs,
   3966 		    &objp->nfs_argop4_u.opgetattr.attr_request));
   3967 	case OP_GETFH:
   3968 		return (TRUE);
   3969 	case OP_LOOKUP:
   3970 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oplookup.
   3971 		    objname.utf8string_val,
   3972 		    (uint_t *)&objp->nfs_argop4_u.oplookup.
   3973 		    objname.utf8string_len,
   3974 		    NFS4_MAX_UTF8STRING));
   3975 	case OP_OPEN:
   3976 		return (xdr_OPEN4args(xdrs, &objp->nfs_argop4_u.opopen));
   3977 	case OP_CLOSE:
   3978 		return (xdr_CLOSE4args(xdrs, &objp->nfs_argop4_u.opclose));
   3979 	case OP_ACCESS:
   3980 		return (xdr_u_int(xdrs,
   3981 		    &objp->nfs_argop4_u.opaccess.access));
   3982 	case OP_READ:
   3983 		return (xdr_READ4args(xdrs, &objp->nfs_argop4_u.opread));
   3984 	case OP_WRITE:
   3985 		return (xdr_WRITE4args(xdrs, &objp->nfs_argop4_u.opwrite));
   3986 	case OP_DELEGRETURN:
   3987 		if (!xdr_u_int(xdrs,
   3988 		    &objp->nfs_argop4_u.opdelegreturn.deleg_stateid.seqid))
   3989 			return (FALSE);
   3990 		return (xdr_opaque(xdrs,
   3991 		    objp->nfs_argop4_u.opdelegreturn.deleg_stateid.other, 12));
   3992 	case OP_LOOKUPP:
   3993 		return (TRUE);
   3994 	case OP_READDIR:
   3995 		return (xdr_READDIR4args(xdrs, &objp->nfs_argop4_u.opreaddir));
   3996 	case OP_REMOVE:
   3997 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.opremove.
   3998 		    target.utf8string_val,
   3999 		    (uint_t *)&objp->nfs_argop4_u.opremove.
   4000 		    target.utf8string_len,
   4001 		    NFS4_MAX_UTF8STRING));
   4002 	case OP_COMMIT:
   4003 		if (!xdr_u_longlong_t(xdrs,
   4004 		    (u_longlong_t *)&objp->nfs_argop4_u.opcommit.offset))
   4005 			return (FALSE);
   4006 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opcommit.count));
   4007 	case OP_CREATE:
   4008 		return (xdr_CREATE4args(xdrs, &objp->nfs_argop4_u.opcreate));
   4009 	case OP_DELEGPURGE:
   4010 		return (xdr_u_longlong_t(xdrs,
   4011 		    (u_longlong_t *)&objp->nfs_argop4_u.opdelegpurge.clientid));
   4012 	case OP_LINK:
   4013 		return (xdr_bytes(xdrs,
   4014 		    (char **)&objp->nfs_argop4_u.oplink.newname.utf8string_val,
   4015 		    (uint_t *)&objp->nfs_argop4_u.oplink.newname.utf8string_len,
   4016 		    NFS4_MAX_UTF8STRING));
   4017 	case OP_LOCK:
   4018 		return (xdr_LOCK4args(xdrs, &objp->nfs_argop4_u.oplock));
   4019 	case OP_LOCKT:
   4020 		return (xdr_LOCKT4args(xdrs, &objp->nfs_argop4_u.oplockt));
   4021 	case OP_LOCKU:
   4022 		return (xdr_LOCKU4args(xdrs, &objp->nfs_argop4_u.oplocku));
   4023 	case OP_NVERIFY:
   4024 		return (xdr_fattr4(xdrs,
   4025 		    &objp->nfs_argop4_u.opnverify.obj_attributes));
   4026 	case OP_OPENATTR:
   4027 		return (xdr_bool(xdrs,
   4028 		    &objp->nfs_argop4_u.opopenattr.createdir));
   4029 	case OP_OPEN_CONFIRM:
   4030 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
   4031 		    open_stateid.seqid))
   4032 			return (FALSE);
   4033 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opopen_confirm.
   4034 		    open_stateid.other, 12))
   4035 			return (FALSE);
   4036 		return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm.
   4037 		    seqid));
   4038 	case OP_OPEN_DOWNGRADE:
   4039 		return (xdr_OPEN_DOWNGRADE4args(xdrs,
   4040 		    &objp->nfs_argop4_u.opopen_downgrade));
   4041 	case OP_PUTPUBFH:
   4042 		return (TRUE);
   4043 	case OP_PUTROOTFH:
   4044 		return (TRUE);
   4045 	case OP_READLINK:
   4046 		if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
   4047 		    xdrs->x_op == XDR_ENCODE) {
   4048 			rci.rci_type = RCI_REPLY_CHUNK;
   4049 			rci.rci_len = MAXPATHLEN;
   4050 			XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
   4051 		}
   4052 		return (TRUE);
   4053 	case OP_RENAME:
   4054 		if (!xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
   4055 		    oldname.utf8string_val,
   4056 		    (uint_t *)&objp->nfs_argop4_u.oprename.
   4057 		    oldname.utf8string_len,
   4058 		    NFS4_MAX_UTF8STRING))
   4059 			return (FALSE);
   4060 		return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename.
   4061 		    newname.utf8string_val,
   4062 		    (uint_t *)&objp->nfs_argop4_u.oprename.
   4063 		    newname.utf8string_len,
   4064 		    NFS4_MAX_UTF8STRING));
   4065 	case OP_RENEW:
   4066 		return (xdr_u_longlong_t(xdrs,
   4067 		    (u_longlong_t *)&objp->nfs_argop4_u.oprenew.clientid));
   4068 	case OP_RESTOREFH:
   4069 		return (TRUE);
   4070 	case OP_SAVEFH:
   4071 		return (TRUE);
   4072 	case OP_SECINFO:
   4073 		return (xdr_bytes(xdrs,
   4074 		    (char **)&objp->nfs_argop4_u.opsecinfo.name.utf8string_val,
   4075 		    (uint_t *)&objp->nfs_argop4_u.opsecinfo.name.utf8string_len,
   4076 		    NFS4_MAX_UTF8STRING));
   4077 	case OP_SETATTR:
   4078 		if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opsetattr.
   4079 		    stateid.seqid))
   4080 			return (FALSE);
   4081 		if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opsetattr.
   4082 		    stateid.other, 12))
   4083 			return (FALSE);
   4084 		return (xdr_fattr4(xdrs, &objp->nfs_argop4_u.opsetattr.
   4085 		    obj_attributes));
   4086 	case OP_SETCLIENTID:
   4087 		return (xdr_SETCLIENTID4args(xdrs,
   4088 		    &objp->nfs_argop4_u.opsetclientid));
   4089 	case OP_SETCLIENTID_CONFIRM:
   4090 		if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->nfs_argop4_u.
   4091 		    opsetclientid_confirm.clientid))
   4092 			return (FALSE);
   4093 		return (xdr_u_longlong_t(xdrs,
   4094 		    (u_longlong_t *)&objp->nfs_argop4_u.
   4095 		    opsetclientid_confirm.setclientid_confirm));
   4096 	case OP_VERIFY:
   4097 		return (xdr_fattr4(xdrs,
   4098 		    &objp->nfs_argop4_u.opverify.obj_attributes));
   4099 	case OP_RELEASE_LOCKOWNER:
   4100 		if (!xdr_u_longlong_t(xdrs,
   4101 		    (u_longlong_t *)&objp->nfs_argop4_u.
   4102 		    oprelease_lockowner.lock_owner.clientid))
   4103 			return (FALSE);
   4104 		return (xdr_bytes(xdrs,
   4105 		    (char **)&objp->nfs_argop4_u.oprelease_lockowner.
   4106 		    lock_owner.owner_val,
   4107 		    (uint_t *)&objp->nfs_argop4_u.oprelease_lockowner.
   4108 		    lock_owner.owner_len, NFS4_OPAQUE_LIMIT));
   4109 	case OP_ILLEGAL:
   4110 		return (TRUE);
   4111 	}
   4112 	return (FALSE);
   4113 }
   4114 
   4115 static bool_t
   4116 xdr_cnfs_argop4_wrap(XDR *xdrs, nfs_argop4 *objp)
   4117 {
   4118 	if (!xdr_int(xdrs, (int *)&objp->argop))
   4119 		return (FALSE);
   4120 
   4121 	return (xdr_nfs_argop4(xdrs, objp));
   4122 }
   4123 
   4124 static bool_t
   4125 xdr_snfs_argop4(XDR *xdrs, nfs_argop4 *objp)
   4126 {
   4127 	if (!xdr_int(xdrs, (int *)&objp->argop))
   4128 		return (FALSE);
   4129 
   4130 	switch (objp->argop) {
   4131 	case OP_PUTFH:
   4132 		return (xdr_decode_nfs_fh4(xdrs,
   4133 		    &objp->nfs_argop4_u.opputfh.object));
   4134 	default:
   4135 		return (xdr_nfs_argop4(xdrs, objp));
   4136 	}
   4137 }
   4138 
   4139 /*
   4140  * Client side encode only arg op processing
   4141  */
   4142 static bool_t
   4143 xdr_cnfs_argop4(XDR *xdrs, nfs_argop4 *objp)
   4144 {
   4145 	int len;
   4146 	int op;
   4147 	nfs4_sharedfh_t *sfh;
   4148 	mntinfo4_t *mi;
   4149 	rpc_inline_t *ptr;
   4150 
   4151 	ASSERT(xdrs->x_op == XDR_ENCODE);
   4152 
   4153 	/*
   4154 	 * Special case the private pseudo ops
   4155 	 */
   4156 	if (!(objp->argop & SUNW_PRIVATE_OP))
   4157 		return (xdr_cnfs_argop4_wrap(xdrs, objp));
   4158 
   4159 	/*
   4160 	 * These should be ordered by frequency of use
   4161 	 */
   4162 	switch (objp->argop) {
   4163 	case OP_CPUTFH:
   4164 		/*
   4165 		 * We are passed in the file handle as a nfs4_sharedfh_t *
   4166 		 * We need to acquire the correct locks so we can copy it out.
   4167 		 */
   4168 		sfh = (nfs4_sharedfh_t *)objp->nfs_argop4_u.opcputfh.sfh;
   4169 		mi = sfh->sfh_mi;
   4170 		(void) nfs_rw_enter_sig(&mi->mi_fh_lock, RW_READER, 0);
   4171 
   4172 		len = sfh->sfh_fh.nfs_fh4_len;
   4173 		ASSERT(len <= NFS4_FHSIZE);
   4174 
   4175 		/*
   4176 		 * First try and inline the copy
   4177 		 * Must first be a multiple of BYTES_PER_XDR_UNIT
   4178 		 */
   4179 		if (!(len % BYTES_PER_XDR_UNIT) &&
   4180 		    (ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + len)) !=
   4181 		    NULL) {
   4182 			IXDR_PUT_U_INT32(ptr, OP_PUTFH);
   4183 			IXDR_PUT_U_INT32(ptr, len);
   4184 			bcopy(sfh->sfh_fh.nfs_fh4_val, ptr, len);
   4185 			nfs_rw_exit(&mi->mi_fh_lock);
   4186 			return (TRUE);
   4187 		}
   4188 
   4189 		op = OP_PUTFH;
   4190 		if (!XDR_PUTINT32(xdrs, &op)) {
   4191 			nfs_rw_exit(&mi->mi_fh_lock);
   4192 			return (FALSE);
   4193 		}
   4194 		if (!XDR_PUTINT32(xdrs, &len)) {
   4195 			nfs_rw_exit(&mi->mi_fh_lock);
   4196 			return (FALSE);
   4197 		}
   4198 		if (!(len % BYTES_PER_XDR_UNIT)) {
   4199 			if (XDR_PUTBYTES(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
   4200 				nfs_rw_exit(&mi->mi_fh_lock);
   4201 				return (TRUE);
   4202 			}
   4203 		} else if (xdr_opaque(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) {
   4204 			nfs_rw_exit(&mi->mi_fh_lock);
   4205 			return (TRUE);
   4206 		}
   4207 		nfs_rw_exit(&mi->mi_fh_lock);
   4208 		return (FALSE);
   4209 	case OP_CLOOKUP:
   4210 		len = strlen(objp->nfs_argop4_u.opclookup.cname);
   4211 		if (len > NFS4_MAX_UTF8STRING)
   4212 			return (FALSE);
   4213 		op = OP_LOOKUP;
   4214 		if (XDR_PUTINT32(xdrs, &op)) {
   4215 			if (XDR_PUTINT32(xdrs, &len)) {
   4216 				return (xdr_opaque(xdrs,
   4217 				    objp->nfs_argop4_u.opclookup.cname,
   4218 				    len));
   4219 			}
   4220 		}
   4221 		return (FALSE);
   4222 	case OP_COPEN:
   4223 		/* op processing inlined in xdr_OPEN4cargs */
   4224 		return (xdr_OPEN4cargs(xdrs, &objp->nfs_argop4_u.opcopen));
   4225 	case OP_CREMOVE:
   4226 		len = strlen(objp->nfs_argop4_u.opcremove.ctarget);
   4227 		if (len > NFS4_MAX_UTF8STRING)
   4228 			return (FALSE);
   4229 		op = OP_REMOVE;
   4230 		if (XDR_PUTINT32(xdrs, &op)) {
   4231 			if (XDR_PUTINT32(xdrs, &len)) {
   4232 				return (xdr_opaque(xdrs,
   4233 				    objp->nfs_argop4_u.opcremove.ctarget,
   4234 				    len));
   4235 			}
   4236 		}
   4237 		return (FALSE);
   4238 	case OP_CCREATE:
   4239 		op = OP_CREATE;
   4240 		if (!XDR_PUTINT32(xdrs, &op))
   4241 			return (FALSE);
   4242 		return (xdr_CREATE4cargs(xdrs, &objp->nfs_argop4_u.opccreate));
   4243 	case OP_CLINK:
   4244 		len = strlen(objp->nfs_argop4_u.opclink.cnewname);
   4245 		if (len > NFS4_MAX_UTF8STRING)
   4246 			return (FALSE);
   4247 		op = OP_LINK;
   4248 		if (XDR_PUTINT32(xdrs, &op)) {
   4249 			if (XDR_PUTINT32(xdrs, &len)) {
   4250 				return (xdr_opaque(xdrs,
   4251 				    objp->nfs_argop4_u.opclink.cnewname,
   4252 				    len));
   4253 			}
   4254 		}
   4255 		return (FALSE);
   4256 	case OP_CRENAME:
   4257 		len = strlen(objp->nfs_argop4_u.opcrename.coldname);
   4258 		if (len > NFS4_MAX_UTF8STRING)
   4259 			return (FALSE);
   4260 		op = OP_RENAME;
   4261 		if (!XDR_PUTINT32(xdrs, &op))
   4262 			return (FALSE);
   4263 		if (!XDR_PUTINT32(xdrs, &len))
   4264 			return (FALSE);
   4265 		if (!xdr_opaque(xdrs,
   4266 		    objp->nfs_argop4_u.opcrename.coldname, len))
   4267 			return (FALSE);
   4268 		len = strlen(objp->nfs_argop4_u.opcrename.cnewname);
   4269 		if (len > NFS4_MAX_UTF8STRING)
   4270 			return (FALSE);
   4271 		if (XDR_PUTINT32(xdrs, &len)) {
   4272 			return (xdr_opaque(xdrs,
   4273 			    objp->nfs_argop4_u.opcrename.cnewname, len));
   4274 		}
   4275 		return (FALSE);
   4276 	case OP_CSECINFO:
   4277 		len = strlen(objp->nfs_argop4_u.opcsecinfo.cname);
   4278 		if (len > NFS4_MAX_UTF8STRING)
   4279 			return (FALSE);
   4280 		op = OP_SECINFO;
   4281 		if (XDR_PUTINT32(xdrs, &op)) {
   4282 			if (XDR_PUTINT32(xdrs, &len)) {
   4283 				return (xdr_opaque(xdrs,
   4284 				    objp->nfs_argop4_u.opcsecinfo.cname,
   4285 				    len));
   4286 			}
   4287 		}
   4288 		return (FALSE);
   4289 	}
   4290 	return (FALSE);
   4291 }
   4292 
   4293 /*
   4294  * Note that the len and decode_len will only be different in the case
   4295  * of the client's use of this free function.  If the server is
   4296  * freeing results, then the len/decode_len will always match.
   4297  */
   4298 static bool_t
   4299 xdr_nfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
   4300 {
   4301 	int i;
   4302 	nfs_resop4 *array = *arrayp;
   4303 
   4304 	/*
   4305 	 * Optimized XDR_FREE only results array
   4306 	 */
   4307 	ASSERT(xdrs->x_op == XDR_FREE);
   4308 
   4309 	if (array == NULL)
   4310 		return (TRUE);
   4311 
   4312 	for (i = 0; i < decode_len; i++) {
   4313 		/*
   4314 		 * These should be ordered by frequency of use
   4315 		 */
   4316 		switch (array[i].resop) {
   4317 		case OP_PUTFH:
   4318 			continue;
   4319 		case OP_GETATTR:
   4320 			if (array[i].nfs_resop4_u.opgetattr.status != NFS4_OK)
   4321 				continue;
   4322 			if (array[i].nfs_resop4_u.opgetattr.ga_res.n4g_ext_res)
   4323 				kmem_free(array[i].nfs_resop4_u.opgetattr.
   4324 				    ga_res.n4g_ext_res,
   4325 				    sizeof (struct nfs4_ga_ext_res));
   4326 			continue;
   4327 		case OP_GETFH:
   4328 			if (array[i].nfs_resop4_u.opgetfh.status != NFS4_OK)
   4329 				continue;
   4330 			if (array[i].nfs_resop4_u.opgetfh.object.nfs_fh4_val !=
   4331 			    NULL) {
   4332 				kmem_free(array[i].nfs_resop4_u.opgetfh.object.
   4333 				    nfs_fh4_val,
   4334 				    array[i].nfs_resop4_u.opgetfh.object.
   4335 				    nfs_fh4_len);
   4336 			}
   4337 			continue;
   4338 		case OP_LOOKUP:
   4339 			continue;
   4340 		case OP_OPEN:
   4341 			(void) xdr_OPEN4res(xdrs, &array[i].nfs_resop4_u.
   4342 			    opopen);
   4343 			continue;
   4344 		case OP_CLOSE:
   4345 		case OP_ACCESS:
   4346 			continue;
   4347 		case OP_READ:
   4348 			(void) xdr_READ4res(xdrs,
   4349 			    &array[i].nfs_resop4_u.opread);
   4350 			continue;
   4351 		case OP_WRITE:
   4352 		case OP_DELEGRETURN:
   4353 		case OP_LOOKUPP:
   4354 		case OP_READDIR:
   4355 		case OP_REMOVE:
   4356 		case OP_COMMIT:
   4357 		case OP_CREATE:
   4358 		case OP_DELEGPURGE:
   4359 		case OP_LINK:
   4360 			continue;
   4361 		case OP_LOCK:
   4362 			(void) xdr_LOCK4res(xdrs, &array[i].nfs_resop4_u.
   4363 			    oplock);
   4364 			continue;
   4365 		case OP_LOCKT:
   4366 			(void) xdr_LOCKT4res(xdrs, &array[i].nfs_resop4_u.
   4367 			    oplockt);
   4368 			continue;
   4369 		case OP_LOCKU:
   4370 		case OP_NVERIFY:
   4371 		case OP_OPENATTR:
   4372 		case OP_OPEN_CONFIRM:
   4373 		case OP_OPEN_DOWNGRADE:
   4374 		case OP_PUTPUBFH:
   4375 		case OP_PUTROOTFH:
   4376 		case OP_RENAME:
   4377 		case OP_RENEW:
   4378 		case OP_RESTOREFH:
   4379 		case OP_SAVEFH:
   4380 			continue;
   4381 		case OP_READLINK:
   4382 			(void) xdr_READLINK4res(xdrs, &array[i].nfs_resop4_u.
   4383 			    opreadlink);
   4384 			continue;
   4385 		case OP_SECINFO:
   4386 			(void) xdr_array(xdrs,
   4387 			    (char **)&array[i].nfs_resop4_u.opsecinfo.
   4388 			    SECINFO4resok_val,
   4389 			    (uint_t *)&array[i].nfs_resop4_u.opsecinfo.
   4390 			    SECINFO4resok_len,
   4391 			    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
   4392 			    (xdrproc_t)xdr_secinfo4);
   4393 			continue;
   4394 		case OP_SETCLIENTID:
   4395 			(void) xdr_SETCLIENTID4res(xdrs,
   4396 			    &array[i].nfs_resop4_u.opsetclientid);
   4397 			continue;
   4398 		case OP_SETATTR:
   4399 		case OP_SETCLIENTID_CONFIRM:
   4400 		case OP_VERIFY:
   4401 		case OP_RELEASE_LOCKOWNER:
   4402 		case OP_ILLEGAL:
   4403 			continue;
   4404 		default:
   4405 			/*
   4406 			 * An invalid op is a coding error, it should never
   4407 			 * have been decoded.
   4408 			 * Don't error because the caller cannot finish
   4409 			 * freeing the residual memory of the array.
   4410 			 */
   4411 			continue;
   4412 		}
   4413 	}
   4414 
   4415 	kmem_free(*arrayp, len * sizeof (nfs_resop4));
   4416 	*arrayp = NULL;
   4417 	return (TRUE);
   4418 }
   4419 
   4420 static bool_t
   4421 xdr_snfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len)
   4422 {
   4423 	return (xdr_nfs_resop4_free(xdrs, arrayp, len, decode_len));
   4424 }
   4425 
   4426 static bool_t
   4427 xdr_nfs_resop4(XDR *xdrs, nfs_resop4 *objp)
   4428 {
   4429 	/*
   4430 	 * These should be ordered by frequency of use
   4431 	 */
   4432 	switch (objp->resop) {
   4433 	case OP_PUTFH:
   4434 		return (xdr_int(xdrs,
   4435 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
   4436 	case OP_GETATTR:
   4437 		if (!xdr_int(xdrs,
   4438 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
   4439 			return (FALSE);
   4440 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
   4441 			return (TRUE);
   4442 		return (xdr_fattr4(xdrs,
   4443 		    &objp->nfs_resop4_u.opgetattr.obj_attributes));
   4444 	case OP_GETFH:
   4445 		if (!xdr_int(xdrs,
   4446 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
   4447 			return (FALSE);
   4448 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
   4449 			return (TRUE);
   4450 		return (xdr_bytes(xdrs,
   4451 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
   4452 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
   4453 		    NFS4_FHSIZE));
   4454 	case OP_LOOKUP:
   4455 		return (xdr_int(xdrs,
   4456 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
   4457 	case OP_OPEN:
   4458 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
   4459 	case OP_CLOSE:
   4460 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
   4461 	case OP_ACCESS:
   4462 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
   4463 	case OP_READ:
   4464 		return (xdr_READ4res(xdrs, &objp->nfs_resop4_u.opread));
   4465 	case OP_WRITE:
   4466 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
   4467 	case OP_DELEGRETURN:
   4468 		return (xdr_int(xdrs,
   4469 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
   4470 	case OP_LOOKUPP:
   4471 		return (xdr_int(xdrs,
   4472 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
   4473 	case OP_READDIR:
   4474 		return (xdr_READDIR4res(xdrs, &objp->nfs_resop4_u.opreaddir));
   4475 	case OP_REMOVE:
   4476 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
   4477 
   4478 	case OP_COMMIT:
   4479 		if (!xdr_int(xdrs,
   4480 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
   4481 			return (FALSE);
   4482 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
   4483 			return (TRUE);
   4484 		return (xdr_u_longlong_t(xdrs,
   4485 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
   4486 		    writeverf));
   4487 	case OP_CREATE:
   4488 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
   4489 	case OP_DELEGPURGE:
   4490 		return (xdr_int(xdrs,
   4491 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
   4492 	case OP_LINK:
   4493 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
   4494 	case OP_LOCK:
   4495 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
   4496 	case OP_LOCKT:
   4497 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
   4498 	case OP_LOCKU:
   4499 		if (!xdr_int(xdrs,
   4500 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
   4501 			return (FALSE);
   4502 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
   4503 			return (TRUE);
   4504 		if (!xdr_u_int(xdrs,
   4505 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
   4506 			return (FALSE);
   4507 		return (xdr_opaque(xdrs,
   4508 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
   4509 		    12));
   4510 	case OP_NVERIFY:
   4511 		return (xdr_int(xdrs,
   4512 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
   4513 	case OP_OPENATTR:
   4514 		return (xdr_int(xdrs,
   4515 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
   4516 	case OP_OPEN_CONFIRM:
   4517 		return (xdr_OPEN_CONFIRM4res(xdrs,
   4518 		    &objp->nfs_resop4_u.opopen_confirm));
   4519 	case OP_OPEN_DOWNGRADE:
   4520 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
   4521 		    &objp->nfs_resop4_u.opopen_downgrade));
   4522 	case OP_PUTPUBFH:
   4523 		return (xdr_int(xdrs,
   4524 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
   4525 	case OP_PUTROOTFH:
   4526 		return (xdr_int(xdrs,
   4527 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
   4528 	case OP_READLINK:
   4529 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
   4530 	case OP_RENAME:
   4531 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
   4532 	case OP_RENEW:
   4533 		return (xdr_int(xdrs,
   4534 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
   4535 	case OP_RESTOREFH:
   4536 		return (xdr_int(xdrs,
   4537 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
   4538 	case OP_SAVEFH:
   4539 		return (xdr_int(xdrs,
   4540 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
   4541 	case OP_SECINFO:
   4542 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
   4543 		    status))
   4544 			return (FALSE);
   4545 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
   4546 			return (TRUE);
   4547 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
   4548 		    SECINFO4resok_val,
   4549 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
   4550 		    SECINFO4resok_len,
   4551 		    NFS4_SECINFO_LIMIT, sizeof (secinfo4),
   4552 		    (xdrproc_t)xdr_secinfo4));
   4553 	case OP_SETATTR:
   4554 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
   4555 		    status))
   4556 			return (FALSE);
   4557 		return (xdr_bitmap4(xdrs,
   4558 		    &objp->nfs_resop4_u.opsetattr.attrsset));
   4559 	case OP_SETCLIENTID:
   4560 		return (xdr_SETCLIENTID4res(xdrs,
   4561 		    &objp->nfs_resop4_u.opsetclientid));
   4562 	case OP_SETCLIENTID_CONFIRM:
   4563 		return (xdr_int(xdrs,
   4564 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
   4565 		    status));
   4566 	case OP_VERIFY:
   4567 		return (xdr_int(xdrs,
   4568 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
   4569 	case OP_RELEASE_LOCKOWNER:
   4570 		return (xdr_int(xdrs,
   4571 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
   4572 	case OP_ILLEGAL:
   4573 		return (xdr_int(xdrs,
   4574 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
   4575 	}
   4576 	return (FALSE);
   4577 }
   4578 
   4579 static bool_t
   4580 xdr_snfs_resop4(XDR *xdrs, nfs_resop4 *objp)
   4581 {
   4582 	if (!xdr_int(xdrs, (int *)&objp->resop))
   4583 		return (FALSE);
   4584 
   4585 	switch (objp->resop) {
   4586 	case OP_GETFH:
   4587 		if (!XDR_PUTINT32(xdrs,
   4588 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
   4589 			return (FALSE);
   4590 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
   4591 			return (TRUE);
   4592 		return (xdr_encode_nfs_fh4(xdrs,
   4593 		    &objp->nfs_resop4_u.opgetfh.object));
   4594 	default:
   4595 		return (xdr_nfs_resop4(xdrs, objp));
   4596 	}
   4597 }
   4598 
   4599 static bool_t
   4600 xdr_nfs_resop4_clnt(XDR *xdrs, nfs_resop4 *objp, nfs_argop4 *aobjp)
   4601 {
   4602 	if (!xdr_int(xdrs, (int *)&objp->resop))
   4603 		return (FALSE);
   4604 	/*
   4605 	 * These should be ordered by frequency of use
   4606 	 */
   4607 	switch (objp->resop) {
   4608 	case OP_PUTFH:
   4609 		return (xdr_int(xdrs,
   4610 		    (int32_t *)&objp->nfs_resop4_u.opputfh.status));
   4611 	case OP_GETATTR:
   4612 		if (!xdr_int(xdrs,
   4613 		    (int32_t *)&objp->nfs_resop4_u.opgetattr.status))
   4614 			return (FALSE);
   4615 		if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK)
   4616 			return (TRUE);
   4617 		return (xdr_ga_res(xdrs,
   4618 		    (GETATTR4res *)&objp->nfs_resop4_u.opgetattr,
   4619 		    &aobjp->nfs_argop4_u.opgetattr));
   4620 	case OP_GETFH:
   4621 		if (!xdr_int(xdrs,
   4622 		    (int32_t *)&objp->nfs_resop4_u.opgetfh.status))
   4623 			return (FALSE);
   4624 		if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK)
   4625 			return (TRUE);
   4626 		return (xdr_bytes(xdrs,
   4627 		    (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val,
   4628 		    (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len,
   4629 		    NFS4_FHSIZE));
   4630 	case OP_LOOKUP:
   4631 		return (xdr_int(xdrs,
   4632 		    (int32_t *)&objp->nfs_resop4_u.oplookup.status));
   4633 	case OP_NVERIFY:
   4634 		return (xdr_int(xdrs,
   4635 		    (int32_t *)&objp->nfs_resop4_u.opnverify.status));
   4636 	case OP_OPEN:
   4637 		return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen));
   4638 	case OP_CLOSE:
   4639 		return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose));
   4640 	case OP_ACCESS:
   4641 		return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess));
   4642 	case OP_READ:
   4643 		return (xdr_READ4res_clnt(xdrs, &objp->nfs_resop4_u.opread,
   4644 		    &aobjp->nfs_argop4_u.opread));
   4645 	case OP_WRITE:
   4646 		return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite));
   4647 	case OP_DELEGRETURN:
   4648 		return (xdr_int(xdrs,
   4649 		    (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status));
   4650 	case OP_LOOKUPP:
   4651 		return (xdr_int(xdrs,
   4652 		    (int32_t *)&objp->nfs_resop4_u.oplookupp.status));
   4653 	case OP_READDIR:
   4654 		return (xdr_READDIR4res_clnt(xdrs,
   4655 		    &objp->nfs_resop4_u.opreaddirclnt,
   4656 		    &aobjp->nfs_argop4_u.opreaddir));
   4657 	case OP_REMOVE:
   4658 		return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove));
   4659 
   4660 	case OP_COMMIT:
   4661 		if (!xdr_int(xdrs,
   4662 		    (int32_t *)&objp->nfs_resop4_u.opcommit.status))
   4663 			return (FALSE);
   4664 		if (objp->nfs_resop4_u.opcommit.status != NFS4_OK)
   4665 			return (TRUE);
   4666 		return (xdr_u_longlong_t(xdrs,
   4667 		    (u_longlong_t *)&objp->nfs_resop4_u.opcommit.
   4668 		    writeverf));
   4669 	case OP_CREATE:
   4670 		return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate));
   4671 	case OP_DELEGPURGE:
   4672 		return (xdr_int(xdrs,
   4673 		    (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status));
   4674 	case OP_LINK:
   4675 		return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink));
   4676 	case OP_LOCK:
   4677 		return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock));
   4678 	case OP_LOCKT:
   4679 		return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt));
   4680 	case OP_LOCKU:
   4681 		if (!xdr_int(xdrs,
   4682 		    (int32_t *)&objp->nfs_resop4_u.oplocku.status))
   4683 			return (FALSE);
   4684 		if (objp->nfs_resop4_u.oplocku.status != NFS4_OK)
   4685 			return (TRUE);
   4686 		if (!xdr_u_int(xdrs,
   4687 		    &objp->nfs_resop4_u.oplocku.lock_stateid.seqid))
   4688 			return (FALSE);
   4689 		return (xdr_opaque(xdrs,
   4690 		    objp->nfs_resop4_u.oplocku.lock_stateid.other,
   4691 		    12));
   4692 	case OP_OPENATTR:
   4693 		return (xdr_int(xdrs,
   4694 		    (int32_t *)&objp->nfs_resop4_u.opopenattr.status));
   4695 	case OP_OPEN_CONFIRM:
   4696 		return (xdr_OPEN_CONFIRM4res(xdrs,
   4697 		    &objp->nfs_resop4_u.opopen_confirm));
   4698 	case OP_OPEN_DOWNGRADE:
   4699 		return (xdr_OPEN_DOWNGRADE4res(xdrs,
   4700 		    &objp->nfs_resop4_u.opopen_downgrade));
   4701 	case OP_PUTPUBFH:
   4702 		return (xdr_int(xdrs,
   4703 		    (int32_t *)&objp->nfs_resop4_u.opputpubfh.status));
   4704 	case OP_PUTROOTFH:
   4705 		return (xdr_int(xdrs,
   4706 		    (int32_t *)&objp->nfs_resop4_u.opputrootfh.status));
   4707 	case OP_READLINK:
   4708 		return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink));
   4709 	case OP_RENAME:
   4710 		return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename));
   4711 	case OP_RENEW:
   4712 		return (xdr_int(xdrs,
   4713 		    (int32_t *)&objp->nfs_resop4_u.oprenew.status));
   4714 	case OP_RESTOREFH:
   4715 		return (xdr_int(xdrs,
   4716 		    (int32_t *)&objp->nfs_resop4_u.oprestorefh.status));
   4717 	case OP_SAVEFH:
   4718 		return (xdr_int(xdrs,
   4719 		    (int32_t *)&objp->nfs_resop4_u.opsavefh.status));
   4720 	case OP_SECINFO:
   4721 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo.
   4722 		    status))
   4723 			return (FALSE);
   4724 		if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK)
   4725 			return (TRUE);
   4726 		return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo.
   4727 		    SECINFO4resok_val,
   4728 		    (uint_t *)&objp->nfs_resop4_u.opsecinfo.
   4729 		    SECINFO4resok_len,
   4730 		    ~0, sizeof (secinfo4), (xdrproc_t)xdr_secinfo4));
   4731 	case OP_SETATTR:
   4732 		if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr.
   4733 		    status))
   4734 			return (FALSE);
   4735 		return (xdr_bitmap4(xdrs,
   4736 		    &objp->nfs_resop4_u.opsetattr.attrsset));
   4737 	case OP_SETCLIENTID:
   4738 		return (xdr_SETCLIENTID4res(xdrs,
   4739 		    &objp->nfs_resop4_u.opsetclientid));
   4740 	case OP_SETCLIENTID_CONFIRM:
   4741 		return (xdr_int(xdrs,
   4742 		    (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm.
   4743 		    status));
   4744 	case OP_VERIFY:
   4745 		return (xdr_int(xdrs,
   4746 		    (int32_t *)&objp->nfs_resop4_u.opverify.status));
   4747 	case OP_RELEASE_LOCKOWNER:
   4748 		return (xdr_int(xdrs,
   4749 		    (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status));
   4750 	case OP_ILLEGAL:
   4751 		return (xdr_int(xdrs,
   4752 		    (int32_t *)&objp->nfs_resop4_u.opillegal.status));
   4753 	}
   4754 	return (FALSE);
   4755 }
   4756 
   4757 bool_t
   4758 xdr_COMPOUND4args_clnt(XDR *xdrs, COMPOUND4args_clnt *objp)
   4759 {
   4760 	static int32_t twelve = 12;
   4761 	static int32_t minorversion = NFS4_MINORVERSION;
   4762 	uint32_t *ctagp;
   4763 	rpc_inline_t *ptr;
   4764 	rdma_chunkinfo_t rci;
   4765 	struct xdr_ops *xops = xdrrdma_xops();
   4766 
   4767 	/*
   4768 	 * XDR_ENCODE only
   4769 	 */
   4770 	if (xdrs->x_op == XDR_FREE)
   4771 		return (TRUE);
   4772 	if (xdrs->x_op == XDR_DECODE)
   4773 		return (FALSE);
   4774 
   4775 	ctagp = (uint32_t *)&nfs4_ctags[objp->ctag].ct_tag;
   4776 
   4777 	if ((ptr = XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT)) != NULL) {
   4778 		/*
   4779 		 * Efficiently encode fixed length tags, could be longlongs
   4780 		 * but 8 byte XDR alignment not assured
   4781 		 */
   4782 		IXDR_PUT_U_INT32(ptr, 12);
   4783 		IXDR_PUT_U_INT32(ptr, ctagp[0]);
   4784 		IXDR_PUT_U_INT32(ptr, ctagp[1]);
   4785 		IXDR_PUT_U_INT32(ptr, ctagp[2]);
   4786 
   4787 		/*
   4788 		 * Fixed minor version for now
   4789 		 */
   4790 		IXDR_PUT_U_INT32(ptr, NFS4_MINORVERSION);
   4791 	} else {
   4792 		if (!XDR_PUTINT32(xdrs, &twelve))
   4793 			return (FALSE);
   4794 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[0]))
   4795 			return (FALSE);
   4796 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[1]))
   4797 			return (FALSE);
   4798 		if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[2]))
   4799 			return (FALSE);
   4800 		if (!XDR_PUTINT32(xdrs, (int32_t *)&minorversion))
   4801 			return (FALSE);
   4802 	}
   4803 	if (xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) {
   4804 		rci.rci_type = RCI_REPLY_CHUNK;
   4805 		rci.rci_len = MAXPATHLEN * 2;
   4806 		XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
   4807 	}
   4808 
   4809 	return (xdr_array(xdrs, (char **)&objp->array,
   4810 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
   4811 	    sizeof (nfs_argop4), (xdrproc_t)xdr_cnfs_argop4));
   4812 }
   4813 
   4814 bool_t
   4815 xdr_COMPOUND4args_srv(XDR *xdrs, COMPOUND4args *objp)
   4816 {
   4817 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
   4818 	    (uint_t *)&objp->tag.utf8string_len,
   4819 	    NFS4_MAX_UTF8STRING))
   4820 		return (FALSE);
   4821 	if (!xdr_u_int(xdrs, &objp->minorversion))
   4822 		return (FALSE);
   4823 	if (xdrs->x_op != XDR_FREE)
   4824 		return (xdr_array(xdrs, (char **)&objp->array,
   4825 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
   4826 		    sizeof (nfs_argop4), (xdrproc_t)xdr_snfs_argop4));
   4827 
   4828 	return (xdr_snfs_argop4_free(xdrs, &objp->array, objp->array_len));
   4829 }
   4830 
   4831 bool_t
   4832 xdr_COMPOUND4res_clnt(XDR *xdrs, COMPOUND4res_clnt *objp)
   4833 {
   4834 	uint32_t len;
   4835 	int32_t *ptr;
   4836 	nfs_argop4 *argop;
   4837 	nfs_resop4 *resop;
   4838 
   4839 	/*
   4840 	 * No XDR_ENCODE
   4841 	 */
   4842 	if (xdrs->x_op == XDR_ENCODE)
   4843 		return (FALSE);
   4844 
   4845 	if (xdrs->x_op != XDR_FREE) {
   4846 		if ((ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL) {
   4847 			objp->status = IXDR_GET_U_INT32(ptr);
   4848 			len = IXDR_GET_U_INT32(ptr);
   4849 		} else {
   4850 			if (!xdr_int(xdrs, (int32_t *)&objp->status))
   4851 				return (FALSE);
   4852 			if (!xdr_u_int(xdrs, (uint32_t *)&len))
   4853 				return (FALSE);
   4854 		}
   4855 		if (len > NFS4_MAX_UTF8STRING)
   4856 			return (FALSE);
   4857 		/*
   4858 		 * Ignore the tag
   4859 		 */
   4860 		if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &len))
   4861 			return (FALSE);
   4862 
   4863 		if (!xdr_int(xdrs, (int32_t *)&objp->array_len))
   4864 			return (FALSE);
   4865 
   4866 		if (objp->array_len > objp->argsp->array_len)
   4867 			return (FALSE);
   4868 
   4869 		if (objp->status == NFS_OK &&
   4870 		    objp->array_len != objp->argsp->array_len)
   4871 			return (FALSE);
   4872 
   4873 		/* Alloc the results array */
   4874 		argop = objp->argsp->array;
   4875 		len = objp->array_len * sizeof (nfs_resop4);
   4876 		objp->decode_len = 0;
   4877 		objp->array = resop = kmem_zalloc(len, KM_SLEEP);
   4878 
   4879 		for (len = 0; len < objp->array_len;
   4880 		    len++, resop++, argop++, objp->decode_len++) {
   4881 			if (!xdr_nfs_resop4_clnt(xdrs, resop, argop)) {
   4882 				/*
   4883 				 * Make sure to free anything that may
   4884 				 * have been allocated along the way.
   4885 				 */
   4886 				xdrs->x_op = XDR_FREE;
   4887 				(void) xdr_nfs_resop4_free(xdrs, &objp->array,
   4888 				    objp->array_len,
   4889 				    objp->decode_len);
   4890 				return (FALSE);
   4891 			}
   4892 		}
   4893 		return (TRUE);
   4894 	}
   4895 	return (xdr_nfs_resop4_free(xdrs, &objp->array,
   4896 	    objp->array_len, objp->decode_len));
   4897 }
   4898 
   4899 bool_t
   4900 xdr_COMPOUND4res_srv(XDR *xdrs, COMPOUND4res *objp)
   4901 {
   4902 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   4903 		return (FALSE);
   4904 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
   4905 	    (uint_t *)&objp->tag.utf8string_len,
   4906 	    NFS4_MAX_UTF8STRING))
   4907 		return (FALSE);
   4908 
   4909 	if (xdrs->x_op != XDR_FREE)
   4910 		return (xdr_array(xdrs, (char **)&objp->array,
   4911 		    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
   4912 		    sizeof (nfs_resop4), (xdrproc_t)xdr_snfs_resop4));
   4913 
   4914 	return (xdr_snfs_resop4_free(xdrs, &objp->array,
   4915 	    objp->array_len, objp->array_len));
   4916 }
   4917 
   4918 /*
   4919  * NFS server side callback, initiating the callback request so it
   4920  * is the RPC client. Must convert from server's internal filehandle
   4921  * format to wire format.
   4922  */
   4923 static bool_t
   4924 xdr_snfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
   4925 {
   4926 	CB_GETATTR4args *gargs;
   4927 	CB_RECALL4args *rargs;
   4928 
   4929 	ASSERT(xdrs->x_op == XDR_ENCODE);
   4930 
   4931 	if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->argop))
   4932 		return (FALSE);
   4933 
   4934 	switch (objp->argop) {
   4935 	case OP_CB_GETATTR:
   4936 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
   4937 
   4938 		if (!xdr_encode_nfs_fh4(xdrs, &gargs->fh))
   4939 			return (FALSE);
   4940 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
   4941 	case OP_CB_RECALL:
   4942 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
   4943 
   4944 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->stateid.seqid))
   4945 			return (FALSE);
   4946 		if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
   4947 			return (FALSE);
   4948 		if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->truncate))
   4949 			return (FALSE);
   4950 		return (xdr_encode_nfs_fh4(xdrs, &rargs->fh));
   4951 	case OP_CB_ILLEGAL:
   4952 		return (TRUE);
   4953 	}
   4954 	return (FALSE);
   4955 }
   4956 
   4957 /*
   4958  * NFS client side callback, receiving the callback request so it
   4959  * is the RPC server. Must treat the file handles as opaque.
   4960  */
   4961 static bool_t
   4962 xdr_cnfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp)
   4963 {
   4964 	CB_GETATTR4args *gargs;
   4965 	CB_RECALL4args *rargs;
   4966 
   4967 	ASSERT(xdrs->x_op != XDR_ENCODE);
   4968 
   4969 	if (!xdr_u_int(xdrs, &objp->argop))
   4970 		return (FALSE);
   4971 	switch (objp->argop) {
   4972 	case OP_CB_GETATTR:
   4973 		gargs = &objp->nfs_cb_argop4_u.opcbgetattr;
   4974 
   4975 		if (!xdr_bytes(xdrs, (char **)&gargs->fh.nfs_fh4_val,
   4976 		    (uint_t *)&gargs->fh.nfs_fh4_len, NFS4_FHSIZE))
   4977 			return (FALSE);
   4978 		return (xdr_bitmap4(xdrs, &gargs->attr_request));
   4979 	case OP_CB_RECALL:
   4980 		rargs = &objp->nfs_cb_argop4_u.opcbrecall;
   4981 
   4982 		if (!xdr_u_int(xdrs, &rargs->stateid.seqid))
   4983 			return (FALSE);
   4984 		if (!xdr_opaque(xdrs, rargs->stateid.other, 12))
   4985 			return (FALSE);
   4986 		if (!xdr_bool(xdrs, &rargs->truncate))
   4987 			return (FALSE);
   4988 		return (xdr_bytes(xdrs, (char **)&rargs->fh.nfs_fh4_val,
   4989 		    (uint_t *)&rargs->fh.nfs_fh4_len, NFS4_FHSIZE));
   4990 	case OP_CB_ILLEGAL:
   4991 		return (TRUE);
   4992 	}
   4993 	return (FALSE);
   4994 }
   4995 
   4996 static bool_t
   4997 xdr_nfs_cb_resop4(XDR *xdrs, nfs_cb_resop4 *objp)
   4998 {
   4999 	if (!xdr_u_int(xdrs, &objp->resop))
   5000 		return (FALSE);
   5001 	switch (objp->resop) {
   5002 	case OP_CB_GETATTR:
   5003 		if (!xdr_int(xdrs,
   5004 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbgetattr.
   5005 		    status))
   5006 			return (FALSE);
   5007 		if (objp->nfs_cb_resop4_u.opcbgetattr.status != NFS4_OK)
   5008 			return (TRUE);
   5009 		return (xdr_fattr4(xdrs,
   5010 		    &objp->nfs_cb_resop4_u.opcbgetattr.
   5011 		    obj_attributes));
   5012 	case OP_CB_RECALL:
   5013 		return (xdr_int(xdrs,
   5014 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbrecall.status));
   5015 	case OP_CB_ILLEGAL:
   5016 		return (xdr_int(xdrs,
   5017 		    (int32_t *)&objp->nfs_cb_resop4_u.opcbillegal.status));
   5018 	}
   5019 	return (FALSE);
   5020 }
   5021 
   5022 /*
   5023  * The NFS client side callback, RPC server
   5024  */
   5025 bool_t
   5026 xdr_CB_COMPOUND4args_clnt(XDR *xdrs, CB_COMPOUND4args *objp)
   5027 {
   5028 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
   5029 	    (uint_t *)&objp->tag.utf8string_len,
   5030 	    NFS4_MAX_UTF8STRING))
   5031 		return (FALSE);
   5032 	if (!xdr_u_int(xdrs, &objp->minorversion))
   5033 		return (FALSE);
   5034 	if (!xdr_u_int(xdrs, &objp->callback_ident))
   5035 		return (FALSE);
   5036 	return (xdr_array(xdrs, (char **)&objp->array,
   5037 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
   5038 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_cnfs_cb_argop4));
   5039 }
   5040 
   5041 /*
   5042  * The NFS server side callback, RPC client
   5043  */
   5044 bool_t
   5045 xdr_CB_COMPOUND4args_srv(XDR *xdrs, CB_COMPOUND4args *objp)
   5046 {
   5047 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
   5048 	    (uint_t *)&objp->tag.utf8string_len,
   5049 	    NFS4_MAX_UTF8STRING))
   5050 		return (FALSE);
   5051 	if (!xdr_u_int(xdrs, &objp->minorversion))
   5052 		return (FALSE);
   5053 	if (!xdr_u_int(xdrs, &objp->callback_ident))
   5054 		return (FALSE);
   5055 	return (xdr_array(xdrs, (char **)&objp->array,
   5056 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
   5057 	    sizeof (nfs_cb_argop4), (xdrproc_t)xdr_snfs_cb_argop4));
   5058 }
   5059 
   5060 bool_t
   5061 xdr_CB_COMPOUND4res(XDR *xdrs, CB_COMPOUND4res *objp)
   5062 {
   5063 	if (!xdr_int(xdrs, (int32_t *)&objp->status))
   5064 		return (FALSE);
   5065 	if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val,
   5066 	    (uint_t *)&objp->tag.utf8string_len,
   5067 	    NFS4_MAX_UTF8STRING))
   5068 		return (FALSE);
   5069 	return (xdr_array(xdrs, (char **)&objp->array,
   5070 	    (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT,
   5071 	    sizeof (nfs_cb_resop4), (xdrproc_t)xdr_nfs_cb_resop4));
   5072 }
   5073