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