17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 527242a7cSthurlow * Common Development and Distribution License (the "License"). 627242a7cSthurlow * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21bbe876c0SMarcel Telka 22bbe876c0SMarcel Telka /* 23bbe876c0SMarcel Telka * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 24bbe876c0SMarcel Telka */ 25bbe876c0SMarcel Telka 267c478bd9Sstevel@tonic-gate /* 27c242f9a0Schunli zhang - Sun Microsystems - Irvine United States * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 280a701b1eSRobert Gordon * Use is subject to license terms. 297c478bd9Sstevel@tonic-gate */ 30297b4d80SVitaliy Gusev /* 31e36d7b11SSebastien Roy * Copyright (c) 2013 by Delphix. All rights reserved. 32297b4d80SVitaliy Gusev */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate /* 357c478bd9Sstevel@tonic-gate * A handcoded version based on the original rpcgen code. 367c478bd9Sstevel@tonic-gate * 377c478bd9Sstevel@tonic-gate * Note: All future NFS4 protocol changes should be added by hand 387c478bd9Sstevel@tonic-gate * to this file. 397c478bd9Sstevel@tonic-gate * 407c478bd9Sstevel@tonic-gate * CAUTION: All protocol changes must also be propagated to: 417c478bd9Sstevel@tonic-gate * usr/src/cmd/cmd-inet/usr.sbin/snoop/nfs4_xdr.c 427c478bd9Sstevel@tonic-gate */ 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #include <sys/types.h> 457c478bd9Sstevel@tonic-gate #include <sys/sunddi.h> 467c478bd9Sstevel@tonic-gate #include <sys/dnlc.h> 477c478bd9Sstevel@tonic-gate #include <nfs/nfs.h> 487c478bd9Sstevel@tonic-gate #include <nfs/nfs4_kprot.h> 497c478bd9Sstevel@tonic-gate #include <nfs/rnode4.h> 507c478bd9Sstevel@tonic-gate #include <nfs/nfs4.h> 517c478bd9Sstevel@tonic-gate #include <nfs/nfs4_clnt.h> 527c478bd9Sstevel@tonic-gate #include <sys/sdt.h> 532f172c55SRobert Thurlow #include <sys/mkdev.h> 547c478bd9Sstevel@tonic-gate #include <rpc/rpc_rdma.h> 552f172c55SRobert Thurlow #include <rpc/xdr.h> 562f172c55SRobert Thurlow 572f172c55SRobert Thurlow #define xdr_dev_t xdr_u_int 582f172c55SRobert Thurlow 592f172c55SRobert Thurlow extern bool_t xdr_netbuf(XDR *, struct netbuf *); 602f172c55SRobert Thurlow extern bool_t xdr_vector(XDR *, char *, const uint_t, const uint_t, 612f172c55SRobert Thurlow const xdrproc_t); 622f172c55SRobert Thurlow bool_t xdr_knetconfig(XDR *, struct knetconfig *); 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate bool_t 657c478bd9Sstevel@tonic-gate xdr_bitmap4(XDR *xdrs, bitmap4 *objp) 667c478bd9Sstevel@tonic-gate { 677c478bd9Sstevel@tonic-gate int32_t len, size; 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 707c478bd9Sstevel@tonic-gate return (TRUE); 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* 737c478bd9Sstevel@tonic-gate * Simplified bitmap4 processing, always encode from uint64_t 747c478bd9Sstevel@tonic-gate * to 2 uint32_t's, always decode first 2 uint32_t's into a 757c478bd9Sstevel@tonic-gate * uint64_t and ignore all of the rest. 767c478bd9Sstevel@tonic-gate */ 777c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 787c478bd9Sstevel@tonic-gate len = 2; 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &len)) 817c478bd9Sstevel@tonic-gate return (FALSE); 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN) 847c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp + 857c478bd9Sstevel@tonic-gate BYTES_PER_XDR_UNIT)) == TRUE) { 867c478bd9Sstevel@tonic-gate return (XDR_PUTINT32(xdrs, (int32_t *)objp)); 877c478bd9Sstevel@tonic-gate } 887c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN) 897c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, (int32_t *)objp) == TRUE) { 907c478bd9Sstevel@tonic-gate return (XDR_PUTINT32(xdrs, (int32_t *)((char *)objp + 917c478bd9Sstevel@tonic-gate BYTES_PER_XDR_UNIT))); 927c478bd9Sstevel@tonic-gate } 937c478bd9Sstevel@tonic-gate #endif 947c478bd9Sstevel@tonic-gate return (FALSE); 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, &len)) 987c478bd9Sstevel@tonic-gate return (FALSE); 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate /* 1017c478bd9Sstevel@tonic-gate * Common fast DECODE cases 1027c478bd9Sstevel@tonic-gate */ 1037c478bd9Sstevel@tonic-gate if (len == 2) { 1047c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN) 1057c478bd9Sstevel@tonic-gate if (XDR_GETINT32(xdrs, (int32_t *)((char *)objp + 1067c478bd9Sstevel@tonic-gate BYTES_PER_XDR_UNIT)) == TRUE) { 1077c478bd9Sstevel@tonic-gate return (XDR_GETINT32(xdrs, (int32_t *)objp)); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN) 1107c478bd9Sstevel@tonic-gate if (XDR_GETINT32(xdrs, (int32_t *)objp) == TRUE) { 1117c478bd9Sstevel@tonic-gate return (XDR_GETINT32(xdrs, (int32_t *)((char *)objp + 1127c478bd9Sstevel@tonic-gate BYTES_PER_XDR_UNIT))); 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate #endif 1157c478bd9Sstevel@tonic-gate return (FALSE); 1167c478bd9Sstevel@tonic-gate } 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate *objp = 0; 1197c478bd9Sstevel@tonic-gate if (len == 0) 1207c478bd9Sstevel@tonic-gate return (TRUE); 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate /* 1237c478bd9Sstevel@tonic-gate * The not so common DECODE cases, len == 1 || len > 2 1247c478bd9Sstevel@tonic-gate */ 1257c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN) 1267c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT))) 1277c478bd9Sstevel@tonic-gate return (FALSE); 1287c478bd9Sstevel@tonic-gate if (--len == 0) 1297c478bd9Sstevel@tonic-gate return (TRUE); 1307c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)objp)) 1317c478bd9Sstevel@tonic-gate return (FALSE); 1327c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN) 1337c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)objp)) 1347c478bd9Sstevel@tonic-gate return (FALSE); 1357c478bd9Sstevel@tonic-gate if (--len == 0) 1367c478bd9Sstevel@tonic-gate return (TRUE); 1377c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)((char *)objp + BYTES_PER_XDR_UNIT))) 1387c478bd9Sstevel@tonic-gate return (FALSE); 1397c478bd9Sstevel@tonic-gate #else 1407c478bd9Sstevel@tonic-gate return (FALSE); 1417c478bd9Sstevel@tonic-gate #endif 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate if (--len == 0) 1447c478bd9Sstevel@tonic-gate return (TRUE); 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate size = len * BYTES_PER_XDR_UNIT; 1477c478bd9Sstevel@tonic-gate return (XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size)); 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate /* Called by xdr_array, nfsid_map_xdr */ 1517c478bd9Sstevel@tonic-gate bool_t 1527c478bd9Sstevel@tonic-gate xdr_utf8string(XDR *xdrs, utf8string *objp) 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) 1557c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->utf8string_val, 1567c478bd9Sstevel@tonic-gate (uint_t *)&objp->utf8string_len, NFS4_MAX_UTF8STRING)); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate if (objp->utf8string_val != NULL) { 1597c478bd9Sstevel@tonic-gate kmem_free(objp->utf8string_val, objp->utf8string_len); 1607c478bd9Sstevel@tonic-gate objp->utf8string_val = NULL; 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate return (TRUE); 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate /* 1662f172c55SRobert Thurlow * used by NFSv4 referrals to get info needed for NFSv4 referral mount. 1672f172c55SRobert Thurlow */ 1682f172c55SRobert Thurlow bool_t 1692f172c55SRobert Thurlow xdr_nfs_fsl_info(XDR *xdrs, struct nfs_fsl_info *objp) 1702f172c55SRobert Thurlow { 1712f172c55SRobert Thurlow 1722f172c55SRobert Thurlow if (!xdr_u_int(xdrs, &objp->netbuf_len)) 1732f172c55SRobert Thurlow return (FALSE); 1742f172c55SRobert Thurlow if (!xdr_u_int(xdrs, &objp->netnm_len)) 1752f172c55SRobert Thurlow return (FALSE); 1762f172c55SRobert Thurlow if (!xdr_u_int(xdrs, &objp->knconf_len)) 1772f172c55SRobert Thurlow return (FALSE); 1782f172c55SRobert Thurlow 1792f172c55SRobert Thurlow #if defined(_LP64) 1802f172c55SRobert Thurlow /* 1812f172c55SRobert Thurlow * The object can come from a 32-bit binary; nfsmapid. 1822f172c55SRobert Thurlow * To be safe we double the size of the knetconfig to 1832f172c55SRobert Thurlow * allow some buffering for decoding. 1842f172c55SRobert Thurlow */ 1852f172c55SRobert Thurlow if (xdrs->x_op == XDR_DECODE) 1862f172c55SRobert Thurlow objp->knconf_len += sizeof (struct knetconfig); 1872f172c55SRobert Thurlow #endif 1882f172c55SRobert Thurlow 1892f172c55SRobert Thurlow if (!xdr_string(xdrs, &objp->netname, ~0)) 1902f172c55SRobert Thurlow return (FALSE); 1912f172c55SRobert Thurlow if (!xdr_pointer(xdrs, (char **)&objp->addr, objp->netbuf_len, 1922f172c55SRobert Thurlow (xdrproc_t)xdr_netbuf)) 1932f172c55SRobert Thurlow return (FALSE); 1942f172c55SRobert Thurlow if (!xdr_pointer(xdrs, (char **)&objp->knconf, 1952f172c55SRobert Thurlow objp->knconf_len, (xdrproc_t)xdr_knetconfig)) 1962f172c55SRobert Thurlow return (FALSE); 1972f172c55SRobert Thurlow return (TRUE); 1982f172c55SRobert Thurlow } 1992f172c55SRobert Thurlow 2002f172c55SRobert Thurlow bool_t 2012f172c55SRobert Thurlow xdr_knetconfig(XDR *xdrs, struct knetconfig *objp) 2022f172c55SRobert Thurlow { 2032f172c55SRobert Thurlow rpc_inline_t *buf; 2042f172c55SRobert Thurlow u_longlong_t dev64; 2052f172c55SRobert Thurlow #if !defined(_LP64) 2062f172c55SRobert Thurlow uint32_t major, minor; 2072f172c55SRobert Thurlow #endif 2082f172c55SRobert Thurlow int i; 2092f172c55SRobert Thurlow 2102f172c55SRobert Thurlow if (!xdr_u_int(xdrs, &objp->knc_semantics)) 2112f172c55SRobert Thurlow return (FALSE); 2122f172c55SRobert Thurlow if (xdrs->x_op == XDR_DECODE) { 2132f172c55SRobert Thurlow objp->knc_protofmly = (((char *)objp) + 2142f172c55SRobert Thurlow sizeof (struct knetconfig)); 2152f172c55SRobert Thurlow objp->knc_proto = objp->knc_protofmly + KNC_STRSIZE; 2162f172c55SRobert Thurlow } 2172f172c55SRobert Thurlow if (!xdr_opaque(xdrs, objp->knc_protofmly, KNC_STRSIZE)) 2182f172c55SRobert Thurlow return (FALSE); 2192f172c55SRobert Thurlow if (!xdr_opaque(xdrs, objp->knc_proto, KNC_STRSIZE)) 2202f172c55SRobert Thurlow return (FALSE); 2212f172c55SRobert Thurlow 2222f172c55SRobert Thurlow /* 2232f172c55SRobert Thurlow * For interoperability between 32-bit daemon and 64-bit kernel, 2242f172c55SRobert Thurlow * we always treat dev_t as 64-bit number and do the expanding 2252f172c55SRobert Thurlow * or compression of dev_t as needed. 2262f172c55SRobert Thurlow * We have to hand craft the conversion since there is no available 2272f172c55SRobert Thurlow * function in ddi.c. Besides ddi.c is available only in the kernel 2282f172c55SRobert Thurlow * and we want to keep both user and kernel of xdr_knetconfig() the 2292f172c55SRobert Thurlow * same for consistency. 2302f172c55SRobert Thurlow */ 2312f172c55SRobert Thurlow if (xdrs->x_op == XDR_ENCODE) { 2322f172c55SRobert Thurlow #if defined(_LP64) 2332f172c55SRobert Thurlow dev64 = objp->knc_rdev; 2342f172c55SRobert Thurlow #else 2352f172c55SRobert Thurlow major = (objp->knc_rdev >> NBITSMINOR32) & MAXMAJ32; 2362f172c55SRobert Thurlow minor = objp->knc_rdev & MAXMIN32; 2372f172c55SRobert Thurlow dev64 = (((unsigned long long)major) << NBITSMINOR64) | minor; 2382f172c55SRobert Thurlow #endif 2392f172c55SRobert Thurlow if (!xdr_u_longlong_t(xdrs, &dev64)) 2402f172c55SRobert Thurlow return (FALSE); 2412f172c55SRobert Thurlow } 2422f172c55SRobert Thurlow if (xdrs->x_op == XDR_DECODE) { 2432f172c55SRobert Thurlow #if defined(_LP64) 2442f172c55SRobert Thurlow if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->knc_rdev)) 2452f172c55SRobert Thurlow return (FALSE); 2462f172c55SRobert Thurlow #else 2472f172c55SRobert Thurlow if (!xdr_u_longlong_t(xdrs, &dev64)) 2482f172c55SRobert Thurlow return (FALSE); 2492f172c55SRobert Thurlow 2502f172c55SRobert Thurlow major = (dev64 >> NBITSMINOR64) & L_MAXMAJ32; 2512f172c55SRobert Thurlow minor = dev64 & L_MAXMIN32; 2522f172c55SRobert Thurlow objp->knc_rdev = (major << L_BITSMINOR32) | minor; 2532f172c55SRobert Thurlow #endif 2542f172c55SRobert Thurlow } 2552f172c55SRobert Thurlow 2562f172c55SRobert Thurlow if (xdrs->x_op == XDR_ENCODE) { 2572f172c55SRobert Thurlow buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT); 2582f172c55SRobert Thurlow if (buf == NULL) { 2592f172c55SRobert Thurlow if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8, 2602f172c55SRobert Thurlow sizeof (uint_t), (xdrproc_t)xdr_u_int)) 2612f172c55SRobert Thurlow return (FALSE); 2622f172c55SRobert Thurlow } else { 2632f172c55SRobert Thurlow uint_t *genp; 2642f172c55SRobert Thurlow 2652f172c55SRobert Thurlow for (i = 0, genp = objp->knc_unused; 2662f172c55SRobert Thurlow i < 8; i++) { 2672f172c55SRobert Thurlow #if defined(_LP64) || defined(_KERNEL) 2682f172c55SRobert Thurlow IXDR_PUT_U_INT32(buf, *genp++); 2692f172c55SRobert Thurlow #else 2702f172c55SRobert Thurlow IXDR_PUT_U_LONG(buf, *genp++); 2712f172c55SRobert Thurlow #endif 2722f172c55SRobert Thurlow } 2732f172c55SRobert Thurlow } 2742f172c55SRobert Thurlow return (TRUE); 2752f172c55SRobert Thurlow } else if (xdrs->x_op == XDR_DECODE) { 2762f172c55SRobert Thurlow buf = XDR_INLINE(xdrs, (8) * BYTES_PER_XDR_UNIT); 2772f172c55SRobert Thurlow if (buf == NULL) { 2782f172c55SRobert Thurlow if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8, 2792f172c55SRobert Thurlow sizeof (uint_t), (xdrproc_t)xdr_u_int)) 2802f172c55SRobert Thurlow return (FALSE); 2812f172c55SRobert Thurlow } else { 2822f172c55SRobert Thurlow uint_t *genp; 2832f172c55SRobert Thurlow 2842f172c55SRobert Thurlow for (i = 0, genp = objp->knc_unused; 2852f172c55SRobert Thurlow i < 8; i++) { 2862f172c55SRobert Thurlow #if defined(_LP64) || defined(_KERNEL) 2872f172c55SRobert Thurlow *genp++ = IXDR_GET_U_INT32(buf); 2882f172c55SRobert Thurlow #else 2892f172c55SRobert Thurlow *genp++ = IXDR_GET_U_LONG(buf); 2902f172c55SRobert Thurlow #endif 2912f172c55SRobert Thurlow } 2922f172c55SRobert Thurlow } 2932f172c55SRobert Thurlow return (TRUE); 2942f172c55SRobert Thurlow } 2952f172c55SRobert Thurlow 2962f172c55SRobert Thurlow if (!xdr_vector(xdrs, (char *)objp->knc_unused, 8, 2972f172c55SRobert Thurlow sizeof (uint_t), (xdrproc_t)xdr_u_int)) 2982f172c55SRobert Thurlow return (FALSE); 2992f172c55SRobert Thurlow return (TRUE); 3002f172c55SRobert Thurlow } 3012f172c55SRobert Thurlow 3022f172c55SRobert Thurlow /* 303eac3aab7Srobinson * XDR_INLINE decode a filehandle. 304eac3aab7Srobinson */ 305eac3aab7Srobinson bool_t 306eac3aab7Srobinson xdr_inline_decode_nfs_fh4(uint32_t *ptr, nfs_fh4_fmt_t *fhp, uint32_t fhsize) 307eac3aab7Srobinson { 308eac3aab7Srobinson uchar_t *bp = (uchar_t *)ptr; 309eac3aab7Srobinson uchar_t *cp; 310eac3aab7Srobinson uint32_t dsize; 311eac3aab7Srobinson uintptr_t resid; 312eac3aab7Srobinson 313eac3aab7Srobinson /* 314eac3aab7Srobinson * Check to see if what the client sent us is bigger or smaller 315eac3aab7Srobinson * than what we can ever possibly send out. NFS_FHMAXDATA is 316eac3aab7Srobinson * unfortunately badly named as it is no longer the max and is 317eac3aab7Srobinson * really the min of what is sent over the wire. 318eac3aab7Srobinson */ 319eac3aab7Srobinson if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) + 320eac3aab7Srobinson sizeof (ushort_t) + NFS_FHMAXDATA + 321eac3aab7Srobinson sizeof (ushort_t) + NFS_FHMAXDATA)) { 322eac3aab7Srobinson return (FALSE); 323eac3aab7Srobinson } 324eac3aab7Srobinson 325eac3aab7Srobinson /* 326eac3aab7Srobinson * All internal parts of a filehandle are in native byte order. 327eac3aab7Srobinson * 328eac3aab7Srobinson * Decode what should be fh4_fsid, it is aligned. 329eac3aab7Srobinson */ 330eac3aab7Srobinson fhp->fh4_fsid.val[0] = *(uint32_t *)bp; 331eac3aab7Srobinson bp += BYTES_PER_XDR_UNIT; 332eac3aab7Srobinson fhp->fh4_fsid.val[1] = *(uint32_t *)bp; 333eac3aab7Srobinson bp += BYTES_PER_XDR_UNIT; 334eac3aab7Srobinson 335eac3aab7Srobinson /* 336eac3aab7Srobinson * Decode what should be fh4_len. fh4_len is two bytes, so we're 337eac3aab7Srobinson * unaligned now. 338eac3aab7Srobinson */ 339eac3aab7Srobinson cp = (uchar_t *)&fhp->fh4_len; 340eac3aab7Srobinson *cp++ = *bp++; 341eac3aab7Srobinson *cp++ = *bp++; 342eac3aab7Srobinson fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t); 343eac3aab7Srobinson 344eac3aab7Srobinson /* 345da6c28aaSamw * For backwards compatibility, the fid length may be less than 346eac3aab7Srobinson * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes. 347eac3aab7Srobinson */ 348eac3aab7Srobinson dsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len; 349eac3aab7Srobinson 350eac3aab7Srobinson /* 351eac3aab7Srobinson * Make sure the client isn't sending us a bogus length for fh4_data. 352eac3aab7Srobinson */ 353eac3aab7Srobinson if (fhsize < dsize) 354eac3aab7Srobinson return (FALSE); 355eac3aab7Srobinson bcopy(bp, fhp->fh4_data, dsize); 356eac3aab7Srobinson bp += dsize; 357eac3aab7Srobinson fhsize -= dsize; 358eac3aab7Srobinson 359eac3aab7Srobinson if (fhsize < sizeof (ushort_t)) 360eac3aab7Srobinson return (FALSE); 361eac3aab7Srobinson cp = (uchar_t *)&fhp->fh4_xlen; 362eac3aab7Srobinson *cp++ = *bp++; 363eac3aab7Srobinson *cp++ = *bp++; 364eac3aab7Srobinson fhsize -= sizeof (ushort_t); 365eac3aab7Srobinson 366eac3aab7Srobinson dsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen; 367eac3aab7Srobinson 368eac3aab7Srobinson /* 369eac3aab7Srobinson * Make sure the client isn't sending us a bogus length for fh4_xdata. 370eac3aab7Srobinson */ 371eac3aab7Srobinson if (fhsize < dsize) 372eac3aab7Srobinson return (FALSE); 373eac3aab7Srobinson bcopy(bp, fhp->fh4_xdata, dsize); 374eac3aab7Srobinson fhsize -= dsize; 375eac3aab7Srobinson bp += dsize; 376eac3aab7Srobinson 377eac3aab7Srobinson /* 378eac3aab7Srobinson * We realign things on purpose, so skip any padding 379eac3aab7Srobinson */ 380eac3aab7Srobinson resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT; 381eac3aab7Srobinson if (resid != 0) { 382eac3aab7Srobinson if (fhsize < (BYTES_PER_XDR_UNIT - resid)) 383eac3aab7Srobinson return (FALSE); 384eac3aab7Srobinson bp += BYTES_PER_XDR_UNIT - resid; 385eac3aab7Srobinson fhsize -= BYTES_PER_XDR_UNIT - resid; 386eac3aab7Srobinson } 387eac3aab7Srobinson 388eac3aab7Srobinson if (fhsize < BYTES_PER_XDR_UNIT) 389eac3aab7Srobinson return (FALSE); 390eac3aab7Srobinson fhp->fh4_flag = *(uint32_t *)bp; 391eac3aab7Srobinson bp += BYTES_PER_XDR_UNIT; 392eac3aab7Srobinson fhsize -= BYTES_PER_XDR_UNIT; 393eac3aab7Srobinson 394eac3aab7Srobinson #ifdef VOLATILE_FH_TEST 395eac3aab7Srobinson if (fhsize < BYTES_PER_XDR_UNIT) 396eac3aab7Srobinson return (FALSE); 397eac3aab7Srobinson fhp->fh4_volatile_id = *(uint32_t *)bp; 398eac3aab7Srobinson bp += BYTES_PER_XDR_UNIT; 399eac3aab7Srobinson fhsize -= BYTES_PER_XDR_UNIT; 400eac3aab7Srobinson #endif 401eac3aab7Srobinson /* 402eac3aab7Srobinson * Make sure client didn't send extra bytes 403eac3aab7Srobinson */ 404eac3aab7Srobinson if (fhsize != 0) 405eac3aab7Srobinson return (FALSE); 406eac3aab7Srobinson return (TRUE); 407eac3aab7Srobinson } 408eac3aab7Srobinson 409eac3aab7Srobinson static bool_t 410eac3aab7Srobinson xdr_decode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp) 411eac3aab7Srobinson { 412eac3aab7Srobinson uint32_t fhsize; /* filehandle size */ 413eac3aab7Srobinson uint32_t bufsize; 414eac3aab7Srobinson rpc_inline_t *ptr; 41527242a7cSthurlow uchar_t *bp; 416eac3aab7Srobinson 417eac3aab7Srobinson ASSERT(xdrs->x_op == XDR_DECODE); 418eac3aab7Srobinson 419eac3aab7Srobinson /* 420eac3aab7Srobinson * Retrieve the filehandle length. 421eac3aab7Srobinson */ 422eac3aab7Srobinson if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize)) 423eac3aab7Srobinson return (FALSE); 424eac3aab7Srobinson 425eac3aab7Srobinson objp->nfs_fh4_val = NULL; 426eac3aab7Srobinson objp->nfs_fh4_len = 0; 427eac3aab7Srobinson 428eac3aab7Srobinson /* 429eac3aab7Srobinson * Check to see if what the client sent us is bigger or smaller 430eac3aab7Srobinson * than what we can ever possibly send out. NFS_FHMAXDATA is 431eac3aab7Srobinson * unfortunately badly named as it is no longer the max and is 432eac3aab7Srobinson * really the min of what is sent over the wire. 433eac3aab7Srobinson */ 434eac3aab7Srobinson if (fhsize > sizeof (nfs_fh4_fmt_t) || fhsize < (sizeof (fsid_t) + 435eac3aab7Srobinson sizeof (ushort_t) + NFS_FHMAXDATA + 436eac3aab7Srobinson sizeof (ushort_t) + NFS_FHMAXDATA)) { 437eac3aab7Srobinson if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize)) 438eac3aab7Srobinson return (FALSE); 439eac3aab7Srobinson return (TRUE); 440eac3aab7Srobinson } 441eac3aab7Srobinson 442eac3aab7Srobinson /* 443eac3aab7Srobinson * bring in fhsize plus any padding 444eac3aab7Srobinson */ 445eac3aab7Srobinson bufsize = RNDUP(fhsize); 446eac3aab7Srobinson ptr = XDR_INLINE(xdrs, bufsize); 447eac3aab7Srobinson bp = (uchar_t *)ptr; 448eac3aab7Srobinson if (ptr == NULL) { 44927242a7cSthurlow bp = kmem_alloc(bufsize, KM_SLEEP); 45027242a7cSthurlow if (!xdr_opaque(xdrs, (char *)bp, bufsize)) { 45127242a7cSthurlow kmem_free(bp, bufsize); 452eac3aab7Srobinson return (FALSE); 453eac3aab7Srobinson } 45427242a7cSthurlow } 455eac3aab7Srobinson 456eac3aab7Srobinson objp->nfs_fh4_val = kmem_zalloc(sizeof (nfs_fh4_fmt_t), KM_SLEEP); 457eac3aab7Srobinson objp->nfs_fh4_len = sizeof (nfs_fh4_fmt_t); 458eac3aab7Srobinson 459eac3aab7Srobinson if (xdr_inline_decode_nfs_fh4((uint32_t *)bp, 460eac3aab7Srobinson (nfs_fh4_fmt_t *)objp->nfs_fh4_val, fhsize) == FALSE) { 461eac3aab7Srobinson /* 462eac3aab7Srobinson * If in the process of decoding we find the file handle 463eac3aab7Srobinson * is not correctly formed, we need to continue decoding 464eac3aab7Srobinson * and trigger an NFS layer error. Set the nfs_fh4_len to 465eac3aab7Srobinson * zero so it gets caught as a bad length. 466eac3aab7Srobinson */ 467eac3aab7Srobinson kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len); 468eac3aab7Srobinson objp->nfs_fh4_val = NULL; 469eac3aab7Srobinson objp->nfs_fh4_len = 0; 470eac3aab7Srobinson } 471eac3aab7Srobinson 472eac3aab7Srobinson if (ptr == NULL) 47327242a7cSthurlow kmem_free(bp, bufsize); 474eac3aab7Srobinson return (TRUE); 475eac3aab7Srobinson } 476eac3aab7Srobinson 477eac3aab7Srobinson /* 4787c46fb7fSek110237 * XDR_INLINE encode a filehandle. 4797c46fb7fSek110237 */ 4807c46fb7fSek110237 bool_t 4817c46fb7fSek110237 xdr_inline_encode_nfs_fh4(uint32_t **ptrp, uint32_t *ptr_redzone, 4827c46fb7fSek110237 nfs_fh4_fmt_t *fhp) 4837c46fb7fSek110237 { 4847c46fb7fSek110237 uint32_t *ptr = *ptrp; 4854f85d229Srobinson uchar_t *cp; 4864f85d229Srobinson uint_t otw_len, fsize, xsize; /* otw, file, and export sizes */ 4877c46fb7fSek110237 uint32_t padword; 4887c46fb7fSek110237 4894f85d229Srobinson fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len; 4904f85d229Srobinson xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen; 4914f85d229Srobinson 4927c46fb7fSek110237 /* 4934f85d229Srobinson * First get the initial and variable sized part of the filehandle. 4947c46fb7fSek110237 */ 4954f85d229Srobinson otw_len = sizeof (fhp->fh4_fsid) + 4964f85d229Srobinson sizeof (fhp->fh4_len) + fsize + 4974f85d229Srobinson sizeof (fhp->fh4_xlen) + xsize; 4984f85d229Srobinson 4997c46fb7fSek110237 /* 5007c46fb7fSek110237 * Round out to a full word. 5017c46fb7fSek110237 */ 5027c46fb7fSek110237 otw_len = RNDUP(otw_len); 5034f85d229Srobinson padword = (otw_len / BYTES_PER_XDR_UNIT); /* includes fhlen */ 5047c46fb7fSek110237 5057c46fb7fSek110237 /* 5067c46fb7fSek110237 * Add in the fixed sized pieces. 5077c46fb7fSek110237 */ 5087c46fb7fSek110237 otw_len += sizeof (fhp->fh4_flag); 5097c46fb7fSek110237 #ifdef VOLATILE_FH_TEST 5107c46fb7fSek110237 otw_len += sizeof (fhp->fh4_volatile_id); 5117c46fb7fSek110237 #endif 5127c46fb7fSek110237 5137c46fb7fSek110237 /* 5147c46fb7fSek110237 * Make sure we don't exceed our buffer. 5157c46fb7fSek110237 */ 5167c46fb7fSek110237 if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone) 5177c46fb7fSek110237 return (FALSE); 5187c46fb7fSek110237 5197c46fb7fSek110237 /* 52027242a7cSthurlow * Zero out the padding. 5217c46fb7fSek110237 */ 5227c46fb7fSek110237 ptr[padword] = 0; 5237c46fb7fSek110237 52427242a7cSthurlow IXDR_PUT_U_INT32(ptr, otw_len); 52527242a7cSthurlow 5264f85d229Srobinson /* 5274f85d229Srobinson * The rest of the filehandle is in native byteorder 5284f85d229Srobinson */ 5297c46fb7fSek110237 /* fh4_fsid */ 5300379dd9dSek110237 *ptr++ = (uint32_t)fhp->fh4_fsid.val[0]; 5310379dd9dSek110237 *ptr++ = (uint32_t)fhp->fh4_fsid.val[1]; 5327c46fb7fSek110237 5337c46fb7fSek110237 /* 5347c46fb7fSek110237 * Since the next pieces are unaligned, we need to 5357c46fb7fSek110237 * do bytewise copies. 5367c46fb7fSek110237 */ 5374f85d229Srobinson cp = (uchar_t *)ptr; 5387c46fb7fSek110237 5397c46fb7fSek110237 /* fh4_len + fh4_data */ 5404f85d229Srobinson bcopy(&fhp->fh4_len, cp, sizeof (fhp->fh4_len) + fsize); 5414f85d229Srobinson cp += sizeof (fhp->fh4_len) + fsize; 5427c46fb7fSek110237 5437c46fb7fSek110237 /* fh4_xlen + fh4_xdata */ 5444f85d229Srobinson bcopy(&fhp->fh4_xlen, cp, sizeof (fhp->fh4_xlen) + xsize); 5454f85d229Srobinson cp += sizeof (fhp->fh4_xlen) + xsize; 5467c46fb7fSek110237 5477c46fb7fSek110237 /* do necessary rounding/padding */ 5484f85d229Srobinson cp = (uchar_t *)RNDUP((uintptr_t)cp); 5494f85d229Srobinson ptr = (uint32_t *)cp; 5507c46fb7fSek110237 5517c46fb7fSek110237 /* 5527c46fb7fSek110237 * With the above padding, we're word aligned again. 5537c46fb7fSek110237 */ 5547c46fb7fSek110237 ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0); 5557c46fb7fSek110237 5567c46fb7fSek110237 /* fh4_flag */ 5570379dd9dSek110237 *ptr++ = (uint32_t)fhp->fh4_flag; 5587c46fb7fSek110237 5597c46fb7fSek110237 #ifdef VOLATILE_FH_TEST 5607c46fb7fSek110237 /* fh4_volatile_id */ 5610379dd9dSek110237 *ptr++ = (uint32_t)fhp->fh4_volatile_id; 5627c46fb7fSek110237 #endif 5637c46fb7fSek110237 *ptrp = ptr; 5647c46fb7fSek110237 5657c46fb7fSek110237 return (TRUE); 5667c46fb7fSek110237 } 5677c46fb7fSek110237 5687c46fb7fSek110237 static bool_t 5697c46fb7fSek110237 xdr_encode_nfs_fh4(XDR *xdrs, nfs_fh4 *objp) 5707c46fb7fSek110237 { 5714f85d229Srobinson uint_t otw_len, fsize, xsize; /* otw, file, and export sizes */ 5724f85d229Srobinson bool_t ret; 5734f85d229Srobinson rpc_inline_t *ptr; 5744f85d229Srobinson rpc_inline_t *buf = NULL; 5754f85d229Srobinson uint32_t *ptr_redzone; 5764f85d229Srobinson nfs_fh4_fmt_t *fhp; 5777c46fb7fSek110237 5787c46fb7fSek110237 ASSERT(xdrs->x_op == XDR_ENCODE); 5797c46fb7fSek110237 5804f85d229Srobinson fhp = (nfs_fh4_fmt_t *)objp->nfs_fh4_val; 5814f85d229Srobinson fsize = fhp->fh4_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_len; 5824f85d229Srobinson xsize = fhp->fh4_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh4_xlen; 5837c46fb7fSek110237 5847c46fb7fSek110237 /* 5854f85d229Srobinson * First get the over the wire size, it is the 4 bytes 5864f85d229Srobinson * for the length, plus the combined size of the 5874f85d229Srobinson * file handle components. 5887c46fb7fSek110237 */ 5894f85d229Srobinson otw_len = BYTES_PER_XDR_UNIT + sizeof (fhp->fh4_fsid) + 5904f85d229Srobinson sizeof (fhp->fh4_len) + fsize + 5914f85d229Srobinson sizeof (fhp->fh4_xlen) + xsize + 5924f85d229Srobinson sizeof (fhp->fh4_flag); 5934f85d229Srobinson #ifdef VOLATILE_FH_TEST 5944f85d229Srobinson otw_len += sizeof (fhp->fh4_volatile_id); 5954f85d229Srobinson #endif 5964f85d229Srobinson /* 5974f85d229Srobinson * Round out to a full word. 5984f85d229Srobinson */ 5994f85d229Srobinson otw_len = RNDUP(otw_len); 6007c46fb7fSek110237 6017c46fb7fSek110237 /* 6024f85d229Srobinson * Next try to inline the XDR stream, if that fails (rare) 6034f85d229Srobinson * allocate a buffer to encode the file handle and then 6044f85d229Srobinson * copy it using xdr_opaque and free the buffer. 6057c46fb7fSek110237 */ 6064f85d229Srobinson ptr = XDR_INLINE(xdrs, otw_len); 6074f85d229Srobinson if (ptr == NULL) 6084f85d229Srobinson ptr = buf = kmem_alloc(otw_len, KM_SLEEP); 6097c46fb7fSek110237 6104f85d229Srobinson ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT)); 6114f85d229Srobinson ret = xdr_inline_encode_nfs_fh4((uint32_t **)&ptr, ptr_redzone, fhp); 6127c46fb7fSek110237 6134f85d229Srobinson if (buf != NULL) { 6144f85d229Srobinson if (ret == TRUE) 6154f85d229Srobinson ret = xdr_opaque(xdrs, (char *)buf, otw_len); 6164f85d229Srobinson kmem_free(buf, otw_len); 6174f85d229Srobinson } 6184f85d229Srobinson return (ret); 6197c46fb7fSek110237 } 6207c46fb7fSek110237 6217c46fb7fSek110237 /* 6227c46fb7fSek110237 * XDR a NFSv4 filehandle. 623eac3aab7Srobinson * Encoding interprets the contents (server). 624eac3aab7Srobinson * Decoding the contents are opaque (client). 6257c478bd9Sstevel@tonic-gate */ 6267c478bd9Sstevel@tonic-gate bool_t 6277c478bd9Sstevel@tonic-gate xdr_nfs_fh4(XDR *xdrs, nfs_fh4 *objp) 6287c478bd9Sstevel@tonic-gate { 629eac3aab7Srobinson switch (xdrs->x_op) { 630eac3aab7Srobinson case XDR_ENCODE: 6317c46fb7fSek110237 return (xdr_encode_nfs_fh4(xdrs, objp)); 632eac3aab7Srobinson case XDR_DECODE: 633eac3aab7Srobinson return (xdr_bytes(xdrs, (char **)&objp->nfs_fh4_val, 634eac3aab7Srobinson (uint_t *)&objp->nfs_fh4_len, NFS4_FHSIZE)); 635eac3aab7Srobinson case XDR_FREE: 6367c478bd9Sstevel@tonic-gate if (objp->nfs_fh4_val != NULL) { 6377c478bd9Sstevel@tonic-gate kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len); 6387c478bd9Sstevel@tonic-gate objp->nfs_fh4_val = NULL; 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate return (TRUE); 6417c478bd9Sstevel@tonic-gate } 642eac3aab7Srobinson return (FALSE); 643eac3aab7Srobinson } 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate /* Called by xdr_array */ 6467c478bd9Sstevel@tonic-gate static bool_t 6477c478bd9Sstevel@tonic-gate xdr_fs_location4(XDR *xdrs, fs_location4 *objp) 6487c478bd9Sstevel@tonic-gate { 6492f172c55SRobert Thurlow if (xdrs->x_op == XDR_DECODE) { 6502f172c55SRobert Thurlow objp->server_val = NULL; 6512f172c55SRobert Thurlow objp->rootpath.pathname4_val = NULL; 6522f172c55SRobert Thurlow } 6537c478bd9Sstevel@tonic-gate if (!xdr_array(xdrs, (char **)&objp->server_val, 6542f172c55SRobert Thurlow (uint_t *)&objp->server_len, NFS4_MAX_UTF8STRING, 6557c478bd9Sstevel@tonic-gate sizeof (utf8string), (xdrproc_t)xdr_utf8string)) 6567c478bd9Sstevel@tonic-gate return (FALSE); 6577c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->rootpath.pathname4_val, 6587c478bd9Sstevel@tonic-gate (uint_t *)&objp->rootpath.pathname4_len, 6597c478bd9Sstevel@tonic-gate NFS4_MAX_PATHNAME4, 6607c478bd9Sstevel@tonic-gate sizeof (utf8string), (xdrproc_t)xdr_utf8string)); 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate /* Called by xdr_array */ 6647c478bd9Sstevel@tonic-gate static bool_t 6657c478bd9Sstevel@tonic-gate xdr_nfsace4(XDR *xdrs, nfsace4 *objp) 6667c478bd9Sstevel@tonic-gate { 6677c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 6687c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->type)) 6697c478bd9Sstevel@tonic-gate return (FALSE); 6707c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->flag)) 6717c478bd9Sstevel@tonic-gate return (FALSE); 6727c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->access_mask)) 6737c478bd9Sstevel@tonic-gate return (FALSE); 6747c478bd9Sstevel@tonic-gate 6757c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) { 6767c478bd9Sstevel@tonic-gate objp->who.utf8string_val = NULL; 6777c478bd9Sstevel@tonic-gate objp->who.utf8string_len = 0; 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->who.utf8string_val, 6817c478bd9Sstevel@tonic-gate (uint_t *)&objp->who.utf8string_len, 6827c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate /* 6867c478bd9Sstevel@tonic-gate * Optimized free case 6877c478bd9Sstevel@tonic-gate */ 6887c478bd9Sstevel@tonic-gate if (objp->who.utf8string_val != NULL) { 6897c478bd9Sstevel@tonic-gate kmem_free(objp->who.utf8string_val, objp->who.utf8string_len); 6907c478bd9Sstevel@tonic-gate objp->who.utf8string_val = NULL; 6917c478bd9Sstevel@tonic-gate } 6927c478bd9Sstevel@tonic-gate return (TRUE); 6937c478bd9Sstevel@tonic-gate } 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate /* 6967c478bd9Sstevel@tonic-gate * These functions are called out of nfs4_attr.c 6977c478bd9Sstevel@tonic-gate */ 6987c478bd9Sstevel@tonic-gate bool_t 6997c478bd9Sstevel@tonic-gate xdr_fattr4_fsid(XDR *xdrs, fattr4_fsid *objp) 7007c478bd9Sstevel@tonic-gate { 7017c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 7027c478bd9Sstevel@tonic-gate return (TRUE); 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->major)) 7057c478bd9Sstevel@tonic-gate return (FALSE); 7067c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->minor)); 7077c478bd9Sstevel@tonic-gate } 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate bool_t 7117c478bd9Sstevel@tonic-gate xdr_fattr4_acl(XDR *xdrs, fattr4_acl *objp) 7127c478bd9Sstevel@tonic-gate { 7137c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->fattr4_acl_val, 7147c478bd9Sstevel@tonic-gate (uint_t *)&objp->fattr4_acl_len, NFS4_ACL_LIMIT, 7157c478bd9Sstevel@tonic-gate sizeof (nfsace4), (xdrproc_t)xdr_nfsace4)); 7167c478bd9Sstevel@tonic-gate } 7177c478bd9Sstevel@tonic-gate 7187c478bd9Sstevel@tonic-gate bool_t 7197c478bd9Sstevel@tonic-gate xdr_fattr4_fs_locations(XDR *xdrs, fattr4_fs_locations *objp) 7207c478bd9Sstevel@tonic-gate { 7212f172c55SRobert Thurlow if (xdrs->x_op == XDR_DECODE) { 7222f172c55SRobert Thurlow objp->fs_root.pathname4_len = 0; 7232f172c55SRobert Thurlow objp->fs_root.pathname4_val = NULL; 7242f172c55SRobert Thurlow objp->locations_val = NULL; 7252f172c55SRobert Thurlow } 7267c478bd9Sstevel@tonic-gate if (!xdr_array(xdrs, (char **)&objp->fs_root.pathname4_val, 7277c478bd9Sstevel@tonic-gate (uint_t *)&objp->fs_root.pathname4_len, 7287c478bd9Sstevel@tonic-gate NFS4_MAX_PATHNAME4, 7297c478bd9Sstevel@tonic-gate sizeof (utf8string), (xdrproc_t)xdr_utf8string)) 7307c478bd9Sstevel@tonic-gate return (FALSE); 7317c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->locations_val, 7327c478bd9Sstevel@tonic-gate (uint_t *)&objp->locations_len, NFS4_FS_LOCATIONS_LIMIT, 7337c478bd9Sstevel@tonic-gate sizeof (fs_location4), (xdrproc_t)xdr_fs_location4)); 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate bool_t 7377c478bd9Sstevel@tonic-gate xdr_fattr4_rawdev(XDR *xdrs, fattr4_rawdev *objp) 7387c478bd9Sstevel@tonic-gate { 7397c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 7407c478bd9Sstevel@tonic-gate return (TRUE); 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->specdata1)) 7437c478bd9Sstevel@tonic-gate return (FALSE); 7447c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->specdata2)); 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate bool_t 7487c478bd9Sstevel@tonic-gate xdr_nfstime4(XDR *xdrs, nfstime4 *objp) 7497c478bd9Sstevel@tonic-gate { 7507c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 7517c478bd9Sstevel@tonic-gate return (TRUE); 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->seconds)) 7547c478bd9Sstevel@tonic-gate return (FALSE); 7557c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->nseconds)); 7567c478bd9Sstevel@tonic-gate } 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate /* 7607c478bd9Sstevel@tonic-gate * structured used for calls into xdr_ga_fattr_res() as a means 7617c478bd9Sstevel@tonic-gate * to do an immediate/short-term cache of owner/group strings 7627c478bd9Sstevel@tonic-gate * for callers like the readdir processing. In the case of readdir, 7637c478bd9Sstevel@tonic-gate * it is likely that the directory objects will be owned by the same 7647c478bd9Sstevel@tonic-gate * owner/group and if so there is no need to call into the uid/gid 7657c478bd9Sstevel@tonic-gate * mapping code. While the uid/gid interfaces have their own cache 7667c478bd9Sstevel@tonic-gate * having one here will reduct pathlength further. 7677c478bd9Sstevel@tonic-gate */ 7687c478bd9Sstevel@tonic-gate #define MAX_OG_NAME 100 7697c478bd9Sstevel@tonic-gate typedef struct ug_cache 7707c478bd9Sstevel@tonic-gate { 7717c478bd9Sstevel@tonic-gate uid_t uid; 7727c478bd9Sstevel@tonic-gate gid_t gid; 7737c478bd9Sstevel@tonic-gate utf8string u_curr, u_last; 7747c478bd9Sstevel@tonic-gate utf8string g_curr, g_last; 7757c478bd9Sstevel@tonic-gate char u_buf1[MAX_OG_NAME]; 7767c478bd9Sstevel@tonic-gate char u_buf2[MAX_OG_NAME]; 7777c478bd9Sstevel@tonic-gate char g_buf1[MAX_OG_NAME]; 7787c478bd9Sstevel@tonic-gate char g_buf2[MAX_OG_NAME]; 7797c478bd9Sstevel@tonic-gate } ug_cache_t; 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate #define U_SWAP_CURR_LAST(ug) \ 7827c478bd9Sstevel@tonic-gate (ug)->u_last.utf8string_len = (ug)->u_curr.utf8string_len; \ 7837c478bd9Sstevel@tonic-gate if ((ug)->u_last.utf8string_val == (ug)->u_buf1) { \ 7847c478bd9Sstevel@tonic-gate (ug)->u_last.utf8string_val = (ug)->u_buf2; \ 7857c478bd9Sstevel@tonic-gate (ug)->u_curr.utf8string_val = (ug)->u_buf1; \ 7867c478bd9Sstevel@tonic-gate } else { \ 7877c478bd9Sstevel@tonic-gate (ug)->u_last.utf8string_val = (ug)->u_buf1; \ 7887c478bd9Sstevel@tonic-gate (ug)->u_curr.utf8string_val = (ug)->u_buf2; \ 7897c478bd9Sstevel@tonic-gate } 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate #define G_SWAP_CURR_LAST(ug) \ 7927c478bd9Sstevel@tonic-gate (ug)->g_last.utf8string_len = (ug)->g_curr.utf8string_len; \ 7937c478bd9Sstevel@tonic-gate if ((ug)->g_last.utf8string_val == (ug)->g_buf1) { \ 7947c478bd9Sstevel@tonic-gate (ug)->g_last.utf8string_val = (ug)->g_buf2; \ 7957c478bd9Sstevel@tonic-gate (ug)->g_curr.utf8string_val = (ug)->g_buf1; \ 7967c478bd9Sstevel@tonic-gate } else { \ 7977c478bd9Sstevel@tonic-gate (ug)->g_last.utf8string_val = (ug)->g_buf1; \ 7987c478bd9Sstevel@tonic-gate (ug)->g_curr.utf8string_val = (ug)->g_buf2; \ 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate static ug_cache_t * 8027c478bd9Sstevel@tonic-gate alloc_ugcache() 8037c478bd9Sstevel@tonic-gate { 8047c478bd9Sstevel@tonic-gate ug_cache_t *pug = kmem_alloc(sizeof (ug_cache_t), KM_SLEEP); 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate pug->uid = pug->gid = 0; 8077c478bd9Sstevel@tonic-gate pug->u_curr.utf8string_len = 0; 8087c478bd9Sstevel@tonic-gate pug->u_last.utf8string_len = 0; 8097c478bd9Sstevel@tonic-gate pug->g_curr.utf8string_len = 0; 8107c478bd9Sstevel@tonic-gate pug->g_last.utf8string_len = 0; 8117c478bd9Sstevel@tonic-gate pug->u_curr.utf8string_val = pug->u_buf1; 8127c478bd9Sstevel@tonic-gate pug->u_last.utf8string_val = pug->u_buf2; 8137c478bd9Sstevel@tonic-gate pug->g_curr.utf8string_val = pug->g_buf1; 8147c478bd9Sstevel@tonic-gate pug->g_last.utf8string_val = pug->g_buf2; 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate return (pug); 8177c478bd9Sstevel@tonic-gate } 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate static void 8207c478bd9Sstevel@tonic-gate xdr_ga_prefill_vattr(struct nfs4_ga_res *garp, struct mntinfo4 *mi) 8217c478bd9Sstevel@tonic-gate { 8227c478bd9Sstevel@tonic-gate static vattr_t s_vattr = { 8237c478bd9Sstevel@tonic-gate AT_ALL, /* va_mask */ 8247c478bd9Sstevel@tonic-gate VNON, /* va_type */ 8257c478bd9Sstevel@tonic-gate 0777, /* va_mode */ 8267c478bd9Sstevel@tonic-gate UID_NOBODY, /* va_uid */ 8277c478bd9Sstevel@tonic-gate GID_NOBODY, /* va_gid */ 8287c478bd9Sstevel@tonic-gate 0, /* va_fsid */ 8297c478bd9Sstevel@tonic-gate 0, /* va_nodeid */ 8307c478bd9Sstevel@tonic-gate 1, /* va_nlink */ 8317c478bd9Sstevel@tonic-gate 0, /* va_size */ 8327c478bd9Sstevel@tonic-gate {0, 0}, /* va_atime */ 8337c478bd9Sstevel@tonic-gate {0, 0}, /* va_mtime */ 8347c478bd9Sstevel@tonic-gate {0, 0}, /* va_ctime */ 8357c478bd9Sstevel@tonic-gate 0, /* va_rdev */ 8367c478bd9Sstevel@tonic-gate MAXBSIZE, /* va_blksize */ 8377c478bd9Sstevel@tonic-gate 0, /* va_nblocks */ 8387c478bd9Sstevel@tonic-gate 0 /* va_seq */ 8397c478bd9Sstevel@tonic-gate }; 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate garp->n4g_va = s_vattr; 8437c478bd9Sstevel@tonic-gate garp->n4g_va.va_fsid = mi->mi_vfsp->vfs_dev; 8447c478bd9Sstevel@tonic-gate hrt2ts(gethrtime(), &garp->n4g_va.va_atime); 8457c478bd9Sstevel@tonic-gate garp->n4g_va.va_mtime = garp->n4g_va.va_ctime = garp->n4g_va.va_atime; 8467c478bd9Sstevel@tonic-gate } 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate static void 8497c478bd9Sstevel@tonic-gate xdr_ga_prefill_statvfs(struct nfs4_ga_ext_res *gesp, struct mntinfo4 *mi) 8507c478bd9Sstevel@tonic-gate { 8517c478bd9Sstevel@tonic-gate static statvfs64_t s_sb = { 8527c478bd9Sstevel@tonic-gate MAXBSIZE, /* f_bsize */ 8537c478bd9Sstevel@tonic-gate DEV_BSIZE, /* f_frsize */ 8547c478bd9Sstevel@tonic-gate (fsfilcnt64_t)-1, /* f_blocks */ 8557c478bd9Sstevel@tonic-gate (fsfilcnt64_t)-1, /* f_bfree */ 8567c478bd9Sstevel@tonic-gate (fsfilcnt64_t)-1, /* f_bavail */ 8577c478bd9Sstevel@tonic-gate (fsfilcnt64_t)-1, /* f_files */ 8587c478bd9Sstevel@tonic-gate (fsfilcnt64_t)-1, /* f_ffree */ 8597c478bd9Sstevel@tonic-gate (fsfilcnt64_t)-1, /* f_favail */ 8607c478bd9Sstevel@tonic-gate 0, /* f_fsid */ 8617c478bd9Sstevel@tonic-gate "\0", /* f_basetype */ 8627c478bd9Sstevel@tonic-gate 0, /* f_flag */ 8637c478bd9Sstevel@tonic-gate MAXNAMELEN, /* f_namemax */ 8647c478bd9Sstevel@tonic-gate "\0", /* f_fstr */ 8657c478bd9Sstevel@tonic-gate }; 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate gesp->n4g_sb = s_sb; 8687c478bd9Sstevel@tonic-gate gesp->n4g_sb.f_fsid = mi->mi_vfsp->vfs_fsid.val[0]; 8697c478bd9Sstevel@tonic-gate } 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate static bool_t 8727c478bd9Sstevel@tonic-gate xdr_ga_fattr_res(XDR *xdrs, struct nfs4_ga_res *garp, bitmap4 resbmap, 8737c478bd9Sstevel@tonic-gate bitmap4 argbmap, struct mntinfo4 *mi, ug_cache_t *pug) 8747c478bd9Sstevel@tonic-gate { 8757c478bd9Sstevel@tonic-gate int truefalse; 8767c478bd9Sstevel@tonic-gate struct nfs4_ga_ext_res ges, *gesp; 8777c478bd9Sstevel@tonic-gate vattr_t *vap = &garp->n4g_va; 8787c478bd9Sstevel@tonic-gate vsecattr_t *vsap = &garp->n4g_vsa; 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_DECODE); 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate if (garp->n4g_ext_res) 8837c478bd9Sstevel@tonic-gate gesp = garp->n4g_ext_res; 8847c478bd9Sstevel@tonic-gate else 8857c478bd9Sstevel@tonic-gate gesp = ⩾ 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate vap->va_mask = 0; 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate /* Check to see if the vattr should be pre-filled */ 8907c478bd9Sstevel@tonic-gate if (argbmap & NFS4_VATTR_MASK) 8917c478bd9Sstevel@tonic-gate xdr_ga_prefill_vattr(garp, mi); 8927c478bd9Sstevel@tonic-gate 8937c478bd9Sstevel@tonic-gate if (argbmap & NFS4_STATFS_ATTR_MASK) 8947c478bd9Sstevel@tonic-gate xdr_ga_prefill_statvfs(gesp, mi); 8957c478bd9Sstevel@tonic-gate 8967c478bd9Sstevel@tonic-gate if (resbmap & 8977c478bd9Sstevel@tonic-gate (FATTR4_SUPPORTED_ATTRS_MASK | 8987c478bd9Sstevel@tonic-gate FATTR4_TYPE_MASK | 8997c478bd9Sstevel@tonic-gate FATTR4_FH_EXPIRE_TYPE_MASK | 9007c478bd9Sstevel@tonic-gate FATTR4_CHANGE_MASK | 9017c478bd9Sstevel@tonic-gate FATTR4_SIZE_MASK | 9027c478bd9Sstevel@tonic-gate FATTR4_LINK_SUPPORT_MASK | 9037c478bd9Sstevel@tonic-gate FATTR4_SYMLINK_SUPPORT_MASK | 9047c478bd9Sstevel@tonic-gate FATTR4_NAMED_ATTR_MASK)) { 9057c478bd9Sstevel@tonic-gate 9067c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) { 9077c478bd9Sstevel@tonic-gate if (!xdr_bitmap4(xdrs, &gesp->n4g_suppattrs)) 9087c478bd9Sstevel@tonic-gate return (FALSE); 9097c478bd9Sstevel@tonic-gate } 9107c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TYPE_MASK) { 9117c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&vap->va_type)) 9127c478bd9Sstevel@tonic-gate return (FALSE); 9137c478bd9Sstevel@tonic-gate 9142c2d21e9SRichard Lowe if ((nfs_ftype4)vap->va_type < NF4REG || 9152c2d21e9SRichard Lowe (nfs_ftype4)vap->va_type > NF4NAMEDATTR) 9167c478bd9Sstevel@tonic-gate vap->va_type = VBAD; 9177c478bd9Sstevel@tonic-gate else 9187c478bd9Sstevel@tonic-gate vap->va_type = nf4_to_vt[vap->va_type]; 9197c478bd9Sstevel@tonic-gate if (vap->va_type == VBLK) 9207c478bd9Sstevel@tonic-gate vap->va_blksize = DEV_BSIZE; 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate vap->va_mask |= AT_TYPE; 9237c478bd9Sstevel@tonic-gate } 9247c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) { 9257c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_fet)) 9267c478bd9Sstevel@tonic-gate return (FALSE); 9277c478bd9Sstevel@tonic-gate } 9287c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CHANGE_MASK) { 9297c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 9307c478bd9Sstevel@tonic-gate (u_longlong_t *)&garp->n4g_change)) 9317c478bd9Sstevel@tonic-gate return (FALSE); 9327c478bd9Sstevel@tonic-gate garp->n4g_change_valid = 1; 9337c478bd9Sstevel@tonic-gate } 9347c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SIZE_MASK) { 9357c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 9367c478bd9Sstevel@tonic-gate (u_longlong_t *)&vap->va_size)) 9377c478bd9Sstevel@tonic-gate return (FALSE); 9387c478bd9Sstevel@tonic-gate if (!NFS4_SIZE_OK(vap->va_size)) { 9397c478bd9Sstevel@tonic-gate garp->n4g_attrerr = EFBIG; 9407c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR; 9417c478bd9Sstevel@tonic-gate } else { 9427c478bd9Sstevel@tonic-gate vap->va_mask |= AT_SIZE; 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate } 9457c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_LINK_SUPPORT_MASK) { 9467c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 9477c478bd9Sstevel@tonic-gate return (FALSE); 9487c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_link_support = 9497c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 9507c478bd9Sstevel@tonic-gate } 9517c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) { 9527c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 9537c478bd9Sstevel@tonic-gate return (FALSE); 9547c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_symlink_support = 9557c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 9567c478bd9Sstevel@tonic-gate } 9577c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_NAMED_ATTR_MASK) { 9587c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 9597c478bd9Sstevel@tonic-gate return (FALSE); 9607c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_xattr_exists = TRUE; 9617c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_xattr_exists = 9627c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 9637c478bd9Sstevel@tonic-gate } 9647c478bd9Sstevel@tonic-gate } 9657c478bd9Sstevel@tonic-gate if (resbmap & 9667c478bd9Sstevel@tonic-gate (FATTR4_FSID_MASK | 9677c478bd9Sstevel@tonic-gate FATTR4_UNIQUE_HANDLES_MASK | 9687c478bd9Sstevel@tonic-gate FATTR4_LEASE_TIME_MASK | 9697c478bd9Sstevel@tonic-gate FATTR4_RDATTR_ERROR_MASK)) { 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FSID_MASK) { 9727c478bd9Sstevel@tonic-gate if ((!xdr_u_longlong_t(xdrs, 9737c478bd9Sstevel@tonic-gate (u_longlong_t *)&garp->n4g_fsid.major)) || 9747c478bd9Sstevel@tonic-gate (!xdr_u_longlong_t(xdrs, 9757c478bd9Sstevel@tonic-gate (u_longlong_t *)&garp->n4g_fsid.minor))) 9767c478bd9Sstevel@tonic-gate return (FALSE); 9777c478bd9Sstevel@tonic-gate garp->n4g_fsid_valid = 1; 9787c478bd9Sstevel@tonic-gate } 9797c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) { 9807c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 9817c478bd9Sstevel@tonic-gate return (FALSE); 9827c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_unique_handles = 9837c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 9847c478bd9Sstevel@tonic-gate } 9857c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_LEASE_TIME_MASK) { 9867c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_leasetime)) 9877c478bd9Sstevel@tonic-gate return (FALSE); 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_RDATTR_ERROR_MASK) { 9907c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, 9917c478bd9Sstevel@tonic-gate (int *)&gesp->n4g_rdattr_error)) 9927c478bd9Sstevel@tonic-gate return (FALSE); 9937c478bd9Sstevel@tonic-gate } 9947c478bd9Sstevel@tonic-gate } 9957c478bd9Sstevel@tonic-gate if (resbmap & 9967c478bd9Sstevel@tonic-gate (FATTR4_ACL_MASK | 9977c478bd9Sstevel@tonic-gate FATTR4_ACLSUPPORT_MASK | 9987c478bd9Sstevel@tonic-gate FATTR4_ARCHIVE_MASK | 9997c478bd9Sstevel@tonic-gate FATTR4_CANSETTIME_MASK)) { 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_ACL_MASK) { 10027c478bd9Sstevel@tonic-gate fattr4_acl acl; 10037c478bd9Sstevel@tonic-gate 10047c478bd9Sstevel@tonic-gate acl.fattr4_acl_val = NULL; 10057c478bd9Sstevel@tonic-gate acl.fattr4_acl_len = 0; 10067c478bd9Sstevel@tonic-gate 10077c478bd9Sstevel@tonic-gate if (!xdr_fattr4_acl(xdrs, &acl)) 10087c478bd9Sstevel@tonic-gate return (FALSE); 10097c478bd9Sstevel@tonic-gate 10107c478bd9Sstevel@tonic-gate vsap->vsa_aclcnt = acl.fattr4_acl_len; 10117c478bd9Sstevel@tonic-gate vsap->vsa_aclentp = acl.fattr4_acl_val; 10127c478bd9Sstevel@tonic-gate vsap->vsa_mask = VSA_ACE | VSA_ACECNT; 1013da6c28aaSamw vsap->vsa_aclentsz = vsap->vsa_aclcnt * sizeof (ace_t); 10147c478bd9Sstevel@tonic-gate 10157c478bd9Sstevel@tonic-gate } 10167c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_ACLSUPPORT_MASK) { 10177c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&gesp->n4g_aclsupport)) 10187c478bd9Sstevel@tonic-gate return (FALSE); 10197c478bd9Sstevel@tonic-gate } 10207c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_ARCHIVE_MASK) { 10217c478bd9Sstevel@tonic-gate ASSERT(0); 10227c478bd9Sstevel@tonic-gate } 10237c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CANSETTIME_MASK) { 10247c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 10257c478bd9Sstevel@tonic-gate return (FALSE); 10267c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_cansettime = 10277c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 10287c478bd9Sstevel@tonic-gate } 10297c478bd9Sstevel@tonic-gate } 10307c478bd9Sstevel@tonic-gate if (resbmap & 10317c478bd9Sstevel@tonic-gate (FATTR4_CASE_INSENSITIVE_MASK | 10327c478bd9Sstevel@tonic-gate FATTR4_CASE_PRESERVING_MASK | 10337c478bd9Sstevel@tonic-gate FATTR4_CHOWN_RESTRICTED_MASK | 10347c478bd9Sstevel@tonic-gate FATTR4_FILEHANDLE_MASK | 10357c478bd9Sstevel@tonic-gate FATTR4_FILEID_MASK | 10367c478bd9Sstevel@tonic-gate FATTR4_FILES_AVAIL_MASK | 10377c478bd9Sstevel@tonic-gate FATTR4_FILES_FREE_MASK | 10387c478bd9Sstevel@tonic-gate FATTR4_FILES_TOTAL_MASK)) { 10397c478bd9Sstevel@tonic-gate 10407c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) { 10417c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 10427c478bd9Sstevel@tonic-gate return (FALSE); 10437c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_case_insensitive = 10447c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 10457c478bd9Sstevel@tonic-gate } 10467c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CASE_PRESERVING_MASK) { 10477c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 10487c478bd9Sstevel@tonic-gate return (FALSE); 10497c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_case_preserving = 10507c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 10517c478bd9Sstevel@tonic-gate } 10527c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) { 10537c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 10547c478bd9Sstevel@tonic-gate return (FALSE); 10557c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_chown_restricted = 10567c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 10577c478bd9Sstevel@tonic-gate } 10587c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILEHANDLE_MASK) { 10597c478bd9Sstevel@tonic-gate gesp->n4g_fh_u.nfs_fh4_alt.len = 0; 10607c478bd9Sstevel@tonic-gate gesp->n4g_fh_u.nfs_fh4_alt.val = 10617c478bd9Sstevel@tonic-gate gesp->n4g_fh_u.nfs_fh4_alt.data; 10627c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, 10637c478bd9Sstevel@tonic-gate (char **)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_val, 10647c478bd9Sstevel@tonic-gate (uint_t *)&gesp->n4g_fh_u.n4g_fh.nfs_fh4_len, 10657c478bd9Sstevel@tonic-gate NFS4_FHSIZE)) 10667c478bd9Sstevel@tonic-gate return (FALSE); 10677c478bd9Sstevel@tonic-gate } 10687c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILEID_MASK) { 10697c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 10707c478bd9Sstevel@tonic-gate (u_longlong_t *)&vap->va_nodeid)) 10717c478bd9Sstevel@tonic-gate return (FALSE); 10727c478bd9Sstevel@tonic-gate vap->va_mask |= AT_NODEID; 10737c478bd9Sstevel@tonic-gate } 10747c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILES_AVAIL_MASK) { 10757c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 10767c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_sb.f_favail)) 10777c478bd9Sstevel@tonic-gate return (FALSE); 10787c478bd9Sstevel@tonic-gate } 10797c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILES_FREE_MASK) { 10807c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 10817c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_sb.f_ffree)) 10827c478bd9Sstevel@tonic-gate return (FALSE); 10837c478bd9Sstevel@tonic-gate } 10847c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILES_TOTAL_MASK) { 10857c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 10867c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_sb.f_files)) 10877c478bd9Sstevel@tonic-gate return (FALSE); 10887c478bd9Sstevel@tonic-gate } 10897c478bd9Sstevel@tonic-gate } 10907c478bd9Sstevel@tonic-gate if (resbmap & 10917c478bd9Sstevel@tonic-gate (FATTR4_FS_LOCATIONS_MASK | 10927c478bd9Sstevel@tonic-gate FATTR4_HIDDEN_MASK | 10937c478bd9Sstevel@tonic-gate FATTR4_HOMOGENEOUS_MASK)) { 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FS_LOCATIONS_MASK) { 10962f172c55SRobert Thurlow if (!xdr_fattr4_fs_locations(xdrs, 10972f172c55SRobert Thurlow &gesp->n4g_fslocations)) 10982f172c55SRobert Thurlow return (FALSE); 10997c478bd9Sstevel@tonic-gate } 11007c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_HIDDEN_MASK) { 11017c478bd9Sstevel@tonic-gate ASSERT(0); 11027c478bd9Sstevel@tonic-gate } 11037c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_HOMOGENEOUS_MASK) { 11047c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 11057c478bd9Sstevel@tonic-gate return (FALSE); 11067c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_homogeneous = 11077c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 11087c478bd9Sstevel@tonic-gate } 11097c478bd9Sstevel@tonic-gate } 11107c478bd9Sstevel@tonic-gate if (resbmap & 11117c478bd9Sstevel@tonic-gate (FATTR4_MAXFILESIZE_MASK | 11127c478bd9Sstevel@tonic-gate FATTR4_MAXLINK_MASK | 11137c478bd9Sstevel@tonic-gate FATTR4_MAXNAME_MASK | 11147c478bd9Sstevel@tonic-gate FATTR4_MAXREAD_MASK | 11157c478bd9Sstevel@tonic-gate FATTR4_MAXWRITE_MASK)) { 11167c478bd9Sstevel@tonic-gate 11177c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXFILESIZE_MASK) { 11187c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 11197c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_maxfilesize)) 11207c478bd9Sstevel@tonic-gate return (FALSE); 11217c478bd9Sstevel@tonic-gate } 11227c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXLINK_MASK) { 11237c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, 11247c478bd9Sstevel@tonic-gate (int *)&gesp->n4g_pc4.pc4_link_max)) 11257c478bd9Sstevel@tonic-gate return (FALSE); 11267c478bd9Sstevel@tonic-gate } 11277c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXNAME_MASK) { 11287c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, 11297c478bd9Sstevel@tonic-gate (int *)&gesp->n4g_pc4.pc4_name_max)) 11307c478bd9Sstevel@tonic-gate return (FALSE); 11317c478bd9Sstevel@tonic-gate gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max; 11327c478bd9Sstevel@tonic-gate } 11337c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXREAD_MASK) { 11347c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 11357c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_maxread)) 11367c478bd9Sstevel@tonic-gate return (FALSE); 11377c478bd9Sstevel@tonic-gate } 11387c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXWRITE_MASK) { 11397c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 11407c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_maxwrite)) 11417c478bd9Sstevel@tonic-gate return (FALSE); 11427c478bd9Sstevel@tonic-gate } 11437c478bd9Sstevel@tonic-gate } 11447c478bd9Sstevel@tonic-gate if (resbmap & 11457c478bd9Sstevel@tonic-gate (FATTR4_MIMETYPE_MASK | 11467c478bd9Sstevel@tonic-gate FATTR4_MODE_MASK | 11477c478bd9Sstevel@tonic-gate FATTR4_NO_TRUNC_MASK | 11487c478bd9Sstevel@tonic-gate FATTR4_NUMLINKS_MASK)) { 11497c478bd9Sstevel@tonic-gate 11507c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MIMETYPE_MASK) { 11517c478bd9Sstevel@tonic-gate ASSERT(0); 11527c478bd9Sstevel@tonic-gate } 11537c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MODE_MASK) { 11547c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&vap->va_mode)) 11557c478bd9Sstevel@tonic-gate return (FALSE); 11567c478bd9Sstevel@tonic-gate vap->va_mask |= AT_MODE; 11577c478bd9Sstevel@tonic-gate } 11587c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_NO_TRUNC_MASK) { 11597c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&truefalse)) 11607c478bd9Sstevel@tonic-gate return (FALSE); 11617c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_no_trunc = 11627c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 11637c478bd9Sstevel@tonic-gate } 11647c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_NUMLINKS_MASK) { 11657c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&vap->va_nlink)) 11667c478bd9Sstevel@tonic-gate return (FALSE); 11677c478bd9Sstevel@tonic-gate vap->va_mask |= AT_NLINK; 11687c478bd9Sstevel@tonic-gate } 11697c478bd9Sstevel@tonic-gate } 11707c478bd9Sstevel@tonic-gate if (resbmap & 11717c478bd9Sstevel@tonic-gate (FATTR4_OWNER_MASK | 11727c478bd9Sstevel@tonic-gate FATTR4_OWNER_GROUP_MASK | 11737c478bd9Sstevel@tonic-gate FATTR4_QUOTA_AVAIL_HARD_MASK | 11747c478bd9Sstevel@tonic-gate FATTR4_QUOTA_AVAIL_SOFT_MASK)) { 11757c478bd9Sstevel@tonic-gate 11767c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_OWNER_MASK) { 11777c478bd9Sstevel@tonic-gate uint_t *owner_length, ol; 11787c478bd9Sstevel@tonic-gate char *owner_val = NULL; 11797c478bd9Sstevel@tonic-gate char *owner_alloc = NULL; 11807c478bd9Sstevel@tonic-gate utf8string ov; 11817c478bd9Sstevel@tonic-gate int error; 11827c478bd9Sstevel@tonic-gate 11837c478bd9Sstevel@tonic-gate /* get the OWNER_LENGTH */ 11847c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ol)) 11857c478bd9Sstevel@tonic-gate return (FALSE); 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate /* Manage the owner length location */ 11887c478bd9Sstevel@tonic-gate if (pug && ol <= MAX_OG_NAME) { 11897c478bd9Sstevel@tonic-gate owner_length = &pug->u_curr.utf8string_len; 11907c478bd9Sstevel@tonic-gate *owner_length = ol; 11917c478bd9Sstevel@tonic-gate } else { 11927c478bd9Sstevel@tonic-gate owner_length = &ol; 11937c478bd9Sstevel@tonic-gate } 11947c478bd9Sstevel@tonic-gate 11957c478bd9Sstevel@tonic-gate /* find memory to store the decode */ 11967c478bd9Sstevel@tonic-gate if (*owner_length > MAX_OG_NAME || pug == NULL) 11977c478bd9Sstevel@tonic-gate owner_val = owner_alloc = 11987c478bd9Sstevel@tonic-gate kmem_alloc(*owner_length, KM_SLEEP); 11997c478bd9Sstevel@tonic-gate else 12007c478bd9Sstevel@tonic-gate owner_val = pug->u_curr.utf8string_val; 12017c478bd9Sstevel@tonic-gate 12027c478bd9Sstevel@tonic-gate /* get the OWNER string */ 12037c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, owner_val, *owner_length)) { 12047c478bd9Sstevel@tonic-gate if (owner_alloc) 12057c478bd9Sstevel@tonic-gate kmem_free(owner_alloc, *owner_length); 12067c478bd9Sstevel@tonic-gate return (FALSE); 12077c478bd9Sstevel@tonic-gate } 12087c478bd9Sstevel@tonic-gate 12097c478bd9Sstevel@tonic-gate /* Optimize for matching if called for */ 12107c478bd9Sstevel@tonic-gate if (pug && 12117c478bd9Sstevel@tonic-gate *owner_length == pug->u_last.utf8string_len && 12127c478bd9Sstevel@tonic-gate bcmp(owner_val, pug->u_last.utf8string_val, 12137c478bd9Sstevel@tonic-gate *owner_length) == 0) { 12147c478bd9Sstevel@tonic-gate vap->va_uid = pug->uid; 12157c478bd9Sstevel@tonic-gate vap->va_mask |= AT_UID; 12167c478bd9Sstevel@tonic-gate } else { 12177c478bd9Sstevel@tonic-gate uid_t uid; 12187c478bd9Sstevel@tonic-gate 12197c478bd9Sstevel@tonic-gate ov.utf8string_len = *owner_length; 12207c478bd9Sstevel@tonic-gate ov.utf8string_val = owner_val; 12217c478bd9Sstevel@tonic-gate error = nfs_idmap_str_uid(&ov, &uid, FALSE); 12227c478bd9Sstevel@tonic-gate /* 12237c478bd9Sstevel@tonic-gate * String was mapped, but to nobody because 12247c478bd9Sstevel@tonic-gate * we are nfsmapid, indicate it should not 12257c478bd9Sstevel@tonic-gate * be cached. 12267c478bd9Sstevel@tonic-gate */ 12277c478bd9Sstevel@tonic-gate if (error == ENOTSUP) { 12287c478bd9Sstevel@tonic-gate error = 0; 12297c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = 12307c478bd9Sstevel@tonic-gate NFS4_GETATTR_NOCACHE_OK; 12317c478bd9Sstevel@tonic-gate } 12327c478bd9Sstevel@tonic-gate 12337c478bd9Sstevel@tonic-gate if (error) { 12347c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 12357c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = 12367c478bd9Sstevel@tonic-gate NFS4_GETATTR_ATUID_ERR; 12377c478bd9Sstevel@tonic-gate } else { 12387c478bd9Sstevel@tonic-gate vap->va_uid = uid; 12397c478bd9Sstevel@tonic-gate vap->va_mask |= AT_UID; 12407c478bd9Sstevel@tonic-gate if (pug && ol <= MAX_OG_NAME) { 12417c478bd9Sstevel@tonic-gate pug->uid = uid; 12427c478bd9Sstevel@tonic-gate U_SWAP_CURR_LAST(pug); 12437c478bd9Sstevel@tonic-gate } 12447c478bd9Sstevel@tonic-gate } 12457c478bd9Sstevel@tonic-gate if (owner_alloc) 12467c478bd9Sstevel@tonic-gate kmem_free(owner_alloc, *owner_length); 12477c478bd9Sstevel@tonic-gate } 12487c478bd9Sstevel@tonic-gate } 12497c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_OWNER_GROUP_MASK) { 12507c478bd9Sstevel@tonic-gate uint_t *group_length, gl; 12517c478bd9Sstevel@tonic-gate char *group_val = NULL; 12527c478bd9Sstevel@tonic-gate char *group_alloc = NULL; 12537c478bd9Sstevel@tonic-gate utf8string gv; 12547c478bd9Sstevel@tonic-gate int error; 12557c478bd9Sstevel@tonic-gate 12567c478bd9Sstevel@tonic-gate /* get the OWNER_GROUP_LENGTH */ 12577c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &gl)) 12587c478bd9Sstevel@tonic-gate return (FALSE); 12597c478bd9Sstevel@tonic-gate 12607c478bd9Sstevel@tonic-gate /* Manage the group length location */ 12617c478bd9Sstevel@tonic-gate if (pug && gl <= MAX_OG_NAME) { 12627c478bd9Sstevel@tonic-gate group_length = &pug->g_curr.utf8string_len; 12637c478bd9Sstevel@tonic-gate *group_length = gl; 12647c478bd9Sstevel@tonic-gate } else { 12657c478bd9Sstevel@tonic-gate group_length = ≷ 12667c478bd9Sstevel@tonic-gate } 12677c478bd9Sstevel@tonic-gate 12687c478bd9Sstevel@tonic-gate /* find memory to store the decode */ 12697c478bd9Sstevel@tonic-gate if (*group_length > MAX_OG_NAME || pug == NULL) 12707c478bd9Sstevel@tonic-gate group_val = group_alloc = 12717c478bd9Sstevel@tonic-gate kmem_alloc(*group_length, KM_SLEEP); 12727c478bd9Sstevel@tonic-gate else 12737c478bd9Sstevel@tonic-gate group_val = pug->g_curr.utf8string_val; 12747c478bd9Sstevel@tonic-gate 12757c478bd9Sstevel@tonic-gate /* get the OWNER_GROUP string */ 12767c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, group_val, *group_length)) { 12777c478bd9Sstevel@tonic-gate if (group_alloc) 12787c478bd9Sstevel@tonic-gate kmem_free(group_alloc, *group_length); 12797c478bd9Sstevel@tonic-gate return (FALSE); 12807c478bd9Sstevel@tonic-gate } 12817c478bd9Sstevel@tonic-gate 12827c478bd9Sstevel@tonic-gate /* Optimize for matching if called for */ 12837c478bd9Sstevel@tonic-gate if (pug && 12847c478bd9Sstevel@tonic-gate *group_length == pug->g_last.utf8string_len && 12857c478bd9Sstevel@tonic-gate bcmp(group_val, pug->g_last.utf8string_val, 12867c478bd9Sstevel@tonic-gate *group_length) == 0) { 12877c478bd9Sstevel@tonic-gate vap->va_gid = pug->gid; 12887c478bd9Sstevel@tonic-gate vap->va_mask |= AT_GID; 12897c478bd9Sstevel@tonic-gate } else { 12907c478bd9Sstevel@tonic-gate uid_t gid; 12917c478bd9Sstevel@tonic-gate 12927c478bd9Sstevel@tonic-gate gv.utf8string_len = *group_length; 12937c478bd9Sstevel@tonic-gate gv.utf8string_val = group_val; 12947c478bd9Sstevel@tonic-gate error = nfs_idmap_str_gid(&gv, &gid, FALSE); 12957c478bd9Sstevel@tonic-gate /* 12967c478bd9Sstevel@tonic-gate * String was mapped, but to nobody because 12977c478bd9Sstevel@tonic-gate * we are nfsmapid, indicate it should not 12987c478bd9Sstevel@tonic-gate * be cached. 12997c478bd9Sstevel@tonic-gate */ 13007c478bd9Sstevel@tonic-gate if (error == ENOTSUP) { 13017c478bd9Sstevel@tonic-gate error = 0; 13027c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = 13037c478bd9Sstevel@tonic-gate NFS4_GETATTR_NOCACHE_OK; 13047c478bd9Sstevel@tonic-gate } 13057c478bd9Sstevel@tonic-gate 13067c478bd9Sstevel@tonic-gate if (error) { 13077c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 13087c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = 13097c478bd9Sstevel@tonic-gate NFS4_GETATTR_ATGID_ERR; 13107c478bd9Sstevel@tonic-gate } else { 13117c478bd9Sstevel@tonic-gate vap->va_gid = gid; 13127c478bd9Sstevel@tonic-gate vap->va_mask |= AT_GID; 13137c478bd9Sstevel@tonic-gate if (pug && gl <= MAX_OG_NAME) { 13147c478bd9Sstevel@tonic-gate pug->gid = gid; 13157c478bd9Sstevel@tonic-gate G_SWAP_CURR_LAST(pug); 13167c478bd9Sstevel@tonic-gate } 13177c478bd9Sstevel@tonic-gate } 13187c478bd9Sstevel@tonic-gate if (group_alloc) { 13197c478bd9Sstevel@tonic-gate kmem_free(group_alloc, *group_length); 13207c478bd9Sstevel@tonic-gate } 13217c478bd9Sstevel@tonic-gate } 13227c478bd9Sstevel@tonic-gate } 13237c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) { 13247c478bd9Sstevel@tonic-gate ASSERT(0); 13257c478bd9Sstevel@tonic-gate } 13267c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) { 13277c478bd9Sstevel@tonic-gate ASSERT(0); 13287c478bd9Sstevel@tonic-gate } 13297c478bd9Sstevel@tonic-gate } 13307c478bd9Sstevel@tonic-gate if (resbmap & 13317c478bd9Sstevel@tonic-gate (FATTR4_QUOTA_USED_MASK | 13327c478bd9Sstevel@tonic-gate FATTR4_SPACE_AVAIL_MASK | 13337c478bd9Sstevel@tonic-gate FATTR4_SPACE_FREE_MASK | 13347c478bd9Sstevel@tonic-gate FATTR4_SPACE_TOTAL_MASK | 13357c478bd9Sstevel@tonic-gate FATTR4_SPACE_USED_MASK | 13367c478bd9Sstevel@tonic-gate FATTR4_SYSTEM_MASK)) { 13377c478bd9Sstevel@tonic-gate 13387c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_QUOTA_USED_MASK) { 13397c478bd9Sstevel@tonic-gate ASSERT(0); 13407c478bd9Sstevel@tonic-gate } 13417c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_RAWDEV_MASK) { 13427c478bd9Sstevel@tonic-gate fattr4_rawdev rawdev; 13437c478bd9Sstevel@tonic-gate if (!xdr_fattr4_rawdev(xdrs, &rawdev)) 13447c478bd9Sstevel@tonic-gate return (FALSE); 13457c478bd9Sstevel@tonic-gate 13467c478bd9Sstevel@tonic-gate if (vap->va_type == VCHR || vap->va_type == VBLK) { 13477c478bd9Sstevel@tonic-gate vap->va_rdev = makedevice(rawdev.specdata1, 13487c478bd9Sstevel@tonic-gate rawdev.specdata2); 13497c478bd9Sstevel@tonic-gate } else { 13507c478bd9Sstevel@tonic-gate vap->va_rdev = 0; 13517c478bd9Sstevel@tonic-gate } 13527c478bd9Sstevel@tonic-gate vap->va_mask |= AT_RDEV; 13537c478bd9Sstevel@tonic-gate } 13547c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SPACE_AVAIL_MASK) { 13557c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 13567c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_sb.f_bavail)) 13577c478bd9Sstevel@tonic-gate return (FALSE); 13587c478bd9Sstevel@tonic-gate gesp->n4g_sb.f_bavail /= DEV_BSIZE; 13597c478bd9Sstevel@tonic-gate } 13607c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SPACE_FREE_MASK) { 13617c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 13627c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_sb.f_bfree)) 13637c478bd9Sstevel@tonic-gate return (FALSE); 13647c478bd9Sstevel@tonic-gate gesp->n4g_sb.f_bfree /= DEV_BSIZE; 13657c478bd9Sstevel@tonic-gate } 13667c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SPACE_TOTAL_MASK) { 13677c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 13687c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_sb.f_blocks)) 13697c478bd9Sstevel@tonic-gate return (FALSE); 13707c478bd9Sstevel@tonic-gate gesp->n4g_sb.f_blocks /= DEV_BSIZE; 13717c478bd9Sstevel@tonic-gate } 13727c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SPACE_USED_MASK) { 13737c478bd9Sstevel@tonic-gate uint64_t space_used; 13747c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 13757c478bd9Sstevel@tonic-gate (u_longlong_t *)&space_used)) 13767c478bd9Sstevel@tonic-gate return (FALSE); 13777c478bd9Sstevel@tonic-gate 13787c478bd9Sstevel@tonic-gate /* Compute space depending on device type */ 13797c478bd9Sstevel@tonic-gate ASSERT((vap->va_mask & AT_TYPE)); 13807c478bd9Sstevel@tonic-gate if (vap->va_type == VREG || vap->va_type == VDIR || 13817c478bd9Sstevel@tonic-gate vap->va_type == VLNK) { 13827c478bd9Sstevel@tonic-gate vap->va_nblocks = (u_longlong_t) 13837c478bd9Sstevel@tonic-gate ((space_used + (offset4)DEV_BSIZE - 13847c478bd9Sstevel@tonic-gate (offset4)1) / (offset4)DEV_BSIZE); 13857c478bd9Sstevel@tonic-gate } else { 13867c478bd9Sstevel@tonic-gate vap->va_nblocks = 0; 13877c478bd9Sstevel@tonic-gate } 13887c478bd9Sstevel@tonic-gate vap->va_mask |= AT_NBLOCKS; 13897c478bd9Sstevel@tonic-gate } 13907c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SYSTEM_MASK) { 13917c478bd9Sstevel@tonic-gate ASSERT(0); 13927c478bd9Sstevel@tonic-gate } 13937c478bd9Sstevel@tonic-gate } 13947c478bd9Sstevel@tonic-gate if (resbmap & 13957c478bd9Sstevel@tonic-gate (FATTR4_TIME_ACCESS_MASK | 13967c478bd9Sstevel@tonic-gate FATTR4_TIME_ACCESS_SET_MASK | 13977c478bd9Sstevel@tonic-gate FATTR4_TIME_BACKUP_MASK | 13987c478bd9Sstevel@tonic-gate FATTR4_TIME_CREATE_MASK | 13997c478bd9Sstevel@tonic-gate FATTR4_TIME_DELTA_MASK | 14007c478bd9Sstevel@tonic-gate FATTR4_TIME_METADATA_MASK | 14017c478bd9Sstevel@tonic-gate FATTR4_TIME_MODIFY_MASK | 14027c478bd9Sstevel@tonic-gate FATTR4_TIME_MODIFY_SET_MASK | 14037c478bd9Sstevel@tonic-gate FATTR4_MOUNTED_ON_FILEID_MASK)) { 14047c478bd9Sstevel@tonic-gate 14057c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_ACCESS_MASK) { 14067c478bd9Sstevel@tonic-gate nfstime4 atime; 14077c478bd9Sstevel@tonic-gate int error; 14087c478bd9Sstevel@tonic-gate 14097c478bd9Sstevel@tonic-gate if (!xdr_longlong_t(xdrs, 14107c478bd9Sstevel@tonic-gate (longlong_t *)&atime.seconds)) 14117c478bd9Sstevel@tonic-gate return (FALSE); 14127c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&atime.nseconds)) 14137c478bd9Sstevel@tonic-gate return (FALSE); 14147c478bd9Sstevel@tonic-gate error = nfs4_time_ntov(&atime, &vap->va_atime); 14157c478bd9Sstevel@tonic-gate if (error) { 14167c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 14177c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR; 14187c478bd9Sstevel@tonic-gate } 14197c478bd9Sstevel@tonic-gate vap->va_mask |= AT_ATIME; 14207c478bd9Sstevel@tonic-gate } 14217c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) { 14227c478bd9Sstevel@tonic-gate ASSERT(0); 14237c478bd9Sstevel@tonic-gate } 14247c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_BACKUP_MASK) { 14257c478bd9Sstevel@tonic-gate ASSERT(0); 14267c478bd9Sstevel@tonic-gate } 14277c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_CREATE_MASK) { 14287c478bd9Sstevel@tonic-gate ASSERT(0); 14297c478bd9Sstevel@tonic-gate } 14307c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_DELTA_MASK) { 14317c478bd9Sstevel@tonic-gate if ((!xdr_u_longlong_t(xdrs, 14327c478bd9Sstevel@tonic-gate (u_longlong_t *)&gesp->n4g_delta.seconds)) || 14337c478bd9Sstevel@tonic-gate (!xdr_u_int(xdrs, &gesp->n4g_delta.nseconds))) 14347c478bd9Sstevel@tonic-gate return (FALSE); 14357c478bd9Sstevel@tonic-gate } 14367c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_METADATA_MASK) { 14377c478bd9Sstevel@tonic-gate nfstime4 mdt; 14387c478bd9Sstevel@tonic-gate int error; 14397c478bd9Sstevel@tonic-gate 14407c478bd9Sstevel@tonic-gate if (!xdr_longlong_t(xdrs, (longlong_t *)&mdt.seconds)) 14417c478bd9Sstevel@tonic-gate return (FALSE); 14427c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&mdt.nseconds)) 14437c478bd9Sstevel@tonic-gate return (FALSE); 14447c478bd9Sstevel@tonic-gate error = nfs4_time_ntov(&mdt, &vap->va_ctime); 14457c478bd9Sstevel@tonic-gate if (error) { 14467c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 14477c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR; 14487c478bd9Sstevel@tonic-gate } 14497c478bd9Sstevel@tonic-gate vap->va_mask |= AT_CTIME; 14507c478bd9Sstevel@tonic-gate } 14517c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_MODIFY_MASK) { 14527c478bd9Sstevel@tonic-gate nfstime4 mtime; 14537c478bd9Sstevel@tonic-gate int error; 14547c478bd9Sstevel@tonic-gate 14557c478bd9Sstevel@tonic-gate if (!xdr_longlong_t(xdrs, 14567c478bd9Sstevel@tonic-gate (longlong_t *)&mtime.seconds)) 14577c478bd9Sstevel@tonic-gate return (FALSE); 14587c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&mtime.nseconds)) 14597c478bd9Sstevel@tonic-gate return (FALSE); 14607c478bd9Sstevel@tonic-gate error = nfs4_time_ntov(&mtime, &vap->va_mtime); 14617c478bd9Sstevel@tonic-gate if (error) { 14627c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 14637c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR; 14647c478bd9Sstevel@tonic-gate } 14657c478bd9Sstevel@tonic-gate vap->va_mask |= AT_MTIME; 14667c478bd9Sstevel@tonic-gate } 14677c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) { 14687c478bd9Sstevel@tonic-gate ASSERT(0); 14697c478bd9Sstevel@tonic-gate } 14707c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) { 14717c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 14727c478bd9Sstevel@tonic-gate (u_longlong_t *)&garp->n4g_mon_fid)) 14737c478bd9Sstevel@tonic-gate return (FALSE); 14747c478bd9Sstevel@tonic-gate garp->n4g_mon_fid_valid = 1; 14757c478bd9Sstevel@tonic-gate } 14767c478bd9Sstevel@tonic-gate } 14777c478bd9Sstevel@tonic-gate 14787c478bd9Sstevel@tonic-gate if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) { 14797c478bd9Sstevel@tonic-gate /* copy only if not provided */ 14807c478bd9Sstevel@tonic-gate if (garp->n4g_ext_res == NULL) { 14817c478bd9Sstevel@tonic-gate garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP); 14827c478bd9Sstevel@tonic-gate bcopy(&ges, garp->n4g_ext_res, sizeof (ges)); 14837c478bd9Sstevel@tonic-gate } 14847c478bd9Sstevel@tonic-gate } 14857c478bd9Sstevel@tonic-gate 14867c478bd9Sstevel@tonic-gate return (TRUE); 14877c478bd9Sstevel@tonic-gate } 14887c478bd9Sstevel@tonic-gate 14897c478bd9Sstevel@tonic-gate /* 14907c478bd9Sstevel@tonic-gate * Inlined version of get_bitmap4 processing 14917c478bd9Sstevel@tonic-gate */ 14927c478bd9Sstevel@tonic-gate bitmap4 14937c478bd9Sstevel@tonic-gate xdr_get_bitmap4_inline(uint32_t **iptr) 14947c478bd9Sstevel@tonic-gate { 14957c478bd9Sstevel@tonic-gate uint32_t resbmaplen; 14967c478bd9Sstevel@tonic-gate bitmap4 bm; 14977c478bd9Sstevel@tonic-gate uint32_t *ptr = *iptr; 14987c478bd9Sstevel@tonic-gate 14997c478bd9Sstevel@tonic-gate /* bitmap LENGTH */ 15007c478bd9Sstevel@tonic-gate resbmaplen = IXDR_GET_U_INT32(ptr); 15017c478bd9Sstevel@tonic-gate 15027c478bd9Sstevel@tonic-gate /* Inline the bitmap and attrlen for common case of two word map */ 15037c478bd9Sstevel@tonic-gate if (resbmaplen == 2) { 15047c478bd9Sstevel@tonic-gate IXDR_GET_HYPER(ptr, bm); 15057c478bd9Sstevel@tonic-gate *iptr = ptr; 15067c478bd9Sstevel@tonic-gate return (bm); 15077c478bd9Sstevel@tonic-gate } 15087c478bd9Sstevel@tonic-gate 15097c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN) 15107c478bd9Sstevel@tonic-gate bm = IXDR_GET_U_INT32(ptr); 15117c478bd9Sstevel@tonic-gate if (--resbmaplen == 0) { 15127c478bd9Sstevel@tonic-gate *iptr = ptr; 15137c478bd9Sstevel@tonic-gate return (bm); 15147c478bd9Sstevel@tonic-gate } 15157c478bd9Sstevel@tonic-gate *((uint32_t *)&bm) |= IXDR_GET_U_INT32(ptr); 15167c478bd9Sstevel@tonic-gate if (--resbmaplen == 0) { 15177c478bd9Sstevel@tonic-gate *iptr = ptr; 15187c478bd9Sstevel@tonic-gate return (bm); 15197c478bd9Sstevel@tonic-gate } 15207c478bd9Sstevel@tonic-gate ptr += resbmaplen; 15217c478bd9Sstevel@tonic-gate *iptr = ptr; 15227c478bd9Sstevel@tonic-gate return (bm); 15237c478bd9Sstevel@tonic-gate #elif defined(_BIG_ENDIAN) 15247c478bd9Sstevel@tonic-gate *((uint32_t *)&bm) = IXDR_GET_U_INT32(ptr); 15257c478bd9Sstevel@tonic-gate if (--resbmaplen == 0) { 15267c478bd9Sstevel@tonic-gate *iptr = ptr; 15277c478bd9Sstevel@tonic-gate return (bm); 15287c478bd9Sstevel@tonic-gate } 15297c478bd9Sstevel@tonic-gate bm |= IXDR_GET_U_INT32(ptr); 15307c478bd9Sstevel@tonic-gate if (--resbmaplen == 0) { 15317c478bd9Sstevel@tonic-gate *iptr = ptr; 15327c478bd9Sstevel@tonic-gate return (bm); 15337c478bd9Sstevel@tonic-gate } 15347c478bd9Sstevel@tonic-gate ptr += resbmaplen; 15357c478bd9Sstevel@tonic-gate *iptr = ptr; 15367c478bd9Sstevel@tonic-gate return (bm); 15377c478bd9Sstevel@tonic-gate #else 15387c478bd9Sstevel@tonic-gate ASSERT(0); 15397c478bd9Sstevel@tonic-gate ptr += resbmaplen; 15407c478bd9Sstevel@tonic-gate *iptr = ptr; 15417c478bd9Sstevel@tonic-gate return (0); 15427c478bd9Sstevel@tonic-gate #endif 15437c478bd9Sstevel@tonic-gate } 15447c478bd9Sstevel@tonic-gate 15457c478bd9Sstevel@tonic-gate static bool_t 15467c478bd9Sstevel@tonic-gate xdr_ga_fattr_res_inline(uint32_t *ptr, struct nfs4_ga_res *garp, 15477c478bd9Sstevel@tonic-gate bitmap4 resbmap, bitmap4 argbmap, struct mntinfo4 *mi, 15487c478bd9Sstevel@tonic-gate ug_cache_t *pug) 15497c478bd9Sstevel@tonic-gate { 15507c478bd9Sstevel@tonic-gate int truefalse; 15517c478bd9Sstevel@tonic-gate struct nfs4_ga_ext_res ges, *gesp; 15527c478bd9Sstevel@tonic-gate vattr_t *vap = &garp->n4g_va; 15537c478bd9Sstevel@tonic-gate 15547c478bd9Sstevel@tonic-gate if (garp->n4g_ext_res) 15557c478bd9Sstevel@tonic-gate gesp = garp->n4g_ext_res; 15567c478bd9Sstevel@tonic-gate else 15577c478bd9Sstevel@tonic-gate gesp = ⩾ 15587c478bd9Sstevel@tonic-gate 15597c478bd9Sstevel@tonic-gate vap->va_mask = 0; 15607c478bd9Sstevel@tonic-gate 15617c478bd9Sstevel@tonic-gate /* Check to see if the vattr should be pre-filled */ 15627c478bd9Sstevel@tonic-gate if (argbmap & NFS4_VATTR_MASK) 15637c478bd9Sstevel@tonic-gate xdr_ga_prefill_vattr(garp, mi); 15647c478bd9Sstevel@tonic-gate 15657c478bd9Sstevel@tonic-gate if (argbmap & NFS4_STATFS_ATTR_MASK) 15667c478bd9Sstevel@tonic-gate xdr_ga_prefill_statvfs(gesp, mi); 15677c478bd9Sstevel@tonic-gate 15687c478bd9Sstevel@tonic-gate if (resbmap & 15697c478bd9Sstevel@tonic-gate (FATTR4_SUPPORTED_ATTRS_MASK | 15707c478bd9Sstevel@tonic-gate FATTR4_TYPE_MASK | 15717c478bd9Sstevel@tonic-gate FATTR4_FH_EXPIRE_TYPE_MASK | 15727c478bd9Sstevel@tonic-gate FATTR4_CHANGE_MASK | 15737c478bd9Sstevel@tonic-gate FATTR4_SIZE_MASK | 15747c478bd9Sstevel@tonic-gate FATTR4_LINK_SUPPORT_MASK | 15757c478bd9Sstevel@tonic-gate FATTR4_SYMLINK_SUPPORT_MASK | 15767c478bd9Sstevel@tonic-gate FATTR4_NAMED_ATTR_MASK)) { 15777c478bd9Sstevel@tonic-gate 15787c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SUPPORTED_ATTRS_MASK) { 15797c478bd9Sstevel@tonic-gate gesp->n4g_suppattrs = xdr_get_bitmap4_inline(&ptr); 15807c478bd9Sstevel@tonic-gate } 15817c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TYPE_MASK) { 15827c478bd9Sstevel@tonic-gate vap->va_type = IXDR_GET_U_INT32(ptr); 15837c478bd9Sstevel@tonic-gate 15842c2d21e9SRichard Lowe if ((nfs_ftype4)vap->va_type < NF4REG || 15852c2d21e9SRichard Lowe (nfs_ftype4)vap->va_type > NF4NAMEDATTR) 15867c478bd9Sstevel@tonic-gate vap->va_type = VBAD; 15877c478bd9Sstevel@tonic-gate else 15887c478bd9Sstevel@tonic-gate vap->va_type = nf4_to_vt[vap->va_type]; 15897c478bd9Sstevel@tonic-gate if (vap->va_type == VBLK) 15907c478bd9Sstevel@tonic-gate vap->va_blksize = DEV_BSIZE; 15917c478bd9Sstevel@tonic-gate 15927c478bd9Sstevel@tonic-gate vap->va_mask |= AT_TYPE; 15937c478bd9Sstevel@tonic-gate } 15947c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FH_EXPIRE_TYPE_MASK) { 15957c478bd9Sstevel@tonic-gate gesp->n4g_fet = IXDR_GET_U_INT32(ptr); 15967c478bd9Sstevel@tonic-gate } 15977c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CHANGE_MASK) { 15987c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, garp->n4g_change); 15997c478bd9Sstevel@tonic-gate garp->n4g_change_valid = 1; 16007c478bd9Sstevel@tonic-gate } 16017c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SIZE_MASK) { 16027c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, vap->va_size); 16037c478bd9Sstevel@tonic-gate 16047c478bd9Sstevel@tonic-gate if (!NFS4_SIZE_OK(vap->va_size)) { 16057c478bd9Sstevel@tonic-gate garp->n4g_attrerr = EFBIG; 16067c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = NFS4_GETATTR_ATSIZE_ERR; 16077c478bd9Sstevel@tonic-gate } else { 16087c478bd9Sstevel@tonic-gate vap->va_mask |= AT_SIZE; 16097c478bd9Sstevel@tonic-gate } 16107c478bd9Sstevel@tonic-gate } 16117c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_LINK_SUPPORT_MASK) { 16127c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 16137c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_link_support = 16147c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 16157c478bd9Sstevel@tonic-gate } 16167c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SYMLINK_SUPPORT_MASK) { 16177c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 16187c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_symlink_support = 16197c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 16207c478bd9Sstevel@tonic-gate } 16217c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_NAMED_ATTR_MASK) { 16227c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 16237c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_xattr_exists = TRUE; 16247c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_xattr_exists = 16257c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 16267c478bd9Sstevel@tonic-gate } 16277c478bd9Sstevel@tonic-gate } 16287c478bd9Sstevel@tonic-gate if (resbmap & 16297c478bd9Sstevel@tonic-gate (FATTR4_FSID_MASK | 16307c478bd9Sstevel@tonic-gate FATTR4_UNIQUE_HANDLES_MASK | 16317c478bd9Sstevel@tonic-gate FATTR4_LEASE_TIME_MASK | 16327c478bd9Sstevel@tonic-gate FATTR4_RDATTR_ERROR_MASK)) { 16337c478bd9Sstevel@tonic-gate 16347c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FSID_MASK) { 16357c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.major); 16367c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, garp->n4g_fsid.minor); 16377c478bd9Sstevel@tonic-gate garp->n4g_fsid_valid = 1; 16387c478bd9Sstevel@tonic-gate } 16397c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_UNIQUE_HANDLES_MASK) { 16407c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 16417c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_unique_handles = 16427c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 16437c478bd9Sstevel@tonic-gate } 16447c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_LEASE_TIME_MASK) { 16457c478bd9Sstevel@tonic-gate gesp->n4g_leasetime = IXDR_GET_U_INT32(ptr); 16467c478bd9Sstevel@tonic-gate } 16477c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_RDATTR_ERROR_MASK) { 16487c478bd9Sstevel@tonic-gate gesp->n4g_rdattr_error = IXDR_GET_U_INT32(ptr); 16497c478bd9Sstevel@tonic-gate } 16507c478bd9Sstevel@tonic-gate } 16517c478bd9Sstevel@tonic-gate if (resbmap & 16527c478bd9Sstevel@tonic-gate (FATTR4_ACL_MASK | 16537c478bd9Sstevel@tonic-gate FATTR4_ACLSUPPORT_MASK | 16547c478bd9Sstevel@tonic-gate FATTR4_ARCHIVE_MASK | 16557c478bd9Sstevel@tonic-gate FATTR4_CANSETTIME_MASK)) { 16567c478bd9Sstevel@tonic-gate 16577c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_ACL_MASK) { 16587c478bd9Sstevel@tonic-gate ASSERT(0); 16597c478bd9Sstevel@tonic-gate } 16607c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_ACLSUPPORT_MASK) { 16617c478bd9Sstevel@tonic-gate gesp->n4g_aclsupport = IXDR_GET_U_INT32(ptr); 16627c478bd9Sstevel@tonic-gate } 16637c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_ARCHIVE_MASK) { 16647c478bd9Sstevel@tonic-gate ASSERT(0); 16657c478bd9Sstevel@tonic-gate } 16667c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CANSETTIME_MASK) { 16677c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 16687c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_cansettime = 16697c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 16707c478bd9Sstevel@tonic-gate } 16717c478bd9Sstevel@tonic-gate } 16727c478bd9Sstevel@tonic-gate if (resbmap & 16737c478bd9Sstevel@tonic-gate (FATTR4_CASE_INSENSITIVE_MASK | 16747c478bd9Sstevel@tonic-gate FATTR4_CASE_PRESERVING_MASK | 16757c478bd9Sstevel@tonic-gate FATTR4_CHOWN_RESTRICTED_MASK | 16767c478bd9Sstevel@tonic-gate FATTR4_FILEHANDLE_MASK | 16777c478bd9Sstevel@tonic-gate FATTR4_FILEID_MASK | 16787c478bd9Sstevel@tonic-gate FATTR4_FILES_AVAIL_MASK | 16797c478bd9Sstevel@tonic-gate FATTR4_FILES_FREE_MASK | 16807c478bd9Sstevel@tonic-gate FATTR4_FILES_TOTAL_MASK)) { 16817c478bd9Sstevel@tonic-gate 16827c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CASE_INSENSITIVE_MASK) { 16837c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 16847c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_case_insensitive = 16857c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 16867c478bd9Sstevel@tonic-gate } 16877c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CASE_PRESERVING_MASK) { 16887c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 16897c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_case_preserving = 16907c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 16917c478bd9Sstevel@tonic-gate } 16927c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_CHOWN_RESTRICTED_MASK) { 16937c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 16947c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_chown_restricted = 16957c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 16967c478bd9Sstevel@tonic-gate } 16977c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILEHANDLE_MASK) { 16987c478bd9Sstevel@tonic-gate int len = IXDR_GET_U_INT32(ptr); 16997c478bd9Sstevel@tonic-gate 17007c478bd9Sstevel@tonic-gate gesp->n4g_fh_u.nfs_fh4_alt.len = 0; 17017c478bd9Sstevel@tonic-gate gesp->n4g_fh_u.nfs_fh4_alt.val = 17027c478bd9Sstevel@tonic-gate gesp->n4g_fh_u.nfs_fh4_alt.data; 17037c478bd9Sstevel@tonic-gate gesp->n4g_fh_u.n4g_fh.nfs_fh4_len = len; 17047c478bd9Sstevel@tonic-gate 17057c478bd9Sstevel@tonic-gate bcopy(ptr, gesp->n4g_fh_u.n4g_fh.nfs_fh4_val, len); 17067c478bd9Sstevel@tonic-gate 17077c478bd9Sstevel@tonic-gate ptr += RNDUP(len) / BYTES_PER_XDR_UNIT; 17087c478bd9Sstevel@tonic-gate } 17097c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILEID_MASK) { 17107c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, vap->va_nodeid); 17117c478bd9Sstevel@tonic-gate vap->va_mask |= AT_NODEID; 17127c478bd9Sstevel@tonic-gate } 17137c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILES_AVAIL_MASK) { 17147c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_favail); 17157c478bd9Sstevel@tonic-gate } 17167c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILES_FREE_MASK) { 17177c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_ffree); 17187c478bd9Sstevel@tonic-gate } 17197c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FILES_TOTAL_MASK) { 17207c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_files); 17217c478bd9Sstevel@tonic-gate } 17227c478bd9Sstevel@tonic-gate } 17237c478bd9Sstevel@tonic-gate if (resbmap & 17247c478bd9Sstevel@tonic-gate (FATTR4_FS_LOCATIONS_MASK | 17257c478bd9Sstevel@tonic-gate FATTR4_HIDDEN_MASK | 17267c478bd9Sstevel@tonic-gate FATTR4_HOMOGENEOUS_MASK)) { 17277c478bd9Sstevel@tonic-gate 17287c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_FS_LOCATIONS_MASK) { 17297c478bd9Sstevel@tonic-gate ASSERT(0); 17307c478bd9Sstevel@tonic-gate } 17317c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_HIDDEN_MASK) { 17327c478bd9Sstevel@tonic-gate ASSERT(0); 17337c478bd9Sstevel@tonic-gate } 17347c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_HOMOGENEOUS_MASK) { 17357c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 17367c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_homogeneous = 17377c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 17387c478bd9Sstevel@tonic-gate } 17397c478bd9Sstevel@tonic-gate } 17407c478bd9Sstevel@tonic-gate if (resbmap & 17417c478bd9Sstevel@tonic-gate (FATTR4_MAXFILESIZE_MASK | 17427c478bd9Sstevel@tonic-gate FATTR4_MAXLINK_MASK | 17437c478bd9Sstevel@tonic-gate FATTR4_MAXNAME_MASK | 17447c478bd9Sstevel@tonic-gate FATTR4_MAXREAD_MASK | 17457c478bd9Sstevel@tonic-gate FATTR4_MAXWRITE_MASK)) { 17467c478bd9Sstevel@tonic-gate 17477c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXFILESIZE_MASK) { 17487c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_maxfilesize); 17497c478bd9Sstevel@tonic-gate } 17507c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXLINK_MASK) { 17517c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_link_max = IXDR_GET_U_INT32(ptr); 17527c478bd9Sstevel@tonic-gate } 17537c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXNAME_MASK) { 17547c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_name_max = IXDR_GET_U_INT32(ptr); 17557c478bd9Sstevel@tonic-gate gesp->n4g_sb.f_namemax = gesp->n4g_pc4.pc4_name_max; 17567c478bd9Sstevel@tonic-gate } 17577c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXREAD_MASK) { 17587c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_maxread); 17597c478bd9Sstevel@tonic-gate } 17607c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MAXWRITE_MASK) { 17617c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_maxwrite); 17627c478bd9Sstevel@tonic-gate } 17637c478bd9Sstevel@tonic-gate } 17647c478bd9Sstevel@tonic-gate if (resbmap & 17657c478bd9Sstevel@tonic-gate (FATTR4_MIMETYPE_MASK | 17667c478bd9Sstevel@tonic-gate FATTR4_MODE_MASK | 17677c478bd9Sstevel@tonic-gate FATTR4_NO_TRUNC_MASK | 17687c478bd9Sstevel@tonic-gate FATTR4_NUMLINKS_MASK)) { 17697c478bd9Sstevel@tonic-gate 17707c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MIMETYPE_MASK) { 17717c478bd9Sstevel@tonic-gate ASSERT(0); 17727c478bd9Sstevel@tonic-gate } 17737c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MODE_MASK) { 17747c478bd9Sstevel@tonic-gate vap->va_mode = IXDR_GET_U_INT32(ptr); 17757c478bd9Sstevel@tonic-gate vap->va_mask |= AT_MODE; 17767c478bd9Sstevel@tonic-gate } 17777c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_NO_TRUNC_MASK) { 17787c478bd9Sstevel@tonic-gate truefalse = IXDR_GET_U_INT32(ptr); 17797c478bd9Sstevel@tonic-gate gesp->n4g_pc4.pc4_no_trunc = 17807c478bd9Sstevel@tonic-gate (truefalse ? TRUE : FALSE); 17817c478bd9Sstevel@tonic-gate } 17827c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_NUMLINKS_MASK) { 17837c478bd9Sstevel@tonic-gate vap->va_nlink = IXDR_GET_U_INT32(ptr); 17847c478bd9Sstevel@tonic-gate vap->va_mask |= AT_NLINK; 17857c478bd9Sstevel@tonic-gate } 17867c478bd9Sstevel@tonic-gate } 17877c478bd9Sstevel@tonic-gate if (resbmap & 17887c478bd9Sstevel@tonic-gate (FATTR4_OWNER_MASK | 17897c478bd9Sstevel@tonic-gate FATTR4_OWNER_GROUP_MASK | 17907c478bd9Sstevel@tonic-gate FATTR4_QUOTA_AVAIL_HARD_MASK | 17917c478bd9Sstevel@tonic-gate FATTR4_QUOTA_AVAIL_SOFT_MASK)) { 17927c478bd9Sstevel@tonic-gate 17937c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_OWNER_MASK) { 17947c478bd9Sstevel@tonic-gate uint_t *owner_length, ol; 17957c478bd9Sstevel@tonic-gate char *owner_val = NULL; 17967c478bd9Sstevel@tonic-gate utf8string ov; 17977c478bd9Sstevel@tonic-gate int error; 17987c478bd9Sstevel@tonic-gate 17997c478bd9Sstevel@tonic-gate /* get the OWNER_LENGTH */ 18007c478bd9Sstevel@tonic-gate ol = IXDR_GET_U_INT32(ptr); 18017c478bd9Sstevel@tonic-gate 18027c478bd9Sstevel@tonic-gate /* Manage the owner length location */ 18037c478bd9Sstevel@tonic-gate if (pug && ol <= MAX_OG_NAME) { 18047c478bd9Sstevel@tonic-gate owner_length = &pug->u_curr.utf8string_len; 18057c478bd9Sstevel@tonic-gate *owner_length = ol; 18067c478bd9Sstevel@tonic-gate } else { 18077c478bd9Sstevel@tonic-gate owner_length = &ol; 18087c478bd9Sstevel@tonic-gate } 18097c478bd9Sstevel@tonic-gate 18107c478bd9Sstevel@tonic-gate /* find memory to store the decode */ 18117c478bd9Sstevel@tonic-gate if (*owner_length > MAX_OG_NAME || pug == NULL) 18127c478bd9Sstevel@tonic-gate owner_val = (char *)ptr; 18137c478bd9Sstevel@tonic-gate else 18147c478bd9Sstevel@tonic-gate owner_val = (char *)ptr; 18157c478bd9Sstevel@tonic-gate 18167c478bd9Sstevel@tonic-gate /* Optimize for matching if called for */ 18177c478bd9Sstevel@tonic-gate if (pug && 18187c478bd9Sstevel@tonic-gate *owner_length == pug->u_last.utf8string_len && 18197c478bd9Sstevel@tonic-gate bcmp(owner_val, pug->u_last.utf8string_val, 18207c478bd9Sstevel@tonic-gate *owner_length) == 0) { 18217c478bd9Sstevel@tonic-gate vap->va_uid = pug->uid; 18227c478bd9Sstevel@tonic-gate vap->va_mask |= AT_UID; 18237c478bd9Sstevel@tonic-gate } else { 18247c478bd9Sstevel@tonic-gate uid_t uid; 18257c478bd9Sstevel@tonic-gate 18267c478bd9Sstevel@tonic-gate ov.utf8string_len = *owner_length; 18277c478bd9Sstevel@tonic-gate ov.utf8string_val = owner_val; 18287c478bd9Sstevel@tonic-gate error = nfs_idmap_str_uid(&ov, &uid, FALSE); 18297c478bd9Sstevel@tonic-gate /* 18307c478bd9Sstevel@tonic-gate * String was mapped, but to nobody because 18317c478bd9Sstevel@tonic-gate * we are nfsmapid, indicate it should not 18327c478bd9Sstevel@tonic-gate * be cached. 18337c478bd9Sstevel@tonic-gate */ 18347c478bd9Sstevel@tonic-gate if (error == ENOTSUP) { 18357c478bd9Sstevel@tonic-gate error = 0; 18367c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = 18377c478bd9Sstevel@tonic-gate NFS4_GETATTR_NOCACHE_OK; 18387c478bd9Sstevel@tonic-gate } 18397c478bd9Sstevel@tonic-gate 18407c478bd9Sstevel@tonic-gate if (error) { 18417c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 18427c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = 18437c478bd9Sstevel@tonic-gate NFS4_GETATTR_ATUID_ERR; 18447c478bd9Sstevel@tonic-gate } else { 18457c478bd9Sstevel@tonic-gate vap->va_uid = uid; 18467c478bd9Sstevel@tonic-gate vap->va_mask |= AT_UID; 18477c478bd9Sstevel@tonic-gate /* save the results for next time */ 18487c478bd9Sstevel@tonic-gate if (pug && ol <= MAX_OG_NAME) { 18497c478bd9Sstevel@tonic-gate pug->uid = uid; 18507c478bd9Sstevel@tonic-gate pug->u_curr.utf8string_len = 18517c478bd9Sstevel@tonic-gate ov.utf8string_len; 18527c478bd9Sstevel@tonic-gate bcopy(owner_val, 18530a701b1eSRobert Gordon pug->u_curr.utf8string_val, 18540a701b1eSRobert Gordon ol); 18557c478bd9Sstevel@tonic-gate U_SWAP_CURR_LAST(pug); 18567c478bd9Sstevel@tonic-gate } 18577c478bd9Sstevel@tonic-gate } 18587c478bd9Sstevel@tonic-gate } 18597c478bd9Sstevel@tonic-gate ptr += RNDUP(ol) / BYTES_PER_XDR_UNIT; 18607c478bd9Sstevel@tonic-gate } 18617c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_OWNER_GROUP_MASK) { 18627c478bd9Sstevel@tonic-gate uint_t *group_length, gl; 18637c478bd9Sstevel@tonic-gate char *group_val = NULL; 18647c478bd9Sstevel@tonic-gate utf8string gv; 18657c478bd9Sstevel@tonic-gate int error; 18667c478bd9Sstevel@tonic-gate 18677c478bd9Sstevel@tonic-gate /* get the OWNER_GROUP_LENGTH */ 18687c478bd9Sstevel@tonic-gate gl = IXDR_GET_U_INT32(ptr); 18697c478bd9Sstevel@tonic-gate 18707c478bd9Sstevel@tonic-gate /* Manage the group length location */ 18717c478bd9Sstevel@tonic-gate if (pug && gl <= MAX_OG_NAME) { 18727c478bd9Sstevel@tonic-gate group_length = &pug->g_curr.utf8string_len; 18737c478bd9Sstevel@tonic-gate *group_length = gl; 18747c478bd9Sstevel@tonic-gate } else { 18757c478bd9Sstevel@tonic-gate group_length = ≷ 18767c478bd9Sstevel@tonic-gate } 18777c478bd9Sstevel@tonic-gate 18787c478bd9Sstevel@tonic-gate /* find memory to store the decode */ 18797c478bd9Sstevel@tonic-gate if (*group_length > MAX_OG_NAME || pug == NULL) 18807c478bd9Sstevel@tonic-gate group_val = (char *)ptr; 18817c478bd9Sstevel@tonic-gate else 18827c478bd9Sstevel@tonic-gate group_val = (char *)ptr; 18837c478bd9Sstevel@tonic-gate 18847c478bd9Sstevel@tonic-gate /* Optimize for matching if called for */ 18857c478bd9Sstevel@tonic-gate if (pug && 18867c478bd9Sstevel@tonic-gate *group_length == pug->g_last.utf8string_len && 18877c478bd9Sstevel@tonic-gate bcmp(group_val, pug->g_last.utf8string_val, 18887c478bd9Sstevel@tonic-gate *group_length) == 0) { 18897c478bd9Sstevel@tonic-gate vap->va_gid = pug->gid; 18907c478bd9Sstevel@tonic-gate vap->va_mask |= AT_GID; 18917c478bd9Sstevel@tonic-gate } else { 18927c478bd9Sstevel@tonic-gate uid_t gid; 18937c478bd9Sstevel@tonic-gate 18947c478bd9Sstevel@tonic-gate gv.utf8string_len = *group_length; 18957c478bd9Sstevel@tonic-gate gv.utf8string_val = group_val; 18967c478bd9Sstevel@tonic-gate error = nfs_idmap_str_gid(&gv, &gid, FALSE); 18977c478bd9Sstevel@tonic-gate /* 18987c478bd9Sstevel@tonic-gate * String was mapped, but to nobody because 18997c478bd9Sstevel@tonic-gate * we are nfsmapid, indicate it should not 19007c478bd9Sstevel@tonic-gate * be cached. 19017c478bd9Sstevel@tonic-gate */ 19027c478bd9Sstevel@tonic-gate if (error == ENOTSUP) { 19037c478bd9Sstevel@tonic-gate error = 0; 19047c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = 19057c478bd9Sstevel@tonic-gate NFS4_GETATTR_NOCACHE_OK; 19067c478bd9Sstevel@tonic-gate } 19077c478bd9Sstevel@tonic-gate 19087c478bd9Sstevel@tonic-gate if (error) { 19097c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 19107c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = 19117c478bd9Sstevel@tonic-gate NFS4_GETATTR_ATGID_ERR; 19127c478bd9Sstevel@tonic-gate } else { 19137c478bd9Sstevel@tonic-gate vap->va_gid = gid; 19147c478bd9Sstevel@tonic-gate vap->va_mask |= AT_GID; 19157c478bd9Sstevel@tonic-gate if (pug && gl <= MAX_OG_NAME) { 19167c478bd9Sstevel@tonic-gate pug->gid = gid; 19177c478bd9Sstevel@tonic-gate pug->g_curr.utf8string_len = 19187c478bd9Sstevel@tonic-gate gv.utf8string_len; 19197c478bd9Sstevel@tonic-gate bcopy(group_val, 19207c478bd9Sstevel@tonic-gate pug->g_curr.utf8string_val, 19217c478bd9Sstevel@tonic-gate gl); 19227c478bd9Sstevel@tonic-gate G_SWAP_CURR_LAST(pug); 19237c478bd9Sstevel@tonic-gate } 19247c478bd9Sstevel@tonic-gate } 19257c478bd9Sstevel@tonic-gate } 19267c478bd9Sstevel@tonic-gate ptr += RNDUP(gl) / BYTES_PER_XDR_UNIT; 19277c478bd9Sstevel@tonic-gate } 19287c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_QUOTA_AVAIL_HARD_MASK) { 19297c478bd9Sstevel@tonic-gate ASSERT(0); 19307c478bd9Sstevel@tonic-gate } 19317c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_QUOTA_AVAIL_SOFT_MASK) { 19327c478bd9Sstevel@tonic-gate ASSERT(0); 19337c478bd9Sstevel@tonic-gate } 19347c478bd9Sstevel@tonic-gate } 19357c478bd9Sstevel@tonic-gate if (resbmap & 19367c478bd9Sstevel@tonic-gate (FATTR4_QUOTA_USED_MASK | 19377c478bd9Sstevel@tonic-gate FATTR4_SPACE_AVAIL_MASK | 19387c478bd9Sstevel@tonic-gate FATTR4_SPACE_FREE_MASK | 19397c478bd9Sstevel@tonic-gate FATTR4_SPACE_TOTAL_MASK | 19407c478bd9Sstevel@tonic-gate FATTR4_SPACE_USED_MASK | 19417c478bd9Sstevel@tonic-gate FATTR4_SYSTEM_MASK)) { 19427c478bd9Sstevel@tonic-gate 19437c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_QUOTA_USED_MASK) { 19447c478bd9Sstevel@tonic-gate ASSERT(0); 19457c478bd9Sstevel@tonic-gate } 19467c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_RAWDEV_MASK) { 19477c478bd9Sstevel@tonic-gate fattr4_rawdev rawdev; 19487c478bd9Sstevel@tonic-gate 19497c478bd9Sstevel@tonic-gate rawdev.specdata1 = IXDR_GET_U_INT32(ptr); 19507c478bd9Sstevel@tonic-gate rawdev.specdata2 = IXDR_GET_U_INT32(ptr); 19517c478bd9Sstevel@tonic-gate 19527c478bd9Sstevel@tonic-gate if (vap->va_type == VCHR || vap->va_type == VBLK) { 19537c478bd9Sstevel@tonic-gate vap->va_rdev = makedevice(rawdev.specdata1, 19547c478bd9Sstevel@tonic-gate rawdev.specdata2); 19557c478bd9Sstevel@tonic-gate } else { 19567c478bd9Sstevel@tonic-gate vap->va_rdev = 0; 19577c478bd9Sstevel@tonic-gate } 19587c478bd9Sstevel@tonic-gate vap->va_mask |= AT_RDEV; 19597c478bd9Sstevel@tonic-gate } 19607c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SPACE_AVAIL_MASK) { 19617c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bavail); 19627c478bd9Sstevel@tonic-gate gesp->n4g_sb.f_bavail /= DEV_BSIZE; 19637c478bd9Sstevel@tonic-gate } 19647c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SPACE_FREE_MASK) { 19657c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_bfree); 19667c478bd9Sstevel@tonic-gate gesp->n4g_sb.f_bfree /= DEV_BSIZE; 19677c478bd9Sstevel@tonic-gate } 19687c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SPACE_TOTAL_MASK) { 19697c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_sb.f_blocks); 19707c478bd9Sstevel@tonic-gate gesp->n4g_sb.f_blocks /= DEV_BSIZE; 19717c478bd9Sstevel@tonic-gate } 19727c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SPACE_USED_MASK) { 19737c478bd9Sstevel@tonic-gate uint64_t space_used; 19747c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, space_used); 19757c478bd9Sstevel@tonic-gate 19767c478bd9Sstevel@tonic-gate /* Compute space depending on device type */ 19777c478bd9Sstevel@tonic-gate ASSERT((vap->va_mask & AT_TYPE)); 19787c478bd9Sstevel@tonic-gate if (vap->va_type == VREG || vap->va_type == VDIR || 19797c478bd9Sstevel@tonic-gate vap->va_type == VLNK) { 19807c478bd9Sstevel@tonic-gate vap->va_nblocks = (u_longlong_t) 19817c478bd9Sstevel@tonic-gate ((space_used + (offset4)DEV_BSIZE - 19827c478bd9Sstevel@tonic-gate (offset4)1) / (offset4)DEV_BSIZE); 19837c478bd9Sstevel@tonic-gate } else { 19847c478bd9Sstevel@tonic-gate vap->va_nblocks = 0; 19857c478bd9Sstevel@tonic-gate } 19867c478bd9Sstevel@tonic-gate vap->va_mask |= AT_NBLOCKS; 19877c478bd9Sstevel@tonic-gate } 19887c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_SYSTEM_MASK) { 19897c478bd9Sstevel@tonic-gate ASSERT(0); 19907c478bd9Sstevel@tonic-gate } 19917c478bd9Sstevel@tonic-gate } 19927c478bd9Sstevel@tonic-gate if (resbmap & 19937c478bd9Sstevel@tonic-gate (FATTR4_TIME_ACCESS_MASK | 19947c478bd9Sstevel@tonic-gate FATTR4_TIME_ACCESS_SET_MASK | 19957c478bd9Sstevel@tonic-gate FATTR4_TIME_BACKUP_MASK | 19967c478bd9Sstevel@tonic-gate FATTR4_TIME_CREATE_MASK | 19977c478bd9Sstevel@tonic-gate FATTR4_TIME_DELTA_MASK | 19987c478bd9Sstevel@tonic-gate FATTR4_TIME_METADATA_MASK | 19997c478bd9Sstevel@tonic-gate FATTR4_TIME_MODIFY_MASK | 20007c478bd9Sstevel@tonic-gate FATTR4_TIME_MODIFY_SET_MASK | 20017c478bd9Sstevel@tonic-gate FATTR4_MOUNTED_ON_FILEID_MASK)) { 20027c478bd9Sstevel@tonic-gate 20037c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_ACCESS_MASK) { 20047c478bd9Sstevel@tonic-gate nfstime4 atime; 20057c478bd9Sstevel@tonic-gate int error; 20067c478bd9Sstevel@tonic-gate 20077c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, atime.seconds); 20087c478bd9Sstevel@tonic-gate atime.nseconds = IXDR_GET_U_INT32(ptr); 20097c478bd9Sstevel@tonic-gate 20107c478bd9Sstevel@tonic-gate error = nfs4_time_ntov(&atime, &vap->va_atime); 20117c478bd9Sstevel@tonic-gate if (error) { 20127c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 20137c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = NFS4_GETATTR_ATATIME_ERR; 20147c478bd9Sstevel@tonic-gate } 20157c478bd9Sstevel@tonic-gate vap->va_mask |= AT_ATIME; 20167c478bd9Sstevel@tonic-gate } 20177c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_ACCESS_SET_MASK) { 20187c478bd9Sstevel@tonic-gate ASSERT(0); 20197c478bd9Sstevel@tonic-gate } 20207c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_BACKUP_MASK) { 20217c478bd9Sstevel@tonic-gate ASSERT(0); 20227c478bd9Sstevel@tonic-gate } 20237c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_CREATE_MASK) { 20247c478bd9Sstevel@tonic-gate ASSERT(0); 20257c478bd9Sstevel@tonic-gate } 20267c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_DELTA_MASK) { 20277c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, gesp->n4g_delta.seconds); 20287c478bd9Sstevel@tonic-gate gesp->n4g_delta.nseconds = IXDR_GET_U_INT32(ptr); 20297c478bd9Sstevel@tonic-gate } 20307c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_METADATA_MASK) { 20317c478bd9Sstevel@tonic-gate nfstime4 mdt; 20327c478bd9Sstevel@tonic-gate int error; 20337c478bd9Sstevel@tonic-gate 20347c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, mdt.seconds); 20357c478bd9Sstevel@tonic-gate mdt.nseconds = IXDR_GET_U_INT32(ptr); 20367c478bd9Sstevel@tonic-gate 20377c478bd9Sstevel@tonic-gate error = nfs4_time_ntov(&mdt, &vap->va_ctime); 20387c478bd9Sstevel@tonic-gate if (error) { 20397c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 20407c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = NFS4_GETATTR_ATCTIME_ERR; 20417c478bd9Sstevel@tonic-gate } 20427c478bd9Sstevel@tonic-gate vap->va_mask |= AT_CTIME; 20437c478bd9Sstevel@tonic-gate } 20447c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_MODIFY_MASK) { 20457c478bd9Sstevel@tonic-gate nfstime4 mtime; 20467c478bd9Sstevel@tonic-gate int error; 20477c478bd9Sstevel@tonic-gate 20487c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, mtime.seconds); 20497c478bd9Sstevel@tonic-gate mtime.nseconds = IXDR_GET_U_INT32(ptr); 20507c478bd9Sstevel@tonic-gate 20517c478bd9Sstevel@tonic-gate error = nfs4_time_ntov(&mtime, &vap->va_mtime); 20527c478bd9Sstevel@tonic-gate if (error) { 20537c478bd9Sstevel@tonic-gate garp->n4g_attrerr = error; 20547c478bd9Sstevel@tonic-gate garp->n4g_attrwhy = NFS4_GETATTR_ATMTIME_ERR; 20557c478bd9Sstevel@tonic-gate } 20567c478bd9Sstevel@tonic-gate vap->va_mask |= AT_MTIME; 20577c478bd9Sstevel@tonic-gate } 20587c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_TIME_MODIFY_SET_MASK) { 20597c478bd9Sstevel@tonic-gate ASSERT(0); 20607c478bd9Sstevel@tonic-gate } 20617c478bd9Sstevel@tonic-gate if (resbmap & FATTR4_MOUNTED_ON_FILEID_MASK) { 20627c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, garp->n4g_mon_fid); 20637c478bd9Sstevel@tonic-gate garp->n4g_mon_fid_valid = 1; 20647c478bd9Sstevel@tonic-gate } 20657c478bd9Sstevel@tonic-gate } 20667c478bd9Sstevel@tonic-gate 20677c478bd9Sstevel@tonic-gate /* 20687c478bd9Sstevel@tonic-gate * FATTR4_ACL_MASK is not yet supported by this function, but 20697c478bd9Sstevel@tonic-gate * we check against it anyway, in case it ever is. 20707c478bd9Sstevel@tonic-gate */ 20717c478bd9Sstevel@tonic-gate if (resbmap & ~(NFS4_VATTR_MASK | FATTR4_ACL_MASK)) { 20727c478bd9Sstevel@tonic-gate /* copy only if not provided */ 20737c478bd9Sstevel@tonic-gate if (garp->n4g_ext_res == NULL) { 20747c478bd9Sstevel@tonic-gate garp->n4g_ext_res = kmem_alloc(sizeof (ges), KM_SLEEP); 20757c478bd9Sstevel@tonic-gate bcopy(&ges, garp->n4g_ext_res, sizeof (ges)); 20767c478bd9Sstevel@tonic-gate } 20777c478bd9Sstevel@tonic-gate } 20787c478bd9Sstevel@tonic-gate 20797c478bd9Sstevel@tonic-gate return (TRUE); 20807c478bd9Sstevel@tonic-gate } 20817c478bd9Sstevel@tonic-gate 20827c478bd9Sstevel@tonic-gate 20837c478bd9Sstevel@tonic-gate /* 20847c478bd9Sstevel@tonic-gate * "." and ".." buffers for filling in on read and readdir 20857c478bd9Sstevel@tonic-gate * calls. Intialize the first time and fill in on every 20867c478bd9Sstevel@tonic-gate * call to to readdir. 20877c478bd9Sstevel@tonic-gate */ 20887c478bd9Sstevel@tonic-gate char *nfs4_dot_entries; 20897c478bd9Sstevel@tonic-gate char *nfs4_dot_dot_entry; 20907c478bd9Sstevel@tonic-gate 20917c478bd9Sstevel@tonic-gate /* 20927c478bd9Sstevel@tonic-gate * Create the "." or ".." and pad the buffer once so they are 20937c478bd9Sstevel@tonic-gate * copied out as required into the user supplied buffer everytime. 20947c478bd9Sstevel@tonic-gate * DIRENT64_RECLEN(sizeof (".") - 1) = DIRENT64_RECLEN(1) 20957c478bd9Sstevel@tonic-gate * DIRENT64_RECLEN(sizeof ("..") - 1) = DIRENT64_RECLEN(2) 20967c478bd9Sstevel@tonic-gate */ 20977c478bd9Sstevel@tonic-gate void 20987c478bd9Sstevel@tonic-gate nfs4_init_dot_entries() 20997c478bd9Sstevel@tonic-gate { 21007c478bd9Sstevel@tonic-gate struct dirent64 *odp; 21017c478bd9Sstevel@tonic-gate 21027c478bd9Sstevel@tonic-gate /* 21037c478bd9Sstevel@tonic-gate * zalloc it so it zeros the buffer out. Need 21047c478bd9Sstevel@tonic-gate * to just do it once. 21057c478bd9Sstevel@tonic-gate */ 21067c478bd9Sstevel@tonic-gate nfs4_dot_entries = kmem_zalloc(DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2), 21077c478bd9Sstevel@tonic-gate KM_SLEEP); 21087c478bd9Sstevel@tonic-gate 21097c478bd9Sstevel@tonic-gate odp = (struct dirent64 *)nfs4_dot_entries; 21107c478bd9Sstevel@tonic-gate odp->d_off = 1; /* magic cookie for "." entry */ 21117c478bd9Sstevel@tonic-gate odp->d_reclen = DIRENT64_RECLEN(1); 21127c478bd9Sstevel@tonic-gate odp->d_name[0] = '.'; 21137c478bd9Sstevel@tonic-gate odp->d_name[1] = '\0'; 21147c478bd9Sstevel@tonic-gate 21157c478bd9Sstevel@tonic-gate nfs4_dot_dot_entry = nfs4_dot_entries + DIRENT64_RECLEN(1); 21167c478bd9Sstevel@tonic-gate odp = (struct dirent64 *)nfs4_dot_dot_entry; 21177c478bd9Sstevel@tonic-gate 21187c478bd9Sstevel@tonic-gate odp->d_off = 2; 21197c478bd9Sstevel@tonic-gate odp->d_reclen = DIRENT64_RECLEN(2); 21207c478bd9Sstevel@tonic-gate odp->d_name[0] = '.'; 21217c478bd9Sstevel@tonic-gate odp->d_name[1] = '.'; 21227c478bd9Sstevel@tonic-gate odp->d_name[2] = '\0'; 21237c478bd9Sstevel@tonic-gate } 21247c478bd9Sstevel@tonic-gate 21257c478bd9Sstevel@tonic-gate void 21267c478bd9Sstevel@tonic-gate nfs4_destroy_dot_entries() 21277c478bd9Sstevel@tonic-gate { 21287c478bd9Sstevel@tonic-gate if (nfs4_dot_entries) 21297c478bd9Sstevel@tonic-gate kmem_free(nfs4_dot_entries, DIRENT64_RECLEN(1) + 21307c478bd9Sstevel@tonic-gate DIRENT64_RECLEN(2)); 21317c478bd9Sstevel@tonic-gate 21327c478bd9Sstevel@tonic-gate nfs4_dot_entries = nfs4_dot_dot_entry = NULL; 21337c478bd9Sstevel@tonic-gate } 21347c478bd9Sstevel@tonic-gate 21357c478bd9Sstevel@tonic-gate bool_t 21367c478bd9Sstevel@tonic-gate xdr_READDIR4res_clnt(XDR *xdrs, READDIR4res_clnt *objp, READDIR4args *aobjp) 21377c478bd9Sstevel@tonic-gate { 21387c478bd9Sstevel@tonic-gate bool_t more_data; 21397c478bd9Sstevel@tonic-gate rddir4_cache *rdc = aobjp->rdc; 21407c478bd9Sstevel@tonic-gate dirent64_t *dp = NULL; 21417c478bd9Sstevel@tonic-gate int entry_length = 0; 21427c478bd9Sstevel@tonic-gate int space_left = 0; 21437c478bd9Sstevel@tonic-gate bitmap4 resbmap; 21447c478bd9Sstevel@tonic-gate uint32_t attrlen; 21457c478bd9Sstevel@tonic-gate nfs4_ga_res_t gar; 21467c478bd9Sstevel@tonic-gate struct nfs4_ga_ext_res ges; 21477c478bd9Sstevel@tonic-gate uint64_t last_cookie = 0; 21487c478bd9Sstevel@tonic-gate int skip_to_end; 21497c478bd9Sstevel@tonic-gate ug_cache_t *pug = NULL; 21507c478bd9Sstevel@tonic-gate 21517c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_DECODE); 21527c478bd9Sstevel@tonic-gate ASSERT(rdc->entries == NULL); 21537c478bd9Sstevel@tonic-gate ASSERT(aobjp->dircount > 0); 21547c478bd9Sstevel@tonic-gate 21557c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 21567c478bd9Sstevel@tonic-gate return (FALSE); 21577c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 21587c478bd9Sstevel@tonic-gate return (TRUE); 21597c478bd9Sstevel@tonic-gate 21607c478bd9Sstevel@tonic-gate gar.n4g_va.va_mask = 0; 21617c478bd9Sstevel@tonic-gate gar.n4g_change_valid = 0; 21627c478bd9Sstevel@tonic-gate gar.n4g_mon_fid_valid = 0; 21637c478bd9Sstevel@tonic-gate gar.n4g_fsid_valid = 0; 21647c478bd9Sstevel@tonic-gate gar.n4g_vsa.vsa_mask = 0; 21657c478bd9Sstevel@tonic-gate gar.n4g_attrwhy = NFS4_GETATTR_OP_OK; 21667c478bd9Sstevel@tonic-gate ges.n4g_pc4.pc4_cache_valid = 0; 21677c478bd9Sstevel@tonic-gate ges.n4g_pc4.pc4_xattr_valid = 0; 21687c478bd9Sstevel@tonic-gate gar.n4g_ext_res = ⩾ 21697c478bd9Sstevel@tonic-gate 21707c478bd9Sstevel@tonic-gate /* READDIR4res_clnt_free needs to kmem_free this buffer */ 21717c478bd9Sstevel@tonic-gate rdc->entries = kmem_alloc(aobjp->dircount, KM_SLEEP); 21727c478bd9Sstevel@tonic-gate 21737c478bd9Sstevel@tonic-gate dp = (dirent64_t *)rdc->entries; 21747c478bd9Sstevel@tonic-gate rdc->entlen = rdc->buflen = space_left = aobjp->dircount; 21757c478bd9Sstevel@tonic-gate 21767c478bd9Sstevel@tonic-gate /* Fill in dot and dot-dot if needed */ 21777c478bd9Sstevel@tonic-gate if (rdc->nfs4_cookie == (nfs_cookie4) 0 || 21787c478bd9Sstevel@tonic-gate rdc->nfs4_cookie == (nfs_cookie4) 1) { 21797c478bd9Sstevel@tonic-gate 21807c478bd9Sstevel@tonic-gate if (rdc->nfs4_cookie == (nfs_cookie4)0) { 21817c478bd9Sstevel@tonic-gate bcopy(nfs4_dot_entries, rdc->entries, 21827c478bd9Sstevel@tonic-gate DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2)); 21837c478bd9Sstevel@tonic-gate objp->dotp = dp; 21847c478bd9Sstevel@tonic-gate dp = (struct dirent64 *)(((char *)dp) + 21857c478bd9Sstevel@tonic-gate DIRENT64_RECLEN(1)); 21867c478bd9Sstevel@tonic-gate objp->dotdotp = dp; 21877c478bd9Sstevel@tonic-gate dp = (struct dirent64 *)(((char *)dp) + 21887c478bd9Sstevel@tonic-gate DIRENT64_RECLEN(2)); 21897c478bd9Sstevel@tonic-gate space_left -= DIRENT64_RECLEN(1) + DIRENT64_RECLEN(2); 21907c478bd9Sstevel@tonic-gate 21917c478bd9Sstevel@tonic-gate } else { /* for ".." entry */ 21927c478bd9Sstevel@tonic-gate bcopy(nfs4_dot_dot_entry, rdc->entries, 21937c478bd9Sstevel@tonic-gate DIRENT64_RECLEN(2)); 21947c478bd9Sstevel@tonic-gate objp->dotp = NULL; 21957c478bd9Sstevel@tonic-gate objp->dotdotp = dp; 21967c478bd9Sstevel@tonic-gate dp = (struct dirent64 *)(((char *)dp) + 21977c478bd9Sstevel@tonic-gate DIRENT64_RECLEN(2)); 21987c478bd9Sstevel@tonic-gate space_left -= DIRENT64_RECLEN(2); 21997c478bd9Sstevel@tonic-gate } 22007c478bd9Sstevel@tonic-gate /* Magic NFSv4 number for entry after start */ 22017c478bd9Sstevel@tonic-gate last_cookie = 2; 22027c478bd9Sstevel@tonic-gate } 22037c478bd9Sstevel@tonic-gate 22047c478bd9Sstevel@tonic-gate /* Get the cookie VERIFIER */ 22057c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf)) 22067c478bd9Sstevel@tonic-gate goto noentries; 22077c478bd9Sstevel@tonic-gate 22087c478bd9Sstevel@tonic-gate /* Get the do-we-have-a-next-entry BOOL */ 22097c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &more_data)) 22107c478bd9Sstevel@tonic-gate goto noentries; 22117c478bd9Sstevel@tonic-gate 22127c478bd9Sstevel@tonic-gate if (aobjp->attr_request & (FATTR4_OWNER_MASK | FATTR4_OWNER_GROUP_MASK)) 22137c478bd9Sstevel@tonic-gate pug = alloc_ugcache(); 22147c478bd9Sstevel@tonic-gate 22157c478bd9Sstevel@tonic-gate skip_to_end = 0; 22167c478bd9Sstevel@tonic-gate while (more_data) { 22177c478bd9Sstevel@tonic-gate uint_t namelen; 22187c478bd9Sstevel@tonic-gate uint64_t cookie; 22197c478bd9Sstevel@tonic-gate 22207c478bd9Sstevel@tonic-gate /* Get the COOKIE */ 22217c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&cookie)) 22227c478bd9Sstevel@tonic-gate goto noentries; 22237c478bd9Sstevel@tonic-gate 22247c478bd9Sstevel@tonic-gate /* Get the LENGTH of the entry name */ 22257c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &namelen)) 22267c478bd9Sstevel@tonic-gate goto noentries; 22277c478bd9Sstevel@tonic-gate 22287c478bd9Sstevel@tonic-gate if (!skip_to_end) { 22297c478bd9Sstevel@tonic-gate /* 22307c478bd9Sstevel@tonic-gate * With the length of the directory entry name 22317c478bd9Sstevel@tonic-gate * in hand, figure out if there is room left 22327c478bd9Sstevel@tonic-gate * to encode it for the requestor. If not, 22337c478bd9Sstevel@tonic-gate * that is okay, but the rest of the readdir 22347c478bd9Sstevel@tonic-gate * operation result must be decoded in the 22357c478bd9Sstevel@tonic-gate * case there are following operations 22367c478bd9Sstevel@tonic-gate * in the compound request. Therefore, mark 22377c478bd9Sstevel@tonic-gate * the rest of the response as "skip" and 22387c478bd9Sstevel@tonic-gate * decode or skip the remaining data 22397c478bd9Sstevel@tonic-gate */ 22407c478bd9Sstevel@tonic-gate entry_length = DIRENT64_RECLEN(namelen); 22417c478bd9Sstevel@tonic-gate if (space_left < entry_length) 22427c478bd9Sstevel@tonic-gate skip_to_end = 1; 22437c478bd9Sstevel@tonic-gate } 22447c478bd9Sstevel@tonic-gate 22457c478bd9Sstevel@tonic-gate /* Get the NAME of the entry */ 22467c478bd9Sstevel@tonic-gate if (!skip_to_end) { 22477c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, dp->d_name, namelen)) 22487c478bd9Sstevel@tonic-gate goto noentries; 22497c478bd9Sstevel@tonic-gate bzero(&dp->d_name[namelen], 22507c478bd9Sstevel@tonic-gate DIRENT64_NAMELEN(entry_length) - namelen); 22517c478bd9Sstevel@tonic-gate dp->d_off = last_cookie = cookie; 22527c478bd9Sstevel@tonic-gate dp->d_reclen = entry_length; 22537c478bd9Sstevel@tonic-gate } else { 22547c478bd9Sstevel@tonic-gate if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &namelen)) 22557c478bd9Sstevel@tonic-gate goto noentries; 22567c478bd9Sstevel@tonic-gate } 22577c478bd9Sstevel@tonic-gate 22587c478bd9Sstevel@tonic-gate /* Get the attribute BITMAP */ 22597c478bd9Sstevel@tonic-gate if (!xdr_bitmap4(xdrs, &resbmap)) 22607c478bd9Sstevel@tonic-gate goto noentries; 22617c478bd9Sstevel@tonic-gate /* Get the LENGTH of the attributes */ 22627c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, (uint_t *)&attrlen)) 22637c478bd9Sstevel@tonic-gate goto noentries; 22647c478bd9Sstevel@tonic-gate 22657c478bd9Sstevel@tonic-gate /* Get the ATTRIBUTES */ 22667c478bd9Sstevel@tonic-gate if (!skip_to_end) { 22677c478bd9Sstevel@tonic-gate uint32_t *ptr; 22687c478bd9Sstevel@tonic-gate 22697c478bd9Sstevel@tonic-gate if (!(resbmap & FATTR4_ACL_MASK) && 22707c478bd9Sstevel@tonic-gate (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen)) 22717c478bd9Sstevel@tonic-gate != NULL) { 22727c478bd9Sstevel@tonic-gate if (!xdr_ga_fattr_res_inline(ptr, &gar, resbmap, 22730a701b1eSRobert Gordon aobjp->attr_request, aobjp->mi, pug)) 22747c478bd9Sstevel@tonic-gate goto noentries; 22757c478bd9Sstevel@tonic-gate } else { 22767c478bd9Sstevel@tonic-gate if (!xdr_ga_fattr_res(xdrs, &gar, resbmap, 22770a701b1eSRobert Gordon aobjp->attr_request, aobjp->mi, pug)) 22787c478bd9Sstevel@tonic-gate goto noentries; 22797c478bd9Sstevel@tonic-gate } 22807c478bd9Sstevel@tonic-gate 22817c478bd9Sstevel@tonic-gate /* Fill in the d_ino per the server's fid values */ 22827c478bd9Sstevel@tonic-gate /* 22837c478bd9Sstevel@tonic-gate * Important to note that the mounted on fileid 22847c478bd9Sstevel@tonic-gate * is returned in d_ino if supported. This is 22857c478bd9Sstevel@tonic-gate * expected, readdir returns the mounted on fileid 22867c478bd9Sstevel@tonic-gate * while stat() returns the fileid of the object 22877c478bd9Sstevel@tonic-gate * on "top" of the mount. 22887c478bd9Sstevel@tonic-gate */ 22897c478bd9Sstevel@tonic-gate if (gar.n4g_mon_fid_valid) 22907c478bd9Sstevel@tonic-gate dp->d_ino = gar.n4g_mon_fid; 22917c478bd9Sstevel@tonic-gate else if (gar.n4g_va.va_mask & AT_NODEID) 22927c478bd9Sstevel@tonic-gate dp->d_ino = gar.n4g_va.va_nodeid; 22937c478bd9Sstevel@tonic-gate else 22947c478bd9Sstevel@tonic-gate dp->d_ino = 0; 22957c478bd9Sstevel@tonic-gate 22967c478bd9Sstevel@tonic-gate /* See about creating an rnode for this entry */ 22977c478bd9Sstevel@tonic-gate if ((resbmap & 22987c478bd9Sstevel@tonic-gate (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) == 22997c478bd9Sstevel@tonic-gate (NFS4_VATTR_MASK | FATTR4_FILEHANDLE_MASK)) { 23007c478bd9Sstevel@tonic-gate nfs4_sharedfh_t *sfhp; 23017c478bd9Sstevel@tonic-gate vnode_t *vp; 23027c478bd9Sstevel@tonic-gate 23037c478bd9Sstevel@tonic-gate sfhp = sfh4_put(&ges.n4g_fh_u.n4g_fh, 23047c478bd9Sstevel@tonic-gate aobjp->mi, NULL); 23057c478bd9Sstevel@tonic-gate vp = makenfs4node(sfhp, &gar, 23067c478bd9Sstevel@tonic-gate aobjp->dvp->v_vfsp, 23077c478bd9Sstevel@tonic-gate aobjp->t, 23087c478bd9Sstevel@tonic-gate aobjp->cr, 23097c478bd9Sstevel@tonic-gate aobjp->dvp, 23107c478bd9Sstevel@tonic-gate fn_get(VTOSV(aobjp->dvp)->sv_name, 2311bbf2a467SNagakiran Rajashekar dp->d_name, sfhp)); 23127c478bd9Sstevel@tonic-gate sfh4_rele(&sfhp); 23137c478bd9Sstevel@tonic-gate dnlc_update(aobjp->dvp, dp->d_name, vp); 23147c478bd9Sstevel@tonic-gate VN_RELE(vp); 23157c478bd9Sstevel@tonic-gate } 23167c478bd9Sstevel@tonic-gate 23177c478bd9Sstevel@tonic-gate dp = (struct dirent64 *)(((caddr_t)dp) + dp->d_reclen); 23187c478bd9Sstevel@tonic-gate 23197c478bd9Sstevel@tonic-gate space_left -= entry_length; 23207c478bd9Sstevel@tonic-gate 23217c478bd9Sstevel@tonic-gate } else { 23227c478bd9Sstevel@tonic-gate if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &attrlen)) 23237c478bd9Sstevel@tonic-gate goto noentries; 23247c478bd9Sstevel@tonic-gate } 23257c478bd9Sstevel@tonic-gate 23267c478bd9Sstevel@tonic-gate /* Get the do-we-have-a-next-entry BOOL */ 23277c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &more_data)) 23287c478bd9Sstevel@tonic-gate goto noentries; 23297c478bd9Sstevel@tonic-gate } 23307c478bd9Sstevel@tonic-gate 23317c478bd9Sstevel@tonic-gate if (pug) { 23327c478bd9Sstevel@tonic-gate kmem_free(pug, sizeof (ug_cache_t)); 23337c478bd9Sstevel@tonic-gate pug = NULL; 23347c478bd9Sstevel@tonic-gate } 23357c478bd9Sstevel@tonic-gate 23367c478bd9Sstevel@tonic-gate /* 23377c478bd9Sstevel@tonic-gate * Finish up the rddir cache 23387c478bd9Sstevel@tonic-gate * If no entries were returned, free up buffer & 23397c478bd9Sstevel@tonic-gate * set ncookie to the starting cookie for this 23407c478bd9Sstevel@tonic-gate * readdir request so that the direof caching 23417c478bd9Sstevel@tonic-gate * will work properly. 23427c478bd9Sstevel@tonic-gate */ 23437c478bd9Sstevel@tonic-gate ASSERT(rdc->entries); 23447c478bd9Sstevel@tonic-gate if (last_cookie == 0) { 23457c478bd9Sstevel@tonic-gate kmem_free(rdc->entries, rdc->entlen); 23467c478bd9Sstevel@tonic-gate rdc->entries = NULL; 23477c478bd9Sstevel@tonic-gate last_cookie = rdc->nfs4_cookie; 23487c478bd9Sstevel@tonic-gate } 23497c478bd9Sstevel@tonic-gate 23507c478bd9Sstevel@tonic-gate rdc->actlen = rdc->entlen - space_left; 23517c478bd9Sstevel@tonic-gate rdc->nfs4_ncookie = last_cookie; 23527c478bd9Sstevel@tonic-gate 23537c478bd9Sstevel@tonic-gate /* Get the EOF marker */ 23547c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->eof)) 23557c478bd9Sstevel@tonic-gate goto noentries; 23567c478bd9Sstevel@tonic-gate 23577c478bd9Sstevel@tonic-gate /* 23587c478bd9Sstevel@tonic-gate * If the server returns eof and there were no 23597c478bd9Sstevel@tonic-gate * skipped entries, set eof 23607c478bd9Sstevel@tonic-gate */ 23617c478bd9Sstevel@tonic-gate rdc->eof = (objp->eof && !skip_to_end) ? TRUE : FALSE; 23627c478bd9Sstevel@tonic-gate 23637c478bd9Sstevel@tonic-gate /* 23647c478bd9Sstevel@tonic-gate * If we encoded entries we are done 23657c478bd9Sstevel@tonic-gate */ 23667c478bd9Sstevel@tonic-gate if (rdc->entries) { 23677c478bd9Sstevel@tonic-gate rdc->error = 0; 23687c478bd9Sstevel@tonic-gate return (TRUE); 23697c478bd9Sstevel@tonic-gate } 23707c478bd9Sstevel@tonic-gate 23717c478bd9Sstevel@tonic-gate /* 23727c478bd9Sstevel@tonic-gate * If there were no entries and we skipped because 23737c478bd9Sstevel@tonic-gate * there was not enough space, return EINVAL 23747c478bd9Sstevel@tonic-gate */ 23757c478bd9Sstevel@tonic-gate if (skip_to_end) { 23767c478bd9Sstevel@tonic-gate rdc->error = EINVAL; 23777c478bd9Sstevel@tonic-gate return (TRUE); 23787c478bd9Sstevel@tonic-gate } 23797c478bd9Sstevel@tonic-gate 23807c478bd9Sstevel@tonic-gate /* 23817c478bd9Sstevel@tonic-gate * No entries, nothing skipped, and EOF, return OK. 23827c478bd9Sstevel@tonic-gate */ 23837c478bd9Sstevel@tonic-gate if (objp->eof == TRUE) { 23847c478bd9Sstevel@tonic-gate rdc->error = 0; 23857c478bd9Sstevel@tonic-gate return (TRUE); 23867c478bd9Sstevel@tonic-gate } 23877c478bd9Sstevel@tonic-gate 23887c478bd9Sstevel@tonic-gate /* 23897c478bd9Sstevel@tonic-gate * No entries, nothing skipped, and not EOF 23907c478bd9Sstevel@tonic-gate * probably a bad cookie, return ENOENT. 23917c478bd9Sstevel@tonic-gate */ 23927c478bd9Sstevel@tonic-gate rdc->error = ENOENT; 23937c478bd9Sstevel@tonic-gate return (TRUE); 23947c478bd9Sstevel@tonic-gate 23957c478bd9Sstevel@tonic-gate noentries: 23967c478bd9Sstevel@tonic-gate if (rdc->entries) { 23977c478bd9Sstevel@tonic-gate kmem_free(rdc->entries, rdc->entlen); 23987c478bd9Sstevel@tonic-gate rdc->entries = NULL; 23997c478bd9Sstevel@tonic-gate } 24007c478bd9Sstevel@tonic-gate if (pug) 24017c478bd9Sstevel@tonic-gate kmem_free(pug, sizeof (ug_cache_t)); 24027c478bd9Sstevel@tonic-gate rdc->error = EIO; 24037c478bd9Sstevel@tonic-gate return (FALSE); 24047c478bd9Sstevel@tonic-gate } 24057c478bd9Sstevel@tonic-gate 24067c478bd9Sstevel@tonic-gate /* 24077c478bd9Sstevel@tonic-gate * xdr_ga_res 24087c478bd9Sstevel@tonic-gate * 24097c478bd9Sstevel@tonic-gate * Returns: FALSE on raw data processing errors, TRUE otherwise. 24107c478bd9Sstevel@tonic-gate * 24117c478bd9Sstevel@tonic-gate * This function pre-processes the OP_GETATTR response, and then 24127c478bd9Sstevel@tonic-gate * calls common routines to process the GETATTR fattr4 results into 24137c478bd9Sstevel@tonic-gate * vnode attributes and other components that the client is interested 24147c478bd9Sstevel@tonic-gate * in. If an error other than an RPC error is encountered, the details 24157c478bd9Sstevel@tonic-gate * of the error are filled into objp, although the result of the 24167c478bd9Sstevel@tonic-gate * processing is set to TRUE. 24177c478bd9Sstevel@tonic-gate */ 24187c478bd9Sstevel@tonic-gate static bool_t 24197c478bd9Sstevel@tonic-gate xdr_ga_res(XDR *xdrs, GETATTR4res *objp, GETATTR4args *aobjp) 24207c478bd9Sstevel@tonic-gate { 24212f172c55SRobert Thurlow #ifdef INLINE 24227c478bd9Sstevel@tonic-gate uint32_t *ptr; 24232f172c55SRobert Thurlow #endif 24247c478bd9Sstevel@tonic-gate bitmap4 resbmap; 24257c478bd9Sstevel@tonic-gate uint32_t attrlen; 24267c478bd9Sstevel@tonic-gate 24277c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_DECODE); 24287c478bd9Sstevel@tonic-gate 24297c478bd9Sstevel@tonic-gate /* Initialize objp attribute error values */ 24307c478bd9Sstevel@tonic-gate objp->ga_res.n4g_attrerr = 24317c478bd9Sstevel@tonic-gate objp->ga_res.n4g_attrwhy = NFS4_GETATTR_OP_OK; 24327c478bd9Sstevel@tonic-gate 24337c478bd9Sstevel@tonic-gate if (!xdr_bitmap4(xdrs, &resbmap)) 24347c478bd9Sstevel@tonic-gate return (FALSE); 24357c478bd9Sstevel@tonic-gate 24367c478bd9Sstevel@tonic-gate /* save the response bitmap for the caller */ 24377c478bd9Sstevel@tonic-gate objp->ga_res.n4g_resbmap = resbmap; 24387c478bd9Sstevel@tonic-gate 24397c478bd9Sstevel@tonic-gate /* attrlen */ 24407c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&attrlen)) 24417c478bd9Sstevel@tonic-gate return (FALSE); 24427c478bd9Sstevel@tonic-gate 24437c478bd9Sstevel@tonic-gate /* 24447c478bd9Sstevel@tonic-gate * Handle case where request and response bitmaps don't match. 24457c478bd9Sstevel@tonic-gate */ 24467c478bd9Sstevel@tonic-gate if (aobjp->attr_request && aobjp->attr_request != resbmap) { 24477c478bd9Sstevel@tonic-gate bitmap4 deltabmap; 24487c478bd9Sstevel@tonic-gate 24497c478bd9Sstevel@tonic-gate /* 24507c478bd9Sstevel@tonic-gate * Return error for case where server sent extra attributes 24517c478bd9Sstevel@tonic-gate * because the "unknown" attributes may be anywhere in the 24527c478bd9Sstevel@tonic-gate * xdr stream and can't be properly processed. 24537c478bd9Sstevel@tonic-gate */ 24547c478bd9Sstevel@tonic-gate deltabmap = ((aobjp->attr_request ^ resbmap) & resbmap); 24557c478bd9Sstevel@tonic-gate if (deltabmap) { 24567c478bd9Sstevel@tonic-gate objp->ga_res.n4g_attrerr = EINVAL; 24577c478bd9Sstevel@tonic-gate objp->ga_res.n4g_attrwhy = NFS4_GETATTR_BITMAP_ERR; 24587c478bd9Sstevel@tonic-gate return (TRUE); 24597c478bd9Sstevel@tonic-gate } 24607c478bd9Sstevel@tonic-gate 24617c478bd9Sstevel@tonic-gate /* 24627c478bd9Sstevel@tonic-gate * Return error for case where there is a mandatory 24637c478bd9Sstevel@tonic-gate * attribute missing in the server response. Note that 24647c478bd9Sstevel@tonic-gate * missing recommended attributes are evaluated in the 24657c478bd9Sstevel@tonic-gate * specific routines that decode the server response. 24667c478bd9Sstevel@tonic-gate */ 24677c478bd9Sstevel@tonic-gate deltabmap = ((aobjp->attr_request ^ resbmap) 24687c478bd9Sstevel@tonic-gate & aobjp->attr_request); 24697c478bd9Sstevel@tonic-gate if ((deltabmap & FATTR4_MANDATTR_MASK)) { 24707c478bd9Sstevel@tonic-gate objp->ga_res.n4g_attrerr = EINVAL; 24717c478bd9Sstevel@tonic-gate objp->ga_res.n4g_attrwhy = NFS4_GETATTR_MANDATTR_ERR; 24727c478bd9Sstevel@tonic-gate return (TRUE); 24737c478bd9Sstevel@tonic-gate } 24747c478bd9Sstevel@tonic-gate } 24757c478bd9Sstevel@tonic-gate 24767c478bd9Sstevel@tonic-gate /* Check to see if the attrs can be inlined and go for it if so */ 24772f172c55SRobert Thurlow #ifdef INLINE 24787c478bd9Sstevel@tonic-gate if (!(resbmap & FATTR4_ACL_MASK) && 24797c478bd9Sstevel@tonic-gate (ptr = (uint32_t *)XDR_INLINE(xdrs, attrlen)) != NULL) 24807c478bd9Sstevel@tonic-gate return (xdr_ga_fattr_res_inline(ptr, &objp->ga_res, 24810a701b1eSRobert Gordon resbmap, aobjp->attr_request, aobjp->mi, NULL)); 24827c478bd9Sstevel@tonic-gate else 24832f172c55SRobert Thurlow #endif 24847c478bd9Sstevel@tonic-gate return (xdr_ga_fattr_res(xdrs, &objp->ga_res, 24850a701b1eSRobert Gordon resbmap, aobjp->attr_request, aobjp->mi, NULL)); 24867c478bd9Sstevel@tonic-gate } 24877c478bd9Sstevel@tonic-gate 24887c478bd9Sstevel@tonic-gate #if defined(DEBUG) && !defined(lint) 24897c478bd9Sstevel@tonic-gate /* 24907c478bd9Sstevel@tonic-gate * We assume that an enum is a 32-bit value, check it once 24917c478bd9Sstevel@tonic-gate */ 24927c478bd9Sstevel@tonic-gate static enum szchk { SZVAL } szchkvar; 24937c478bd9Sstevel@tonic-gate #endif 24947c478bd9Sstevel@tonic-gate 24957c478bd9Sstevel@tonic-gate bool_t 24967c478bd9Sstevel@tonic-gate xdr_settime4(XDR *xdrs, settime4 *objp) 24977c478bd9Sstevel@tonic-gate { 24987c478bd9Sstevel@tonic-gate #if defined(DEBUG) && !defined(lint) 24997c478bd9Sstevel@tonic-gate ASSERT(sizeof (szchkvar) == sizeof (int32_t)); 25007c478bd9Sstevel@tonic-gate #endif 25017c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 25027c478bd9Sstevel@tonic-gate return (TRUE); 25037c478bd9Sstevel@tonic-gate 25047c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->set_it)) 25057c478bd9Sstevel@tonic-gate return (FALSE); 25067c478bd9Sstevel@tonic-gate if (objp->set_it != SET_TO_CLIENT_TIME4) 25077c478bd9Sstevel@tonic-gate return (TRUE); 25087c478bd9Sstevel@tonic-gate /* xdr_nfstime4 */ 25097c478bd9Sstevel@tonic-gate if (!xdr_longlong_t(xdrs, (longlong_t *)&objp->time.seconds)) 25107c478bd9Sstevel@tonic-gate return (FALSE); 25117c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->time.nseconds)); 25127c478bd9Sstevel@tonic-gate } 25137c478bd9Sstevel@tonic-gate 25147c478bd9Sstevel@tonic-gate static bool_t 25157c478bd9Sstevel@tonic-gate xdr_fattr4(XDR *xdrs, fattr4 *objp) 25167c478bd9Sstevel@tonic-gate { 25177c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 25187c478bd9Sstevel@tonic-gate if (!xdr_bitmap4(xdrs, &objp->attrmask)) 25197c478bd9Sstevel@tonic-gate return (FALSE); 25207c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->attrlist4, 25217c478bd9Sstevel@tonic-gate (uint_t *)&objp->attrlist4_len, NFS4_FATTR4_LIMIT)); 25227c478bd9Sstevel@tonic-gate } 25237c478bd9Sstevel@tonic-gate 25247c478bd9Sstevel@tonic-gate /* 25257c478bd9Sstevel@tonic-gate * Optimized free case 25267c478bd9Sstevel@tonic-gate */ 25277c478bd9Sstevel@tonic-gate if (objp->attrlist4 != NULL) 25287c478bd9Sstevel@tonic-gate kmem_free(objp->attrlist4, objp->attrlist4_len); 25297c478bd9Sstevel@tonic-gate return (TRUE); 25307c478bd9Sstevel@tonic-gate } 25317c478bd9Sstevel@tonic-gate 25327c478bd9Sstevel@tonic-gate static bool_t 25337c478bd9Sstevel@tonic-gate xdr_ACCESS4res(XDR *xdrs, ACCESS4res *objp) 25347c478bd9Sstevel@tonic-gate { 25357c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 25367c478bd9Sstevel@tonic-gate return (FALSE); 25377c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 25387c478bd9Sstevel@tonic-gate return (TRUE); 25397c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->supported)) 25407c478bd9Sstevel@tonic-gate return (FALSE); 25417c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->access)); 25427c478bd9Sstevel@tonic-gate } 25437c478bd9Sstevel@tonic-gate 25447c478bd9Sstevel@tonic-gate static bool_t 25457c478bd9Sstevel@tonic-gate xdr_CLOSE4args(XDR *xdrs, CLOSE4args *objp) 25467c478bd9Sstevel@tonic-gate { 25477c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->seqid)) 25487c478bd9Sstevel@tonic-gate return (FALSE); 25497c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->open_stateid.seqid)) 25507c478bd9Sstevel@tonic-gate return (FALSE); 2551bbe876c0SMarcel Telka return (xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE)); 25527c478bd9Sstevel@tonic-gate } 25537c478bd9Sstevel@tonic-gate 25547c478bd9Sstevel@tonic-gate static bool_t 25557c478bd9Sstevel@tonic-gate xdr_CLOSE4res(XDR *xdrs, CLOSE4res *objp) 25567c478bd9Sstevel@tonic-gate { 25577c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 25587c478bd9Sstevel@tonic-gate return (FALSE); 25597c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 25607c478bd9Sstevel@tonic-gate return (TRUE); 25617c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->open_stateid.seqid)) 25627c478bd9Sstevel@tonic-gate return (FALSE); 2563bbe876c0SMarcel Telka return (xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE)); 25647c478bd9Sstevel@tonic-gate } 25657c478bd9Sstevel@tonic-gate 25667c478bd9Sstevel@tonic-gate static bool_t 25677c478bd9Sstevel@tonic-gate xdr_CREATE4args(XDR *xdrs, CREATE4args *objp) 25687c478bd9Sstevel@tonic-gate { 25697c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 25707c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->type)) 25717c478bd9Sstevel@tonic-gate return (FALSE); 25727c478bd9Sstevel@tonic-gate switch (objp->type) { 25737c478bd9Sstevel@tonic-gate case NF4LNK: 25747c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, 2575bbe876c0SMarcel Telka (char **)&objp->ftype4_u.linkdata.linktext4_val, 2576bbe876c0SMarcel Telka (uint_t *)&objp->ftype4_u.linkdata.linktext4_len, 25777c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)) 25787c478bd9Sstevel@tonic-gate return (FALSE); 25797c478bd9Sstevel@tonic-gate break; 25807c478bd9Sstevel@tonic-gate case NF4BLK: 25817c478bd9Sstevel@tonic-gate case NF4CHR: 25827c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata1)) 25837c478bd9Sstevel@tonic-gate return (FALSE); 25847c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->ftype4_u.devdata.specdata2)) 25857c478bd9Sstevel@tonic-gate return (FALSE); 25867c478bd9Sstevel@tonic-gate break; 25877c478bd9Sstevel@tonic-gate case NF4SOCK: 25887c478bd9Sstevel@tonic-gate case NF4FIFO: 25897c478bd9Sstevel@tonic-gate case NF4DIR: 25907c478bd9Sstevel@tonic-gate default: 25917c478bd9Sstevel@tonic-gate break; /* server should return NFS4ERR_BADTYPE */ 25927c478bd9Sstevel@tonic-gate } 25937c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, (char **)&objp->objname.utf8string_val, 25947c478bd9Sstevel@tonic-gate (uint_t *)&objp->objname.utf8string_len, 25957c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)) 25967c478bd9Sstevel@tonic-gate return (FALSE); 25977c478bd9Sstevel@tonic-gate return (xdr_fattr4(xdrs, &objp->createattrs)); 25987c478bd9Sstevel@tonic-gate } 25997c478bd9Sstevel@tonic-gate 26007c478bd9Sstevel@tonic-gate /* 26017c478bd9Sstevel@tonic-gate * Optimized free case 26027c478bd9Sstevel@tonic-gate */ 26037c478bd9Sstevel@tonic-gate if (objp->type == NF4LNK) { 2604bbe876c0SMarcel Telka if (objp->ftype4_u.linkdata.linktext4_val != NULL) 2605bbe876c0SMarcel Telka kmem_free(objp->ftype4_u.linkdata.linktext4_val, 2606bbe876c0SMarcel Telka objp->ftype4_u.linkdata.linktext4_len); 26077c478bd9Sstevel@tonic-gate } 26087c478bd9Sstevel@tonic-gate if (objp->objname.utf8string_val != NULL) 26097c478bd9Sstevel@tonic-gate kmem_free(objp->objname.utf8string_val, 26107c478bd9Sstevel@tonic-gate objp->objname.utf8string_len); 26117c478bd9Sstevel@tonic-gate return (xdr_fattr4(xdrs, &objp->createattrs)); 26127c478bd9Sstevel@tonic-gate } 26137c478bd9Sstevel@tonic-gate 26147c478bd9Sstevel@tonic-gate static bool_t 26157c478bd9Sstevel@tonic-gate xdr_CREATE4cargs(XDR *xdrs, CREATE4cargs *objp) 26167c478bd9Sstevel@tonic-gate { 26177c478bd9Sstevel@tonic-gate int len; 26187c478bd9Sstevel@tonic-gate 26197c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_ENCODE); 26207c478bd9Sstevel@tonic-gate 26217c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->type)) 26227c478bd9Sstevel@tonic-gate return (FALSE); 26237c478bd9Sstevel@tonic-gate switch (objp->type) { 26247c478bd9Sstevel@tonic-gate case NF4LNK: 26257c478bd9Sstevel@tonic-gate len = strlen(objp->ftype4_u.clinkdata); 26267c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 26277c478bd9Sstevel@tonic-gate return (FALSE); 26287c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &len)) 26297c478bd9Sstevel@tonic-gate return (FALSE); 26307c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->ftype4_u.clinkdata, len)) 26317c478bd9Sstevel@tonic-gate return (FALSE); 26327c478bd9Sstevel@tonic-gate break; 26337c478bd9Sstevel@tonic-gate case NF4BLK: 26347c478bd9Sstevel@tonic-gate case NF4CHR: 26357c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, 26367c478bd9Sstevel@tonic-gate (int32_t *)&objp->ftype4_u.devdata.specdata1)) 26377c478bd9Sstevel@tonic-gate return (FALSE); 26387c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, 26397c478bd9Sstevel@tonic-gate (int32_t *)&objp->ftype4_u.devdata.specdata2)) 26407c478bd9Sstevel@tonic-gate return (FALSE); 26417c478bd9Sstevel@tonic-gate break; 26427c478bd9Sstevel@tonic-gate case NF4SOCK: 26437c478bd9Sstevel@tonic-gate case NF4FIFO: 26447c478bd9Sstevel@tonic-gate case NF4DIR: 26457c478bd9Sstevel@tonic-gate default: 26467c478bd9Sstevel@tonic-gate break; /* server should return NFS4ERR_BADTYPE */ 26477c478bd9Sstevel@tonic-gate } 26487c478bd9Sstevel@tonic-gate 26497c478bd9Sstevel@tonic-gate len = strlen(objp->cname); 26507c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 26517c478bd9Sstevel@tonic-gate return (FALSE); 26527c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &len)) 26537c478bd9Sstevel@tonic-gate return (FALSE); 26547c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->cname, len)) 26557c478bd9Sstevel@tonic-gate return (FALSE); 26567c478bd9Sstevel@tonic-gate 26577c478bd9Sstevel@tonic-gate return (xdr_fattr4(xdrs, &objp->createattrs)); 26587c478bd9Sstevel@tonic-gate } 26597c478bd9Sstevel@tonic-gate 26607c478bd9Sstevel@tonic-gate static bool_t 26617c478bd9Sstevel@tonic-gate xdr_CREATE4res(XDR *xdrs, CREATE4res *objp) 26627c478bd9Sstevel@tonic-gate { 26637c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 26647c478bd9Sstevel@tonic-gate return (FALSE); 26657c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 26667c478bd9Sstevel@tonic-gate return (TRUE); 26677c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->cinfo.atomic)) 26687c478bd9Sstevel@tonic-gate return (FALSE); 26697c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before)) 26707c478bd9Sstevel@tonic-gate return (FALSE); 26717c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after)) 26727c478bd9Sstevel@tonic-gate return (FALSE); 26737c478bd9Sstevel@tonic-gate return (xdr_bitmap4(xdrs, &objp->attrset)); 26747c478bd9Sstevel@tonic-gate } 26757c478bd9Sstevel@tonic-gate 26767c478bd9Sstevel@tonic-gate static bool_t 26777c478bd9Sstevel@tonic-gate xdr_LINK4res(XDR *xdrs, LINK4res *objp) 26787c478bd9Sstevel@tonic-gate { 26797c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 26807c478bd9Sstevel@tonic-gate return (FALSE); 26817c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 26827c478bd9Sstevel@tonic-gate return (TRUE); 26837c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->cinfo.atomic)) 26847c478bd9Sstevel@tonic-gate return (FALSE); 26857c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before)) 26867c478bd9Sstevel@tonic-gate return (FALSE); 26877c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after)); 26887c478bd9Sstevel@tonic-gate } 26897c478bd9Sstevel@tonic-gate 26907c478bd9Sstevel@tonic-gate static bool_t 26917c478bd9Sstevel@tonic-gate xdr_LOCK4args(XDR *xdrs, LOCK4args *objp) 26927c478bd9Sstevel@tonic-gate { 26937c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 26947c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->locktype)) 26957c478bd9Sstevel@tonic-gate return (FALSE); 26967c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->reclaim)) 26977c478bd9Sstevel@tonic-gate return (FALSE); 26987c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset)) 26997c478bd9Sstevel@tonic-gate return (FALSE); 27007c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length)) 27017c478bd9Sstevel@tonic-gate return (FALSE); 27027c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->locker.new_lock_owner)) 27037c478bd9Sstevel@tonic-gate return (FALSE); 27047c478bd9Sstevel@tonic-gate if (objp->locker.new_lock_owner == TRUE) { 27057c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner. 27067c478bd9Sstevel@tonic-gate open_seqid)) 27077c478bd9Sstevel@tonic-gate return (FALSE); 27087c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner. 27097c478bd9Sstevel@tonic-gate open_stateid.seqid)) 27107c478bd9Sstevel@tonic-gate return (FALSE); 27117c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->locker.locker4_u.open_owner. 2712bbe876c0SMarcel Telka open_stateid.other, NFS4_OTHER_SIZE)) 27137c478bd9Sstevel@tonic-gate return (FALSE); 27147c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->locker.locker4_u.open_owner. 27157c478bd9Sstevel@tonic-gate lock_seqid)) 27167c478bd9Sstevel@tonic-gate return (FALSE); 27177c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 27187c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->locker.locker4_u. 27197c478bd9Sstevel@tonic-gate open_owner.lock_owner.clientid)) 27207c478bd9Sstevel@tonic-gate return (FALSE); 27217c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, 27227c478bd9Sstevel@tonic-gate (char **)&objp->locker.locker4_u.open_owner. 27237c478bd9Sstevel@tonic-gate lock_owner.owner_val, 27247c478bd9Sstevel@tonic-gate (uint_t *)&objp->locker.locker4_u.open_owner. 27257c478bd9Sstevel@tonic-gate lock_owner.owner_len, 27267c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)); 27277c478bd9Sstevel@tonic-gate } 27287c478bd9Sstevel@tonic-gate 27297c478bd9Sstevel@tonic-gate if (objp->locker.new_lock_owner != FALSE) 27307c478bd9Sstevel@tonic-gate return (FALSE); 27317c478bd9Sstevel@tonic-gate 27327c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner. 27337c478bd9Sstevel@tonic-gate lock_stateid.seqid)) 27347c478bd9Sstevel@tonic-gate return (FALSE); 27357c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->locker.locker4_u.lock_owner. 2736bbe876c0SMarcel Telka lock_stateid.other, NFS4_OTHER_SIZE)) 27377c478bd9Sstevel@tonic-gate return (FALSE); 27387c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->locker.locker4_u.lock_owner. 27397c478bd9Sstevel@tonic-gate lock_seqid)); 27407c478bd9Sstevel@tonic-gate } 27417c478bd9Sstevel@tonic-gate 27427c478bd9Sstevel@tonic-gate /* 27437c478bd9Sstevel@tonic-gate * Optimized free case 27447c478bd9Sstevel@tonic-gate */ 27457c478bd9Sstevel@tonic-gate if (objp->locker.new_lock_owner == TRUE) { 27467c478bd9Sstevel@tonic-gate if (objp->locker.locker4_u.open_owner.lock_owner.owner_val != 27477c478bd9Sstevel@tonic-gate NULL) { 27487c478bd9Sstevel@tonic-gate kmem_free(objp->locker.locker4_u.open_owner.lock_owner. 27497c478bd9Sstevel@tonic-gate owner_val, 27507c478bd9Sstevel@tonic-gate objp->locker.locker4_u.open_owner.lock_owner. 27517c478bd9Sstevel@tonic-gate owner_len); 27527c478bd9Sstevel@tonic-gate } 27537c478bd9Sstevel@tonic-gate } 27547c478bd9Sstevel@tonic-gate 27557c478bd9Sstevel@tonic-gate return (TRUE); 27567c478bd9Sstevel@tonic-gate } 27577c478bd9Sstevel@tonic-gate 27587c478bd9Sstevel@tonic-gate static bool_t 27597c478bd9Sstevel@tonic-gate xdr_LOCK4res(XDR *xdrs, LOCK4res *objp) 27607c478bd9Sstevel@tonic-gate { 27617c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 27627c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 27637c478bd9Sstevel@tonic-gate return (FALSE); 27647c478bd9Sstevel@tonic-gate if (objp->status == NFS4_OK) { 27657c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, 27667c478bd9Sstevel@tonic-gate &objp->LOCK4res_u.lock_stateid.seqid)) 27677c478bd9Sstevel@tonic-gate return (FALSE); 27687c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 2769bbe876c0SMarcel Telka objp->LOCK4res_u.lock_stateid.other, 2770bbe876c0SMarcel Telka NFS4_OTHER_SIZE)); 27717c478bd9Sstevel@tonic-gate } 27727c478bd9Sstevel@tonic-gate if (objp->status != NFS4ERR_DENIED) 27737c478bd9Sstevel@tonic-gate return (TRUE); 27747c478bd9Sstevel@tonic-gate 27757c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u. 27767c478bd9Sstevel@tonic-gate denied.offset)) 27777c478bd9Sstevel@tonic-gate return (FALSE); 27787c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u. 27797c478bd9Sstevel@tonic-gate denied.length)) 27807c478bd9Sstevel@tonic-gate return (FALSE); 27817c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->LOCK4res_u.denied.locktype)) 27827c478bd9Sstevel@tonic-gate return (FALSE); 27837c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->LOCK4res_u. 27847c478bd9Sstevel@tonic-gate denied.owner.clientid)) 27857c478bd9Sstevel@tonic-gate return (FALSE); 27867c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, 27877c478bd9Sstevel@tonic-gate (char **)&objp->LOCK4res_u.denied.owner.owner_val, 27887c478bd9Sstevel@tonic-gate (uint_t *)&objp->LOCK4res_u.denied.owner.owner_len, 27897c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)); 27907c478bd9Sstevel@tonic-gate } 27917c478bd9Sstevel@tonic-gate 27927c478bd9Sstevel@tonic-gate /* 27937c478bd9Sstevel@tonic-gate * Optimized free case 27947c478bd9Sstevel@tonic-gate */ 27957c478bd9Sstevel@tonic-gate if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED) 27967c478bd9Sstevel@tonic-gate return (TRUE); 27977c478bd9Sstevel@tonic-gate 27987c478bd9Sstevel@tonic-gate if (objp->LOCK4res_u.denied.owner.owner_val != NULL) 27997c478bd9Sstevel@tonic-gate kmem_free(objp->LOCK4res_u.denied.owner.owner_val, 28007c478bd9Sstevel@tonic-gate objp->LOCK4res_u.denied.owner.owner_len); 28017c478bd9Sstevel@tonic-gate return (TRUE); 28027c478bd9Sstevel@tonic-gate } 28037c478bd9Sstevel@tonic-gate 28047c478bd9Sstevel@tonic-gate static bool_t 28057c478bd9Sstevel@tonic-gate xdr_LOCKT4args(XDR *xdrs, LOCKT4args *objp) 28067c478bd9Sstevel@tonic-gate { 28077c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 28087c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->locktype)) 28097c478bd9Sstevel@tonic-gate return (FALSE); 28107c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset)) 28117c478bd9Sstevel@tonic-gate return (FALSE); 28127c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length)) 28137c478bd9Sstevel@tonic-gate return (FALSE); 28147c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 28157c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->owner.clientid)) 28167c478bd9Sstevel@tonic-gate return (FALSE); 28177c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->owner.owner_val, 28187c478bd9Sstevel@tonic-gate (uint_t *)&objp->owner.owner_len, 28197c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)); 28207c478bd9Sstevel@tonic-gate } 28217c478bd9Sstevel@tonic-gate 28227c478bd9Sstevel@tonic-gate /* 28237c478bd9Sstevel@tonic-gate * Optimized free case 28247c478bd9Sstevel@tonic-gate */ 28257c478bd9Sstevel@tonic-gate if (objp->owner.owner_val != NULL) 28267c478bd9Sstevel@tonic-gate kmem_free(objp->owner.owner_val, objp->owner.owner_len); 28277c478bd9Sstevel@tonic-gate return (TRUE); 28287c478bd9Sstevel@tonic-gate } 28297c478bd9Sstevel@tonic-gate 28307c478bd9Sstevel@tonic-gate static bool_t 28317c478bd9Sstevel@tonic-gate xdr_LOCKT4res(XDR *xdrs, LOCKT4res *objp) 28327c478bd9Sstevel@tonic-gate { 28337c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 28347c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 28357c478bd9Sstevel@tonic-gate return (FALSE); 28367c478bd9Sstevel@tonic-gate if (objp->status == NFS4_OK) 28377c478bd9Sstevel@tonic-gate return (TRUE); 28387c478bd9Sstevel@tonic-gate if (objp->status != NFS4ERR_DENIED) 28397c478bd9Sstevel@tonic-gate return (TRUE); 28407c478bd9Sstevel@tonic-gate /* xdr_LOCK4denied */ 28417c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 28427c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->denied.offset)) 28437c478bd9Sstevel@tonic-gate return (FALSE); 28447c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 28457c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->denied.length)) 28467c478bd9Sstevel@tonic-gate return (FALSE); 28477c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->denied.locktype)) 28487c478bd9Sstevel@tonic-gate return (FALSE); 28497c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 28507c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->denied.owner.clientid)) 28517c478bd9Sstevel@tonic-gate return (FALSE); 28527c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, 28537c478bd9Sstevel@tonic-gate (char **)&objp->denied.owner.owner_val, 28547c478bd9Sstevel@tonic-gate (uint_t *)&objp->denied.owner.owner_len, 28557c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)); 28567c478bd9Sstevel@tonic-gate } 28577c478bd9Sstevel@tonic-gate 28587c478bd9Sstevel@tonic-gate /* 28597c478bd9Sstevel@tonic-gate * Optimized free case 28607c478bd9Sstevel@tonic-gate */ 28617c478bd9Sstevel@tonic-gate if (objp->status == NFS4_OK || objp->status != NFS4ERR_DENIED) 28627c478bd9Sstevel@tonic-gate return (TRUE); 28637c478bd9Sstevel@tonic-gate if (objp->denied.owner.owner_val != NULL) 28647c478bd9Sstevel@tonic-gate kmem_free(objp->denied.owner.owner_val, 28657c478bd9Sstevel@tonic-gate objp->denied.owner.owner_len); 28667c478bd9Sstevel@tonic-gate return (TRUE); 28677c478bd9Sstevel@tonic-gate } 28687c478bd9Sstevel@tonic-gate 28697c478bd9Sstevel@tonic-gate static bool_t 28707c478bd9Sstevel@tonic-gate xdr_LOCKU4args(XDR *xdrs, LOCKU4args *objp) 28717c478bd9Sstevel@tonic-gate { 28727c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->locktype)) 28737c478bd9Sstevel@tonic-gate return (FALSE); 28747c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->seqid)) 28757c478bd9Sstevel@tonic-gate return (FALSE); 28767c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->lock_stateid.seqid)) 28777c478bd9Sstevel@tonic-gate return (FALSE); 2878bbe876c0SMarcel Telka if (!xdr_opaque(xdrs, objp->lock_stateid.other, NFS4_OTHER_SIZE)) 28797c478bd9Sstevel@tonic-gate return (FALSE); 28807c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset)) 28817c478bd9Sstevel@tonic-gate return (FALSE); 28827c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->length)); 28837c478bd9Sstevel@tonic-gate } 28847c478bd9Sstevel@tonic-gate 28857c478bd9Sstevel@tonic-gate static bool_t 28867c478bd9Sstevel@tonic-gate xdr_OPEN4args(XDR *xdrs, OPEN4args *objp) 28877c478bd9Sstevel@tonic-gate { 28887c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 28897c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->seqid)) 28907c478bd9Sstevel@tonic-gate return (FALSE); 28917c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->share_access)) 28927c478bd9Sstevel@tonic-gate return (FALSE); 28937c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->share_deny)) 28947c478bd9Sstevel@tonic-gate return (FALSE); 28957c478bd9Sstevel@tonic-gate 28967c478bd9Sstevel@tonic-gate /* xdr_open_owner4 */ 28977c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 28987c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->owner.clientid)) 28997c478bd9Sstevel@tonic-gate return (FALSE); 29007c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, (char **)&objp->owner.owner_val, 29017c478bd9Sstevel@tonic-gate (uint_t *)&objp->owner.owner_len, 29027c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)) 29037c478bd9Sstevel@tonic-gate return (FALSE); 29047c478bd9Sstevel@tonic-gate 29057c478bd9Sstevel@tonic-gate /* xdr_openflag4 */ 29067c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->opentype)) 29077c478bd9Sstevel@tonic-gate return (FALSE); 29087c478bd9Sstevel@tonic-gate if (objp->opentype == OPEN4_CREATE) { 29097c478bd9Sstevel@tonic-gate 29107c478bd9Sstevel@tonic-gate /* xdr_createhow4 */ 29117c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->mode)) 29127c478bd9Sstevel@tonic-gate return (FALSE); 29137c478bd9Sstevel@tonic-gate switch (objp->mode) { 29147c478bd9Sstevel@tonic-gate case UNCHECKED4: 29157c478bd9Sstevel@tonic-gate case GUARDED4: 29167c478bd9Sstevel@tonic-gate if (!xdr_fattr4(xdrs, 29177c478bd9Sstevel@tonic-gate &objp->createhow4_u.createattrs)) 29187c478bd9Sstevel@tonic-gate return (FALSE); 29197c478bd9Sstevel@tonic-gate break; 29207c478bd9Sstevel@tonic-gate case EXCLUSIVE4: 29217c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 29227c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->createhow4_u. 29237c478bd9Sstevel@tonic-gate createverf)) 29247c478bd9Sstevel@tonic-gate return (FALSE); 29257c478bd9Sstevel@tonic-gate break; 29267c478bd9Sstevel@tonic-gate default: 29277c478bd9Sstevel@tonic-gate return (FALSE); 29287c478bd9Sstevel@tonic-gate } 29297c478bd9Sstevel@tonic-gate } 29307c478bd9Sstevel@tonic-gate 29317c478bd9Sstevel@tonic-gate /* xdr_open_claim4 */ 29327c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->claim)) 29337c478bd9Sstevel@tonic-gate return (FALSE); 29347c478bd9Sstevel@tonic-gate 29357c478bd9Sstevel@tonic-gate switch (objp->claim) { 29367c478bd9Sstevel@tonic-gate case CLAIM_NULL: 29377c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u. 29387c478bd9Sstevel@tonic-gate file.utf8string_val, 29397c478bd9Sstevel@tonic-gate (uint_t *)&objp->open_claim4_u.file. 29407c478bd9Sstevel@tonic-gate utf8string_len, 29417c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 29427c478bd9Sstevel@tonic-gate case CLAIM_PREVIOUS: 29437c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 29447c478bd9Sstevel@tonic-gate (int *)&objp->open_claim4_u.delegate_type)); 29457c478bd9Sstevel@tonic-gate case CLAIM_DELEGATE_CUR: 29467c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, (uint_t *)&objp->open_claim4_u. 29477c478bd9Sstevel@tonic-gate delegate_cur_info.delegate_stateid.seqid)) 29487c478bd9Sstevel@tonic-gate return (FALSE); 29497c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->open_claim4_u. 29507c478bd9Sstevel@tonic-gate delegate_cur_info.delegate_stateid.other, 2951bbe876c0SMarcel Telka NFS4_OTHER_SIZE)) 29527c478bd9Sstevel@tonic-gate return (FALSE); 29537c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u. 29547c478bd9Sstevel@tonic-gate delegate_cur_info.file.utf8string_val, 29557c478bd9Sstevel@tonic-gate (uint_t *)&objp->open_claim4_u. 29567c478bd9Sstevel@tonic-gate delegate_cur_info.file.utf8string_len, 29577c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 29587c478bd9Sstevel@tonic-gate case CLAIM_DELEGATE_PREV: 29597c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->open_claim4_u. 29607c478bd9Sstevel@tonic-gate file_delegate_prev.utf8string_val, 29617c478bd9Sstevel@tonic-gate (uint_t *)&objp->open_claim4_u. 29627c478bd9Sstevel@tonic-gate file_delegate_prev.utf8string_len, 29637c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 29647c478bd9Sstevel@tonic-gate default: 29657c478bd9Sstevel@tonic-gate return (FALSE); 29667c478bd9Sstevel@tonic-gate } 29677c478bd9Sstevel@tonic-gate } 29687c478bd9Sstevel@tonic-gate 29697c478bd9Sstevel@tonic-gate /* 29707c478bd9Sstevel@tonic-gate * Optimized free case 29717c478bd9Sstevel@tonic-gate */ 29727c478bd9Sstevel@tonic-gate if (objp->owner.owner_val != NULL) 29737c478bd9Sstevel@tonic-gate kmem_free(objp->owner.owner_val, objp->owner.owner_len); 29747c478bd9Sstevel@tonic-gate 29757c478bd9Sstevel@tonic-gate if (objp->opentype == OPEN4_CREATE) { 29767c478bd9Sstevel@tonic-gate switch (objp->mode) { 29777c478bd9Sstevel@tonic-gate case UNCHECKED4: 29787c478bd9Sstevel@tonic-gate case GUARDED4: 29797c478bd9Sstevel@tonic-gate (void) xdr_fattr4(xdrs, 29807c478bd9Sstevel@tonic-gate &objp->createhow4_u.createattrs); 29817c478bd9Sstevel@tonic-gate break; 29827c478bd9Sstevel@tonic-gate case EXCLUSIVE4: 29837c478bd9Sstevel@tonic-gate default: 29847c478bd9Sstevel@tonic-gate break; 29857c478bd9Sstevel@tonic-gate } 29867c478bd9Sstevel@tonic-gate } 29877c478bd9Sstevel@tonic-gate 29887c478bd9Sstevel@tonic-gate switch (objp->claim) { 29897c478bd9Sstevel@tonic-gate case CLAIM_NULL: 29907c478bd9Sstevel@tonic-gate if (objp->open_claim4_u.file.utf8string_val != NULL) 29917c478bd9Sstevel@tonic-gate kmem_free(objp->open_claim4_u.file.utf8string_val, 29927c478bd9Sstevel@tonic-gate objp->open_claim4_u.file.utf8string_len); 29937c478bd9Sstevel@tonic-gate return (TRUE); 29947c478bd9Sstevel@tonic-gate case CLAIM_PREVIOUS: 29957c478bd9Sstevel@tonic-gate return (TRUE); 29967c478bd9Sstevel@tonic-gate case CLAIM_DELEGATE_CUR: 29977c478bd9Sstevel@tonic-gate if (objp->open_claim4_u.delegate_cur_info.file.utf8string_val != 29987c478bd9Sstevel@tonic-gate NULL) { 29997c478bd9Sstevel@tonic-gate kmem_free(objp->open_claim4_u.delegate_cur_info.file. 30007c478bd9Sstevel@tonic-gate utf8string_val, 30017c478bd9Sstevel@tonic-gate objp->open_claim4_u.delegate_cur_info.file. 30027c478bd9Sstevel@tonic-gate utf8string_len); 30037c478bd9Sstevel@tonic-gate } 30047c478bd9Sstevel@tonic-gate return (TRUE); 30057c478bd9Sstevel@tonic-gate case CLAIM_DELEGATE_PREV: 30067c478bd9Sstevel@tonic-gate if (objp->open_claim4_u.file_delegate_prev.utf8string_val != 30077c478bd9Sstevel@tonic-gate NULL) { 30087c478bd9Sstevel@tonic-gate kmem_free(objp->open_claim4_u.file_delegate_prev. 30097c478bd9Sstevel@tonic-gate utf8string_val, 30107c478bd9Sstevel@tonic-gate objp->open_claim4_u.file_delegate_prev. 30117c478bd9Sstevel@tonic-gate utf8string_len); 30127c478bd9Sstevel@tonic-gate } 30137c478bd9Sstevel@tonic-gate return (TRUE); 30147c478bd9Sstevel@tonic-gate default: 30157c478bd9Sstevel@tonic-gate return (TRUE); 30167c478bd9Sstevel@tonic-gate } 30177c478bd9Sstevel@tonic-gate } 30187c478bd9Sstevel@tonic-gate 30197c478bd9Sstevel@tonic-gate static bool_t 30207c478bd9Sstevel@tonic-gate xdr_OPEN4cargs(XDR *xdrs, OPEN4cargs *objp) 30217c478bd9Sstevel@tonic-gate { 30227c478bd9Sstevel@tonic-gate int op; 30237c478bd9Sstevel@tonic-gate int len; 30247c478bd9Sstevel@tonic-gate rpc_inline_t *ptr; 30257c478bd9Sstevel@tonic-gate 30267c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_ENCODE); 30277c478bd9Sstevel@tonic-gate 30287c478bd9Sstevel@tonic-gate /* 30297c478bd9Sstevel@tonic-gate * We must always define the client's open_owner to be 30307c478bd9Sstevel@tonic-gate * 4 byte aligned and sized. 30317c478bd9Sstevel@tonic-gate */ 30327c478bd9Sstevel@tonic-gate ASSERT(objp->owner.owner_len <= NFS4_OPAQUE_LIMIT); 30337c478bd9Sstevel@tonic-gate ASSERT(!(objp->owner.owner_len % BYTES_PER_XDR_UNIT)); 30347c478bd9Sstevel@tonic-gate 30357c478bd9Sstevel@tonic-gate len = objp->owner.owner_len; 30367c478bd9Sstevel@tonic-gate if ((ptr = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + len)) != NULL) { 30377c478bd9Sstevel@tonic-gate int i; 30387c478bd9Sstevel@tonic-gate int32_t *ip; 30397c478bd9Sstevel@tonic-gate 30407c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, OP_OPEN); 30417c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, objp->seqid); 30427c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, objp->share_access); 30437c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, objp->share_deny); 30447c478bd9Sstevel@tonic-gate 30457c478bd9Sstevel@tonic-gate /* xdr_open_owner4 */ 30467c478bd9Sstevel@tonic-gate IXDR_PUT_HYPER(ptr, objp->owner.clientid); 30477c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, objp->owner.owner_len); 30487c478bd9Sstevel@tonic-gate /* We know this is very short so don't bcopy */ 30497c478bd9Sstevel@tonic-gate ip = (int32_t *)objp->owner.owner_val; 30507c478bd9Sstevel@tonic-gate len /= BYTES_PER_XDR_UNIT; 30517c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) 30527c478bd9Sstevel@tonic-gate *ptr++ = *ip++; 30537c478bd9Sstevel@tonic-gate 30547c478bd9Sstevel@tonic-gate /* xdr_openflag4 */ 30557c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, objp->opentype); 30567c478bd9Sstevel@tonic-gate } else { 30577c478bd9Sstevel@tonic-gate op = OP_OPEN; 30587c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&op)) 30597c478bd9Sstevel@tonic-gate return (FALSE); 30607c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->seqid)) 30617c478bd9Sstevel@tonic-gate return (FALSE); 30627c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_access)) 30637c478bd9Sstevel@tonic-gate return (FALSE); 30647c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->share_deny)) 30657c478bd9Sstevel@tonic-gate return (FALSE); 30667c478bd9Sstevel@tonic-gate 30677c478bd9Sstevel@tonic-gate /* xdr_open_owner4 */ 30687c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 30697c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->owner.clientid)) 30707c478bd9Sstevel@tonic-gate return (FALSE); 30717c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->owner.owner_len)) 30727c478bd9Sstevel@tonic-gate return (FALSE); 30737c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->owner.owner_val, 30747c478bd9Sstevel@tonic-gate objp->owner.owner_len)) 30757c478bd9Sstevel@tonic-gate return (FALSE); 30767c478bd9Sstevel@tonic-gate 30777c478bd9Sstevel@tonic-gate /* xdr_openflag4 */ 30787c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->opentype)) 30797c478bd9Sstevel@tonic-gate return (FALSE); 30807c478bd9Sstevel@tonic-gate } 30817c478bd9Sstevel@tonic-gate 30827c478bd9Sstevel@tonic-gate if (objp->opentype == OPEN4_CREATE) { 30837c478bd9Sstevel@tonic-gate /* xdr_createhow4 */ 30847c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->mode)) 30857c478bd9Sstevel@tonic-gate return (FALSE); 30867c478bd9Sstevel@tonic-gate switch (objp->mode) { 30877c478bd9Sstevel@tonic-gate case UNCHECKED4: 30887c478bd9Sstevel@tonic-gate case GUARDED4: 30897c478bd9Sstevel@tonic-gate if (!xdr_fattr4(xdrs, 30907c478bd9Sstevel@tonic-gate &objp->createhow4_u.createattrs)) 30917c478bd9Sstevel@tonic-gate return (FALSE); 30927c478bd9Sstevel@tonic-gate break; 30937c478bd9Sstevel@tonic-gate case EXCLUSIVE4: 30947c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 30957c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->createhow4_u. 30967c478bd9Sstevel@tonic-gate createverf)) 30977c478bd9Sstevel@tonic-gate return (FALSE); 30987c478bd9Sstevel@tonic-gate break; 30997c478bd9Sstevel@tonic-gate default: 31007c478bd9Sstevel@tonic-gate return (FALSE); 31017c478bd9Sstevel@tonic-gate } 31027c478bd9Sstevel@tonic-gate } 31037c478bd9Sstevel@tonic-gate 31047c478bd9Sstevel@tonic-gate /* xdr_open_claim4 */ 31057c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->claim)) 31067c478bd9Sstevel@tonic-gate return (FALSE); 31077c478bd9Sstevel@tonic-gate 31087c478bd9Sstevel@tonic-gate switch (objp->claim) { 31097c478bd9Sstevel@tonic-gate case CLAIM_NULL: 31107c478bd9Sstevel@tonic-gate len = strlen(objp->open_claim4_u.cfile); 31117c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 31127c478bd9Sstevel@tonic-gate return (FALSE); 31137c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &len)) { 31147c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 31157c478bd9Sstevel@tonic-gate objp->open_claim4_u.cfile, len)); 31167c478bd9Sstevel@tonic-gate } 31177c478bd9Sstevel@tonic-gate return (FALSE); 31187c478bd9Sstevel@tonic-gate case CLAIM_PREVIOUS: 31197c478bd9Sstevel@tonic-gate return (XDR_PUTINT32(xdrs, 31207c478bd9Sstevel@tonic-gate (int32_t *)&objp->open_claim4_u.delegate_type)); 31217c478bd9Sstevel@tonic-gate case CLAIM_DELEGATE_CUR: 31227c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->open_claim4_u. 31237c478bd9Sstevel@tonic-gate delegate_cur_info.delegate_stateid.seqid)) 31247c478bd9Sstevel@tonic-gate return (FALSE); 31257c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->open_claim4_u. 31267c478bd9Sstevel@tonic-gate delegate_cur_info.delegate_stateid.other, 3127bbe876c0SMarcel Telka NFS4_OTHER_SIZE)) 31287c478bd9Sstevel@tonic-gate return (FALSE); 31297c478bd9Sstevel@tonic-gate len = strlen(objp->open_claim4_u.delegate_cur_info.cfile); 31307c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 31317c478bd9Sstevel@tonic-gate return (FALSE); 31327c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &len)) { 31337c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 31347c478bd9Sstevel@tonic-gate objp->open_claim4_u.delegate_cur_info.cfile, 31357c478bd9Sstevel@tonic-gate len)); 31367c478bd9Sstevel@tonic-gate } 31377c478bd9Sstevel@tonic-gate return (FALSE); 31387c478bd9Sstevel@tonic-gate case CLAIM_DELEGATE_PREV: 31397c478bd9Sstevel@tonic-gate len = strlen(objp->open_claim4_u.cfile_delegate_prev); 31407c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 31417c478bd9Sstevel@tonic-gate return (FALSE); 31427c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &len)) { 31437c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 31447c478bd9Sstevel@tonic-gate objp->open_claim4_u.cfile_delegate_prev, len)); 31457c478bd9Sstevel@tonic-gate } 31467c478bd9Sstevel@tonic-gate return (FALSE); 31477c478bd9Sstevel@tonic-gate default: 31487c478bd9Sstevel@tonic-gate return (FALSE); 31497c478bd9Sstevel@tonic-gate } 31507c478bd9Sstevel@tonic-gate } 31517c478bd9Sstevel@tonic-gate 31527c478bd9Sstevel@tonic-gate static bool_t 31537c478bd9Sstevel@tonic-gate xdr_OPEN4res(XDR *xdrs, OPEN4res *objp) 31547c478bd9Sstevel@tonic-gate { 31557c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 31567c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 31577c478bd9Sstevel@tonic-gate return (FALSE); 31587c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 31597c478bd9Sstevel@tonic-gate return (TRUE); 31607c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->stateid.seqid)) 31617c478bd9Sstevel@tonic-gate return (FALSE); 3162bbe876c0SMarcel Telka if (!xdr_opaque(xdrs, objp->stateid.other, NFS4_OTHER_SIZE)) 31637c478bd9Sstevel@tonic-gate return (FALSE); 31647c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->cinfo.atomic)) 31657c478bd9Sstevel@tonic-gate return (FALSE); 31667c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 31677c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->cinfo.before)) 31687c478bd9Sstevel@tonic-gate return (FALSE); 31697c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.after)) 31707c478bd9Sstevel@tonic-gate return (FALSE); 31717c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->rflags)) 31727c478bd9Sstevel@tonic-gate return (FALSE); 31737c478bd9Sstevel@tonic-gate if (!xdr_bitmap4(xdrs, &objp->attrset)) 31747c478bd9Sstevel@tonic-gate return (FALSE); 31757c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 31767c478bd9Sstevel@tonic-gate (int *)&objp->delegation.delegation_type)) 31777c478bd9Sstevel@tonic-gate return (FALSE); 31787c478bd9Sstevel@tonic-gate switch (objp->delegation.delegation_type) { 31797c478bd9Sstevel@tonic-gate case OPEN_DELEGATE_NONE: 31807c478bd9Sstevel@tonic-gate return (TRUE); 31817c478bd9Sstevel@tonic-gate case OPEN_DELEGATE_READ: 31827c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->delegation. 31837c478bd9Sstevel@tonic-gate open_delegation4_u.read.stateid.seqid)) 31847c478bd9Sstevel@tonic-gate return (FALSE); 31857c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->delegation. 31867c478bd9Sstevel@tonic-gate open_delegation4_u.read.stateid.other, 3187bbe876c0SMarcel Telka NFS4_OTHER_SIZE)) 31887c478bd9Sstevel@tonic-gate return (FALSE); 31897c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->delegation. 31907c478bd9Sstevel@tonic-gate open_delegation4_u.read.recall)) 31917c478bd9Sstevel@tonic-gate return (FALSE); 31927c478bd9Sstevel@tonic-gate return (xdr_nfsace4(xdrs, &objp->delegation. 31937c478bd9Sstevel@tonic-gate open_delegation4_u.read.permissions)); 31947c478bd9Sstevel@tonic-gate case OPEN_DELEGATE_WRITE: 31957c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->delegation. 31967c478bd9Sstevel@tonic-gate open_delegation4_u.write.stateid.seqid)) 31977c478bd9Sstevel@tonic-gate return (FALSE); 31987c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->delegation. 31997c478bd9Sstevel@tonic-gate open_delegation4_u.write.stateid.other, 3200bbe876c0SMarcel Telka NFS4_OTHER_SIZE)) 32017c478bd9Sstevel@tonic-gate return (FALSE); 32027c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->delegation. 32037c478bd9Sstevel@tonic-gate open_delegation4_u.write.recall)) 32047c478bd9Sstevel@tonic-gate return (FALSE); 32057c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->delegation. 32067c478bd9Sstevel@tonic-gate open_delegation4_u.write.space_limit. 32077c478bd9Sstevel@tonic-gate limitby)) 32087c478bd9Sstevel@tonic-gate return (FALSE); 32097c478bd9Sstevel@tonic-gate switch (objp->delegation. 32107c478bd9Sstevel@tonic-gate open_delegation4_u.write.space_limit. 32117c478bd9Sstevel@tonic-gate limitby) { 32127c478bd9Sstevel@tonic-gate case NFS_LIMIT_SIZE: 32137c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 32147c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->delegation. 32157c478bd9Sstevel@tonic-gate open_delegation4_u.write.space_limit. 32167c478bd9Sstevel@tonic-gate nfs_space_limit4_u.filesize)) 32177c478bd9Sstevel@tonic-gate return (FALSE); 32187c478bd9Sstevel@tonic-gate break; 32197c478bd9Sstevel@tonic-gate case NFS_LIMIT_BLOCKS: 32207c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, 32217c478bd9Sstevel@tonic-gate &objp->delegation.open_delegation4_u.write. 32227c478bd9Sstevel@tonic-gate space_limit.nfs_space_limit4_u. 32237c478bd9Sstevel@tonic-gate mod_blocks.num_blocks)) 32247c478bd9Sstevel@tonic-gate return (FALSE); 32257c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->delegation. 32267c478bd9Sstevel@tonic-gate open_delegation4_u.write.space_limit. 32277c478bd9Sstevel@tonic-gate nfs_space_limit4_u.mod_blocks. 32287c478bd9Sstevel@tonic-gate bytes_per_block)) 32297c478bd9Sstevel@tonic-gate return (FALSE); 32307c478bd9Sstevel@tonic-gate break; 32317c478bd9Sstevel@tonic-gate default: 32327c478bd9Sstevel@tonic-gate return (FALSE); 32337c478bd9Sstevel@tonic-gate } 32347c478bd9Sstevel@tonic-gate return (xdr_nfsace4(xdrs, &objp->delegation. 32357c478bd9Sstevel@tonic-gate open_delegation4_u.write.permissions)); 32367c478bd9Sstevel@tonic-gate } 32377c478bd9Sstevel@tonic-gate return (FALSE); 32387c478bd9Sstevel@tonic-gate } 32397c478bd9Sstevel@tonic-gate 32407c478bd9Sstevel@tonic-gate /* 32417c478bd9Sstevel@tonic-gate * Optimized free case 32427c478bd9Sstevel@tonic-gate */ 32437c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 32447c478bd9Sstevel@tonic-gate return (TRUE); 32457c478bd9Sstevel@tonic-gate 32467c478bd9Sstevel@tonic-gate switch (objp->delegation.delegation_type) { 32477c478bd9Sstevel@tonic-gate case OPEN_DELEGATE_NONE: 32487c478bd9Sstevel@tonic-gate return (TRUE); 32497c478bd9Sstevel@tonic-gate case OPEN_DELEGATE_READ: 32507c478bd9Sstevel@tonic-gate return (xdr_nfsace4(xdrs, &objp->delegation. 32517c478bd9Sstevel@tonic-gate open_delegation4_u.read.permissions)); 32527c478bd9Sstevel@tonic-gate case OPEN_DELEGATE_WRITE: 32537c478bd9Sstevel@tonic-gate switch (objp->delegation. 32547c478bd9Sstevel@tonic-gate open_delegation4_u.write.space_limit.limitby) { 32557c478bd9Sstevel@tonic-gate case NFS_LIMIT_SIZE: 32567c478bd9Sstevel@tonic-gate case NFS_LIMIT_BLOCKS: 32577c478bd9Sstevel@tonic-gate break; 32587c478bd9Sstevel@tonic-gate default: 32597c478bd9Sstevel@tonic-gate return (FALSE); 32607c478bd9Sstevel@tonic-gate } 32617c478bd9Sstevel@tonic-gate return (xdr_nfsace4(xdrs, &objp->delegation. 32627c478bd9Sstevel@tonic-gate open_delegation4_u.write.permissions)); 32637c478bd9Sstevel@tonic-gate } 32647c478bd9Sstevel@tonic-gate return (FALSE); 32657c478bd9Sstevel@tonic-gate } 32667c478bd9Sstevel@tonic-gate 32677c478bd9Sstevel@tonic-gate static bool_t 32687c478bd9Sstevel@tonic-gate xdr_OPEN_CONFIRM4res(XDR *xdrs, OPEN_CONFIRM4res *objp) 32697c478bd9Sstevel@tonic-gate { 32707c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 32717c478bd9Sstevel@tonic-gate return (FALSE); 32727c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 32737c478bd9Sstevel@tonic-gate return (TRUE); 32747c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->open_stateid.seqid)) 32757c478bd9Sstevel@tonic-gate return (FALSE); 3276bbe876c0SMarcel Telka return (xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE)); 32777c478bd9Sstevel@tonic-gate } 32787c478bd9Sstevel@tonic-gate 32797c478bd9Sstevel@tonic-gate static bool_t 32807c478bd9Sstevel@tonic-gate xdr_OPEN_DOWNGRADE4args(XDR *xdrs, OPEN_DOWNGRADE4args *objp) 32817c478bd9Sstevel@tonic-gate { 32827c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->open_stateid.seqid)) 32837c478bd9Sstevel@tonic-gate return (FALSE); 3284bbe876c0SMarcel Telka if (!xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE)) 32857c478bd9Sstevel@tonic-gate return (FALSE); 32867c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->seqid)) 32877c478bd9Sstevel@tonic-gate return (FALSE); 32887c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->share_access)) 32897c478bd9Sstevel@tonic-gate return (FALSE); 32907c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->share_deny)); 32917c478bd9Sstevel@tonic-gate } 32927c478bd9Sstevel@tonic-gate 32937c478bd9Sstevel@tonic-gate static bool_t 32947c478bd9Sstevel@tonic-gate xdr_OPEN_DOWNGRADE4res(XDR *xdrs, OPEN_DOWNGRADE4res *objp) 32957c478bd9Sstevel@tonic-gate { 32967c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 32977c478bd9Sstevel@tonic-gate return (FALSE); 32987c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 32997c478bd9Sstevel@tonic-gate return (TRUE); 33007c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->open_stateid.seqid)) 33017c478bd9Sstevel@tonic-gate return (FALSE); 3302bbe876c0SMarcel Telka return (xdr_opaque(xdrs, objp->open_stateid.other, NFS4_OTHER_SIZE)); 33037c478bd9Sstevel@tonic-gate } 33047c478bd9Sstevel@tonic-gate 33057c478bd9Sstevel@tonic-gate static bool_t 33067c478bd9Sstevel@tonic-gate xdr_READ4args(XDR *xdrs, READ4args *objp) 33077c478bd9Sstevel@tonic-gate { 33080a701b1eSRobert Gordon rdma_chunkinfo_t rci; 33090a701b1eSRobert Gordon rdma_wlist_conn_info_t rwci; 33100a701b1eSRobert Gordon struct xdr_ops *xops = xdrrdma_xops(); 33110a701b1eSRobert Gordon 33127c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->stateid.seqid)) 33137c478bd9Sstevel@tonic-gate return (FALSE); 3314bbe876c0SMarcel Telka if (!xdr_opaque(xdrs, objp->stateid.other, NFS4_OTHER_SIZE)) 33157c478bd9Sstevel@tonic-gate return (FALSE); 33167c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset)) 33177c478bd9Sstevel@tonic-gate return (FALSE); 33180a701b1eSRobert Gordon if (!xdr_u_int(xdrs, &objp->count)) 33190a701b1eSRobert Gordon return (FALSE); 33200a701b1eSRobert Gordon 33210a701b1eSRobert Gordon DTRACE_PROBE1(xdr__i__read4args_buf_len, 33220a701b1eSRobert Gordon int, objp->count); 33230a701b1eSRobert Gordon 33240a701b1eSRobert Gordon objp->wlist = NULL; 33250a701b1eSRobert Gordon 33260a701b1eSRobert Gordon if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) { 33270a701b1eSRobert Gordon rci.rci_type = RCI_WRITE_ADDR_CHUNK; 33280a701b1eSRobert Gordon rci.rci_len = objp->count; 33290a701b1eSRobert Gordon (void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci); 33300a701b1eSRobert Gordon } 33310a701b1eSRobert Gordon 33320a701b1eSRobert Gordon if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE) 33330a701b1eSRobert Gordon return (TRUE); 33340a701b1eSRobert Gordon 33350a701b1eSRobert Gordon if (xdrs->x_op == XDR_ENCODE) { 33360a701b1eSRobert Gordon if (objp->res_uiop != NULL) { 33370a701b1eSRobert Gordon rci.rci_type = RCI_WRITE_UIO_CHUNK; 33380a701b1eSRobert Gordon rci.rci_a.rci_uiop = objp->res_uiop; 33390a701b1eSRobert Gordon rci.rci_len = objp->count; 33400a701b1eSRobert Gordon rci.rci_clpp = &objp->wlist; 33410a701b1eSRobert Gordon } else { 33420a701b1eSRobert Gordon rci.rci_type = RCI_WRITE_ADDR_CHUNK; 33430a701b1eSRobert Gordon rci.rci_a.rci_addr = objp->res_data_val_alt; 33440a701b1eSRobert Gordon rci.rci_len = objp->count; 33450a701b1eSRobert Gordon rci.rci_clpp = &objp->wlist; 33460a701b1eSRobert Gordon } 33470a701b1eSRobert Gordon 33480a701b1eSRobert Gordon return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci)); 33490a701b1eSRobert Gordon } 33500a701b1eSRobert Gordon 33510a701b1eSRobert Gordon /* XDR_DECODE case */ 33520a701b1eSRobert Gordon (void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci); 33530a701b1eSRobert Gordon objp->wlist = rwci.rwci_wlist; 33540a701b1eSRobert Gordon objp->conn = rwci.rwci_conn; 33550a701b1eSRobert Gordon 33560a701b1eSRobert Gordon return (TRUE); 33577c478bd9Sstevel@tonic-gate } 33587c478bd9Sstevel@tonic-gate 33597c478bd9Sstevel@tonic-gate static bool_t 33607c478bd9Sstevel@tonic-gate xdr_READ4res(XDR *xdrs, READ4res *objp) 33617c478bd9Sstevel@tonic-gate { 33627c478bd9Sstevel@tonic-gate mblk_t *mp; 33637c478bd9Sstevel@tonic-gate 33647c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) 33657c478bd9Sstevel@tonic-gate return (FALSE); 33667c478bd9Sstevel@tonic-gate 33677c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) { 33687c478bd9Sstevel@tonic-gate /* 33697c478bd9Sstevel@tonic-gate * Optimized free case 33707c478bd9Sstevel@tonic-gate */ 33717c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 33727c478bd9Sstevel@tonic-gate return (TRUE); 33737c478bd9Sstevel@tonic-gate if (objp->data_val != NULL) 33747c478bd9Sstevel@tonic-gate kmem_free(objp->data_val, objp->data_len); 33757c478bd9Sstevel@tonic-gate return (TRUE); 33767c478bd9Sstevel@tonic-gate } 33777c478bd9Sstevel@tonic-gate 33787c478bd9Sstevel@tonic-gate /* on with ENCODE paths */ 33797c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->status)) 33807c478bd9Sstevel@tonic-gate return (FALSE); 33817c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 33827c478bd9Sstevel@tonic-gate return (TRUE); 33837c478bd9Sstevel@tonic-gate 33847c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &objp->eof)) 33857c478bd9Sstevel@tonic-gate return (FALSE); 33867c478bd9Sstevel@tonic-gate 33877c478bd9Sstevel@tonic-gate mp = objp->mblk; 3388e36d7b11SSebastien Roy if (mp != NULL) { 3389e36d7b11SSebastien Roy if (xdrs->x_ops == &xdrmblk_ops) { 3390e36d7b11SSebastien Roy if (xdrmblk_putmblk(xdrs, mp, objp->data_len)) { 33917c478bd9Sstevel@tonic-gate objp->mblk = NULL; 33927c478bd9Sstevel@tonic-gate return (TRUE); 3393e36d7b11SSebastien Roy } else { 3394e36d7b11SSebastien Roy return (FALSE); 33957c478bd9Sstevel@tonic-gate } 3396e36d7b11SSebastien Roy } else if (mp->b_cont != NULL) { 3397e36d7b11SSebastien Roy /* 3398e36d7b11SSebastien Roy * See xdr_READ3res() for an explanation of why we need 3399e36d7b11SSebastien Roy * to do a pullup here. 3400e36d7b11SSebastien Roy */ 3401e36d7b11SSebastien Roy if (pullupmsg(mp, -1) == 0) 3402e36d7b11SSebastien Roy return (FALSE); 3403e36d7b11SSebastien Roy objp->data_val = (caddr_t)mp->b_rptr; 3404e36d7b11SSebastien Roy } 3405e36d7b11SSebastien Roy } else { 34060a701b1eSRobert Gordon if (xdr_u_int(xdrs, &objp->data_len) == FALSE) { 34070a701b1eSRobert Gordon return (FALSE); 34087c478bd9Sstevel@tonic-gate } 34090a701b1eSRobert Gordon /* 34100a701b1eSRobert Gordon * If read data sent by wlist (RDMA_WRITE), don't do 34110a701b1eSRobert Gordon * xdr_bytes() below. RDMA_WRITE transfers the data. 34120a701b1eSRobert Gordon * Note: this is encode-only because the client code 34130a701b1eSRobert Gordon * uses xdr_READ4res_clnt to decode results. 34140a701b1eSRobert Gordon */ 34150a701b1eSRobert Gordon if (objp->wlist) { 34160a701b1eSRobert Gordon if (objp->data_len != 0) { 34170a701b1eSRobert Gordon return (xdrrdma_send_read_data( 3418f837ee4aSSiddheshwar Mahesh xdrs, objp->data_len, objp->wlist)); 34190a701b1eSRobert Gordon } 34200a701b1eSRobert Gordon return (TRUE); 34210a701b1eSRobert Gordon } 34220a701b1eSRobert Gordon } 34230a701b1eSRobert Gordon 34247c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->data_val, 34257c478bd9Sstevel@tonic-gate (uint_t *)&objp->data_len, 34267c478bd9Sstevel@tonic-gate objp->data_len)); 34277c478bd9Sstevel@tonic-gate } 34287c478bd9Sstevel@tonic-gate 34297c478bd9Sstevel@tonic-gate static bool_t 34307c478bd9Sstevel@tonic-gate xdr_READ4res_clnt(XDR *xdrs, READ4res *objp, READ4args *aobjp) 34317c478bd9Sstevel@tonic-gate { 34327c478bd9Sstevel@tonic-gate mblk_t *mp; 34337c478bd9Sstevel@tonic-gate size_t n; 34347c478bd9Sstevel@tonic-gate int error; 34357c478bd9Sstevel@tonic-gate uint_t size = aobjp->res_maxsize; 34360a701b1eSRobert Gordon count4 ocount; 34377c478bd9Sstevel@tonic-gate 34387c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) 34397c478bd9Sstevel@tonic-gate return (FALSE); 34407c478bd9Sstevel@tonic-gate 34417c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) { 34427c478bd9Sstevel@tonic-gate /* 34437c478bd9Sstevel@tonic-gate * Optimized free case 34447c478bd9Sstevel@tonic-gate */ 34457c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 34467c478bd9Sstevel@tonic-gate return (TRUE); 34477c478bd9Sstevel@tonic-gate if (objp->data_val != NULL) 34487c478bd9Sstevel@tonic-gate kmem_free(objp->data_val, objp->data_len); 34497c478bd9Sstevel@tonic-gate return (TRUE); 34507c478bd9Sstevel@tonic-gate } 34517c478bd9Sstevel@tonic-gate 34527c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status)) 34537c478bd9Sstevel@tonic-gate return (FALSE); 34547c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 34557c478bd9Sstevel@tonic-gate return (TRUE); 34567c478bd9Sstevel@tonic-gate 34577c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, &objp->eof)) 34587c478bd9Sstevel@tonic-gate return (FALSE); 34597c478bd9Sstevel@tonic-gate 34607c478bd9Sstevel@tonic-gate 34617c478bd9Sstevel@tonic-gate /* 34627c478bd9Sstevel@tonic-gate * This is a special case such that the caller is providing a 34637c478bd9Sstevel@tonic-gate * uio as a guide to eventual data location; this is used for 34647c478bd9Sstevel@tonic-gate * handling DIRECTIO reads. 34657c478bd9Sstevel@tonic-gate */ 34667c478bd9Sstevel@tonic-gate if (aobjp->res_uiop != NULL) { 34677c478bd9Sstevel@tonic-gate struct uio *uiop = aobjp->res_uiop; 34687c478bd9Sstevel@tonic-gate int32_t *ptr; 34697c478bd9Sstevel@tonic-gate 34707c478bd9Sstevel@tonic-gate if (xdrs->x_ops == &xdrmblk_ops) { 34717c478bd9Sstevel@tonic-gate if (!xdrmblk_getmblk(xdrs, &mp, &objp->data_len)) 34727c478bd9Sstevel@tonic-gate return (FALSE); 34737c478bd9Sstevel@tonic-gate 34747c478bd9Sstevel@tonic-gate if (objp->data_len == 0) 34757c478bd9Sstevel@tonic-gate return (TRUE); 34767c478bd9Sstevel@tonic-gate 34777c478bd9Sstevel@tonic-gate if (objp->data_len > size) 34787c478bd9Sstevel@tonic-gate return (FALSE); 34797c478bd9Sstevel@tonic-gate 34807c478bd9Sstevel@tonic-gate size = objp->data_len; 34817c478bd9Sstevel@tonic-gate do { 34827c478bd9Sstevel@tonic-gate n = MIN(size, mp->b_wptr - mp->b_rptr); 34837c478bd9Sstevel@tonic-gate if ((n = MIN(uiop->uio_resid, n)) != 0) { 34847c478bd9Sstevel@tonic-gate 34857c478bd9Sstevel@tonic-gate error = uiomove((char *)mp->b_rptr, n, 34867c478bd9Sstevel@tonic-gate UIO_READ, uiop); 34877c478bd9Sstevel@tonic-gate if (error) 34887c478bd9Sstevel@tonic-gate return (FALSE); 34897c478bd9Sstevel@tonic-gate mp->b_rptr += n; 34907c478bd9Sstevel@tonic-gate size -= n; 34917c478bd9Sstevel@tonic-gate } 34927c478bd9Sstevel@tonic-gate 34937c478bd9Sstevel@tonic-gate while (mp && (mp->b_rptr >= mp->b_wptr)) 34947c478bd9Sstevel@tonic-gate mp = mp->b_cont; 34957c478bd9Sstevel@tonic-gate } while (mp && size > 0 && uiop->uio_resid > 0); 34967c478bd9Sstevel@tonic-gate 34977c478bd9Sstevel@tonic-gate return (TRUE); 34987c478bd9Sstevel@tonic-gate } 34997c478bd9Sstevel@tonic-gate 35000a701b1eSRobert Gordon if (xdrs->x_ops == &xdrrdma_ops) { 35010a701b1eSRobert Gordon struct clist *cl; 35020a701b1eSRobert Gordon 35030a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl); 35040a701b1eSRobert Gordon 35050a701b1eSRobert Gordon objp->wlist = cl; 35060a701b1eSRobert Gordon 35070a701b1eSRobert Gordon if (objp->wlist) { 35080a701b1eSRobert Gordon /* opaque count */ 35090a701b1eSRobert Gordon if (!xdr_u_int(xdrs, &ocount)) { 35100a701b1eSRobert Gordon objp->wlist = NULL; 35110a701b1eSRobert Gordon return (FALSE); 35120a701b1eSRobert Gordon } 35130a701b1eSRobert Gordon 3514f837ee4aSSiddheshwar Mahesh objp->wlist_len = clist_len(cl); 3515f837ee4aSSiddheshwar Mahesh objp->data_len = ocount; 35160a701b1eSRobert Gordon 3517f837ee4aSSiddheshwar Mahesh if (objp->wlist_len != 3518f837ee4aSSiddheshwar Mahesh roundup( 3519f837ee4aSSiddheshwar Mahesh objp->data_len, BYTES_PER_XDR_UNIT)) { 35200a701b1eSRobert Gordon DTRACE_PROBE2( 35210a701b1eSRobert Gordon xdr__e__read4resuio_clnt_fail, 35220a701b1eSRobert Gordon int, ocount, 35230a701b1eSRobert Gordon int, objp->data_len); 35240a701b1eSRobert Gordon objp->wlist = NULL; 35250a701b1eSRobert Gordon return (FALSE); 35260a701b1eSRobert Gordon } 35270a701b1eSRobert Gordon 35280a701b1eSRobert Gordon uiop->uio_resid -= objp->data_len; 35290a701b1eSRobert Gordon uiop->uio_iov->iov_len -= objp->data_len; 35300a701b1eSRobert Gordon uiop->uio_iov->iov_base += objp->data_len; 35310a701b1eSRobert Gordon uiop->uio_loffset += objp->data_len; 35320a701b1eSRobert Gordon 35330a701b1eSRobert Gordon objp->wlist = NULL; 35340a701b1eSRobert Gordon return (TRUE); 35350a701b1eSRobert Gordon } 35360a701b1eSRobert Gordon } 35370a701b1eSRobert Gordon 35387c478bd9Sstevel@tonic-gate /* 35390a701b1eSRobert Gordon * This isn't an xdrmblk stream nor RDMA. 35400a701b1eSRobert Gordon * Handle the likely case that it can be 35410a701b1eSRobert Gordon * inlined (ex. xdrmem). 35427c478bd9Sstevel@tonic-gate */ 35437c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&objp->data_len)) 35447c478bd9Sstevel@tonic-gate return (FALSE); 35457c478bd9Sstevel@tonic-gate 35467c478bd9Sstevel@tonic-gate if (objp->data_len == 0) 35477c478bd9Sstevel@tonic-gate return (TRUE); 35487c478bd9Sstevel@tonic-gate 35497c478bd9Sstevel@tonic-gate if (objp->data_len > size) 35507c478bd9Sstevel@tonic-gate return (FALSE); 35517c478bd9Sstevel@tonic-gate 35527c478bd9Sstevel@tonic-gate size = (int)objp->data_len; 35537c478bd9Sstevel@tonic-gate if ((ptr = XDR_INLINE(xdrs, size)) != NULL) 35547c478bd9Sstevel@tonic-gate return (uiomove(ptr, size, UIO_READ, uiop) ? 35557c478bd9Sstevel@tonic-gate FALSE : TRUE); 35567c478bd9Sstevel@tonic-gate 35577c478bd9Sstevel@tonic-gate /* 35587c478bd9Sstevel@tonic-gate * Handle some other (unlikely) stream type that will 35597c478bd9Sstevel@tonic-gate * need a copy. 35607c478bd9Sstevel@tonic-gate */ 35617c478bd9Sstevel@tonic-gate if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL) 35627c478bd9Sstevel@tonic-gate return (FALSE); 35637c478bd9Sstevel@tonic-gate 35647c478bd9Sstevel@tonic-gate if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) { 35657c478bd9Sstevel@tonic-gate kmem_free(ptr, size); 35667c478bd9Sstevel@tonic-gate return (FALSE); 35677c478bd9Sstevel@tonic-gate } 35687c478bd9Sstevel@tonic-gate error = uiomove(ptr, size, UIO_READ, uiop); 35697c478bd9Sstevel@tonic-gate kmem_free(ptr, size); 35707c478bd9Sstevel@tonic-gate 35717c478bd9Sstevel@tonic-gate return (error ? FALSE : TRUE); 35727c478bd9Sstevel@tonic-gate } 35737c478bd9Sstevel@tonic-gate 35747c478bd9Sstevel@tonic-gate /* 35757c478bd9Sstevel@tonic-gate * Check for the other special case of the caller providing 35767c478bd9Sstevel@tonic-gate * the target area for the data. 35777c478bd9Sstevel@tonic-gate */ 35780a701b1eSRobert Gordon if (aobjp->res_data_val_alt == NULL) 35790a701b1eSRobert Gordon return (FALSE); 35800a701b1eSRobert Gordon 35810a701b1eSRobert Gordon /* 35820a701b1eSRobert Gordon * If read data received via RDMA_WRITE, don't do xdr_bytes(). 35830a701b1eSRobert Gordon * RDMA_WRITE already moved the data so decode length of 35840a701b1eSRobert Gordon * RDMA_WRITE. 35850a701b1eSRobert Gordon */ 35860a701b1eSRobert Gordon if (xdrs->x_ops == &xdrrdma_ops) { 35870a701b1eSRobert Gordon struct clist *cl; 35880a701b1eSRobert Gordon 35890a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl); 35900a701b1eSRobert Gordon 35910a701b1eSRobert Gordon objp->wlist = cl; 35920a701b1eSRobert Gordon 35930a701b1eSRobert Gordon /* 35940a701b1eSRobert Gordon * Data transferred through inline if 35950a701b1eSRobert Gordon * objp->wlist == NULL 35960a701b1eSRobert Gordon */ 35970a701b1eSRobert Gordon if (objp->wlist) { 35980a701b1eSRobert Gordon /* opaque count */ 35990a701b1eSRobert Gordon if (!xdr_u_int(xdrs, &ocount)) { 36000a701b1eSRobert Gordon objp->wlist = NULL; 36010a701b1eSRobert Gordon return (FALSE); 36020a701b1eSRobert Gordon } 36030a701b1eSRobert Gordon 3604f837ee4aSSiddheshwar Mahesh objp->wlist_len = clist_len(cl); 3605f837ee4aSSiddheshwar Mahesh objp->data_len = ocount; 36060a701b1eSRobert Gordon 3607f837ee4aSSiddheshwar Mahesh if (objp->wlist_len != 3608f837ee4aSSiddheshwar Mahesh roundup( 3609f837ee4aSSiddheshwar Mahesh objp->data_len, BYTES_PER_XDR_UNIT)) { 36100a701b1eSRobert Gordon DTRACE_PROBE2( 36110a701b1eSRobert Gordon xdr__e__read4res_clnt_fail, 36120a701b1eSRobert Gordon int, ocount, 36130a701b1eSRobert Gordon int, objp->data_len); 36140a701b1eSRobert Gordon objp->wlist = NULL; 36150a701b1eSRobert Gordon return (FALSE); 36160a701b1eSRobert Gordon } 36170a701b1eSRobert Gordon 36180a701b1eSRobert Gordon objp->wlist = NULL; 36190a701b1eSRobert Gordon return (TRUE); 36200a701b1eSRobert Gordon } 36210a701b1eSRobert Gordon } 36220a701b1eSRobert Gordon 36237c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&aobjp->res_data_val_alt, 36247c478bd9Sstevel@tonic-gate (uint_t *)&objp->data_len, 36257c478bd9Sstevel@tonic-gate aobjp->res_maxsize)); 36267c478bd9Sstevel@tonic-gate } 36277c478bd9Sstevel@tonic-gate 36287c478bd9Sstevel@tonic-gate static bool_t 36297c478bd9Sstevel@tonic-gate xdr_READDIR4args(XDR *xdrs, READDIR4args *objp) 36307c478bd9Sstevel@tonic-gate { 36310a701b1eSRobert Gordon rdma_chunkinfo_t rci; 36320a701b1eSRobert Gordon struct xdr_ops *xops = xdrrdma_xops(); 36330a701b1eSRobert Gordon 36340a701b1eSRobert Gordon if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) && 36350a701b1eSRobert Gordon xdrs->x_op == XDR_ENCODE) { 36360a701b1eSRobert Gordon rci.rci_type = RCI_REPLY_CHUNK; 36370a701b1eSRobert Gordon rci.rci_len = objp->maxcount; 36380a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci); 36390a701b1eSRobert Gordon } 36400a701b1eSRobert Gordon 36417c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookie)) 36427c478bd9Sstevel@tonic-gate return (FALSE); 36437c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cookieverf)) 36447c478bd9Sstevel@tonic-gate return (FALSE); 36457c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->dircount)) 36467c478bd9Sstevel@tonic-gate return (FALSE); 36477c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->maxcount)) 36487c478bd9Sstevel@tonic-gate return (FALSE); 36497c478bd9Sstevel@tonic-gate return (xdr_bitmap4(xdrs, &objp->attr_request)); 36507c478bd9Sstevel@tonic-gate } 36517c478bd9Sstevel@tonic-gate 36527c478bd9Sstevel@tonic-gate /* ARGSUSED */ 36537c478bd9Sstevel@tonic-gate static bool_t 36547c478bd9Sstevel@tonic-gate xdrmblk_putmblk_rd(XDR *xdrs, mblk_t *m) 36557c478bd9Sstevel@tonic-gate { 36567c478bd9Sstevel@tonic-gate if (((m->b_wptr - m->b_rptr) % BYTES_PER_XDR_UNIT) != 0) 36577c478bd9Sstevel@tonic-gate return (FALSE); 36587c478bd9Sstevel@tonic-gate 36597c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 36607c478bd9Sstevel@tonic-gate ((mblk_t *)xdrs->x_base)->b_cont = m; 36617c478bd9Sstevel@tonic-gate xdrs->x_base = (caddr_t)m; 36627c478bd9Sstevel@tonic-gate xdrs->x_handy = 0; 36637c478bd9Sstevel@tonic-gate return (TRUE); 36647c478bd9Sstevel@tonic-gate } 36657c478bd9Sstevel@tonic-gate 36667c478bd9Sstevel@tonic-gate bool_t 36677c478bd9Sstevel@tonic-gate xdr_READDIR4res(XDR *xdrs, READDIR4res *objp) 36687c478bd9Sstevel@tonic-gate { 36697c478bd9Sstevel@tonic-gate mblk_t *mp = objp->mblk; 36707c478bd9Sstevel@tonic-gate bool_t ret_val; 36717c478bd9Sstevel@tonic-gate uint_t flags = 0; 36727c478bd9Sstevel@tonic-gate 36737c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_ENCODE); 36747c478bd9Sstevel@tonic-gate 36757c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 36767c478bd9Sstevel@tonic-gate return (FALSE); 36777c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 36787c478bd9Sstevel@tonic-gate return (TRUE); 36797c478bd9Sstevel@tonic-gate if (mp == NULL) 36807c478bd9Sstevel@tonic-gate return (FALSE); 36817c478bd9Sstevel@tonic-gate 36827c478bd9Sstevel@tonic-gate if (xdrs->x_ops == &xdrmblk_ops) { 36837c478bd9Sstevel@tonic-gate if (xdrmblk_putmblk_rd(xdrs, mp) 36847c478bd9Sstevel@tonic-gate == TRUE) { 36857c478bd9Sstevel@tonic-gate /* mblk successfully inserted into outgoing chain */ 36867c478bd9Sstevel@tonic-gate objp->mblk = NULL; 36877c478bd9Sstevel@tonic-gate return (TRUE); 36887c478bd9Sstevel@tonic-gate } 36897c478bd9Sstevel@tonic-gate } 36907c478bd9Sstevel@tonic-gate 36917c478bd9Sstevel@tonic-gate ASSERT(mp->b_cont == NULL); 36927c478bd9Sstevel@tonic-gate 36937c478bd9Sstevel@tonic-gate /* 36940a701b1eSRobert Gordon * If transport is RDMA, the pre-encoded m_blk needs to be moved 36957c478bd9Sstevel@tonic-gate * without being chunked. 36960a701b1eSRobert Gordon * Check if chunking is enabled for the xdr stream. 36970a701b1eSRobert Gordon * If it is enabled, disable it temporarily for this op, 36980a701b1eSRobert Gordon * then re-enable. 36997c478bd9Sstevel@tonic-gate */ 37000a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_GET_FLAGS, &flags); 37010a701b1eSRobert Gordon 37020a701b1eSRobert Gordon if (!(flags & XDR_RDMA_CHUNK)) 37037c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len)); 37047c478bd9Sstevel@tonic-gate 37050a701b1eSRobert Gordon flags &= ~XDR_RDMA_CHUNK; 37060a701b1eSRobert Gordon 37070a701b1eSRobert Gordon (void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags); 37080a701b1eSRobert Gordon 37097c478bd9Sstevel@tonic-gate ret_val = xdr_opaque(xdrs, (char *)mp->b_rptr, objp->data_len); 37100a701b1eSRobert Gordon 37110a701b1eSRobert Gordon flags |= XDR_RDMA_CHUNK; 37120a701b1eSRobert Gordon 37130a701b1eSRobert Gordon (void) XDR_CONTROL(xdrs, XDR_RDMA_SET_FLAGS, &flags); 37140a701b1eSRobert Gordon 37157c478bd9Sstevel@tonic-gate return (ret_val); 37167c478bd9Sstevel@tonic-gate } 37177c478bd9Sstevel@tonic-gate 37187c478bd9Sstevel@tonic-gate static bool_t 37197c478bd9Sstevel@tonic-gate xdr_READLINK4res(XDR *xdrs, READLINK4res *objp) 37207c478bd9Sstevel@tonic-gate { 37217c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 37227c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 37237c478bd9Sstevel@tonic-gate return (FALSE); 37247c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 37257c478bd9Sstevel@tonic-gate return (TRUE); 3726bbe876c0SMarcel Telka return (xdr_bytes(xdrs, (char **)&objp->link.linktext4_val, 3727bbe876c0SMarcel Telka (uint_t *)&objp->link.linktext4_len, 37287c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 37297c478bd9Sstevel@tonic-gate } 37307c478bd9Sstevel@tonic-gate 37317c478bd9Sstevel@tonic-gate /* 37327c478bd9Sstevel@tonic-gate * Optimized free case 37337c478bd9Sstevel@tonic-gate */ 37347c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 37357c478bd9Sstevel@tonic-gate return (TRUE); 3736bbe876c0SMarcel Telka if (objp->link.linktext4_val != NULL) 3737bbe876c0SMarcel Telka kmem_free(objp->link.linktext4_val, objp->link.linktext4_len); 37387c478bd9Sstevel@tonic-gate return (TRUE); 37397c478bd9Sstevel@tonic-gate } 37407c478bd9Sstevel@tonic-gate 37417c478bd9Sstevel@tonic-gate static bool_t 37427c478bd9Sstevel@tonic-gate xdr_REMOVE4res(XDR *xdrs, REMOVE4res *objp) 37437c478bd9Sstevel@tonic-gate { 37447c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 37457c478bd9Sstevel@tonic-gate return (FALSE); 37467c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 37477c478bd9Sstevel@tonic-gate return (TRUE); 37487c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->cinfo.atomic)) 37497c478bd9Sstevel@tonic-gate return (FALSE); 37507c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->cinfo.before)) 37517c478bd9Sstevel@tonic-gate return (FALSE); 37527c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, 37537c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->cinfo.after)); 37547c478bd9Sstevel@tonic-gate } 37557c478bd9Sstevel@tonic-gate 37567c478bd9Sstevel@tonic-gate static bool_t 37577c478bd9Sstevel@tonic-gate xdr_RENAME4res(XDR *xdrs, RENAME4res *objp) 37587c478bd9Sstevel@tonic-gate { 37597c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 37607c478bd9Sstevel@tonic-gate return (FALSE); 37617c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 37627c478bd9Sstevel@tonic-gate return (TRUE); 37637c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->source_cinfo.atomic)) 37647c478bd9Sstevel@tonic-gate return (FALSE); 37657c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 37667c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->source_cinfo.before)) 37677c478bd9Sstevel@tonic-gate return (FALSE); 37687c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 37697c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->source_cinfo.after)) 37707c478bd9Sstevel@tonic-gate return (FALSE); 37717c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->target_cinfo.atomic)) 37727c478bd9Sstevel@tonic-gate return (FALSE); 37737c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 37747c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->target_cinfo.before)) 37757c478bd9Sstevel@tonic-gate return (FALSE); 37767c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, 37777c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->target_cinfo.after)); 37787c478bd9Sstevel@tonic-gate } 37797c478bd9Sstevel@tonic-gate 37807c478bd9Sstevel@tonic-gate static bool_t 37817c478bd9Sstevel@tonic-gate xdr_secinfo4(XDR *xdrs, secinfo4 *objp) 37827c478bd9Sstevel@tonic-gate { 37837c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 37847c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->flavor)) 37857c478bd9Sstevel@tonic-gate return (FALSE); 37867c478bd9Sstevel@tonic-gate if (objp->flavor != RPCSEC_GSS) 37877c478bd9Sstevel@tonic-gate return (TRUE); 37887c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, 37897c478bd9Sstevel@tonic-gate (char **)&objp->flavor_info.oid.sec_oid4_val, 37907c478bd9Sstevel@tonic-gate (uint_t *)&objp->flavor_info.oid.sec_oid4_len, 37917c478bd9Sstevel@tonic-gate NFS4_MAX_SECOID4)) 37927c478bd9Sstevel@tonic-gate return (FALSE); 37937c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->flavor_info.qop)) 37947c478bd9Sstevel@tonic-gate return (FALSE); 37957c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, (int *)&objp->flavor_info.service)); 37967c478bd9Sstevel@tonic-gate } 37977c478bd9Sstevel@tonic-gate 37987c478bd9Sstevel@tonic-gate /* 37997c478bd9Sstevel@tonic-gate * Optimized free path 38007c478bd9Sstevel@tonic-gate */ 38017c478bd9Sstevel@tonic-gate if (objp->flavor != RPCSEC_GSS) 38027c478bd9Sstevel@tonic-gate return (TRUE); 38037c478bd9Sstevel@tonic-gate 38047c478bd9Sstevel@tonic-gate if (objp->flavor_info.oid.sec_oid4_val != NULL) 38057c478bd9Sstevel@tonic-gate kmem_free(objp->flavor_info.oid.sec_oid4_val, 38067c478bd9Sstevel@tonic-gate objp->flavor_info.oid.sec_oid4_len); 38077c478bd9Sstevel@tonic-gate return (TRUE); 38087c478bd9Sstevel@tonic-gate } 38097c478bd9Sstevel@tonic-gate 38107c478bd9Sstevel@tonic-gate static bool_t 38117c478bd9Sstevel@tonic-gate xdr_SETCLIENTID4args(XDR *xdrs, SETCLIENTID4args *objp) 38127c478bd9Sstevel@tonic-gate { 38137c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 38147c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 38157c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->client.verifier)) 38167c478bd9Sstevel@tonic-gate return (FALSE); 38177c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, (char **)&objp->client.id_val, 38187c478bd9Sstevel@tonic-gate (uint_t *)&objp->client.id_len, NFS4_OPAQUE_LIMIT)) 38197c478bd9Sstevel@tonic-gate return (FALSE); 38207c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->callback.cb_program)) 38217c478bd9Sstevel@tonic-gate return (FALSE); 38227c478bd9Sstevel@tonic-gate if (!xdr_string(xdrs, &objp->callback.cb_location.r_netid, 38237c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)) 38247c478bd9Sstevel@tonic-gate return (FALSE); 38257c478bd9Sstevel@tonic-gate if (!xdr_string(xdrs, &objp->callback.cb_location.r_addr, 38267c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)) 38277c478bd9Sstevel@tonic-gate return (FALSE); 38287c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->callback_ident)); 38297c478bd9Sstevel@tonic-gate } 38307c478bd9Sstevel@tonic-gate 38317c478bd9Sstevel@tonic-gate /* 38327c478bd9Sstevel@tonic-gate * Optimized free case 38337c478bd9Sstevel@tonic-gate */ 38347c478bd9Sstevel@tonic-gate if (objp->client.id_val != NULL) 38357c478bd9Sstevel@tonic-gate kmem_free(objp->client.id_val, objp->client.id_len); 38367c478bd9Sstevel@tonic-gate (void) xdr_string(xdrs, &objp->callback.cb_location.r_netid, 38377c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT); 38387c478bd9Sstevel@tonic-gate return (xdr_string(xdrs, &objp->callback.cb_location.r_addr, 38397c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)); 38407c478bd9Sstevel@tonic-gate } 38417c478bd9Sstevel@tonic-gate 38427c478bd9Sstevel@tonic-gate static bool_t 38437c478bd9Sstevel@tonic-gate xdr_SETCLIENTID4res(XDR *xdrs, SETCLIENTID4res *objp) 38447c478bd9Sstevel@tonic-gate { 38457c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 38467c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 38477c478bd9Sstevel@tonic-gate return (FALSE); 38487c478bd9Sstevel@tonic-gate switch (objp->status) { 38497c478bd9Sstevel@tonic-gate case NFS4_OK: 38507c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 38517c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->SETCLIENTID4res_u.resok4. 38527c478bd9Sstevel@tonic-gate clientid)) 38537c478bd9Sstevel@tonic-gate return (FALSE); 38547c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, 38557c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->SETCLIENTID4res_u. 38567c478bd9Sstevel@tonic-gate resok4.setclientid_confirm)); 38577c478bd9Sstevel@tonic-gate case NFS4ERR_CLID_INUSE: 38587c478bd9Sstevel@tonic-gate if (!xdr_string(xdrs, 38597c478bd9Sstevel@tonic-gate &objp->SETCLIENTID4res_u.client_using. 38607c478bd9Sstevel@tonic-gate r_netid, NFS4_OPAQUE_LIMIT)) 38617c478bd9Sstevel@tonic-gate return (FALSE); 38627c478bd9Sstevel@tonic-gate return (xdr_string(xdrs, 38637c478bd9Sstevel@tonic-gate &objp->SETCLIENTID4res_u.client_using. 38647c478bd9Sstevel@tonic-gate r_addr, NFS4_OPAQUE_LIMIT)); 38657c478bd9Sstevel@tonic-gate } 38667c478bd9Sstevel@tonic-gate return (TRUE); 38677c478bd9Sstevel@tonic-gate } 38687c478bd9Sstevel@tonic-gate 38697c478bd9Sstevel@tonic-gate /* 38707c478bd9Sstevel@tonic-gate * Optimized free case 38717c478bd9Sstevel@tonic-gate */ 38727c478bd9Sstevel@tonic-gate if (objp->status != NFS4ERR_CLID_INUSE) 38737c478bd9Sstevel@tonic-gate return (TRUE); 38747c478bd9Sstevel@tonic-gate 38757c478bd9Sstevel@tonic-gate if (!xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_netid, 38767c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)) 38777c478bd9Sstevel@tonic-gate return (FALSE); 38787c478bd9Sstevel@tonic-gate return (xdr_string(xdrs, &objp->SETCLIENTID4res_u.client_using.r_addr, 38797c478bd9Sstevel@tonic-gate NFS4_OPAQUE_LIMIT)); 38807c478bd9Sstevel@tonic-gate } 38817c478bd9Sstevel@tonic-gate 38827c478bd9Sstevel@tonic-gate static bool_t 38837c478bd9Sstevel@tonic-gate xdr_WRITE4args(XDR *xdrs, WRITE4args *objp) 38847c478bd9Sstevel@tonic-gate { 38857c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 38867c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->stateid.seqid)) 38877c478bd9Sstevel@tonic-gate return (FALSE); 3888bbe876c0SMarcel Telka if (!xdr_opaque(xdrs, objp->stateid.other, NFS4_OTHER_SIZE)) 38897c478bd9Sstevel@tonic-gate return (FALSE); 38907c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->offset)) 38917c478bd9Sstevel@tonic-gate return (FALSE); 38927c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->stable)) 38937c478bd9Sstevel@tonic-gate return (FALSE); 38947c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) { 38957c478bd9Sstevel@tonic-gate if (xdrs->x_ops == &xdrmblk_ops) { 38967c478bd9Sstevel@tonic-gate objp->data_val = NULL; 38977c478bd9Sstevel@tonic-gate return (xdrmblk_getmblk(xdrs, &objp->mblk, 38987c478bd9Sstevel@tonic-gate &objp->data_len)); 38997c478bd9Sstevel@tonic-gate } 39007c478bd9Sstevel@tonic-gate objp->mblk = NULL; 39010a701b1eSRobert Gordon if (xdrs->x_ops == &xdrrdmablk_ops) { 39020a701b1eSRobert Gordon int retval; 39030a701b1eSRobert Gordon retval = xdrrdma_getrdmablk(xdrs, 39040a701b1eSRobert Gordon &objp->rlist, 39050a701b1eSRobert Gordon &objp->data_len, 39060a701b1eSRobert Gordon &objp->conn, NFS4_DATA_LIMIT); 39070a701b1eSRobert Gordon if (retval == FALSE) 39080a701b1eSRobert Gordon return (FALSE); 3909f837ee4aSSiddheshwar Mahesh return (xdrrdma_read_from_client(objp->rlist, 39100a701b1eSRobert Gordon &objp->conn, objp->data_len)); 39117c478bd9Sstevel@tonic-gate } 39120a701b1eSRobert Gordon } 39130a701b1eSRobert Gordon /* Else fall thru for the xdr_bytes(). */ 39147c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->data_val, 39157c478bd9Sstevel@tonic-gate (uint_t *)&objp->data_len, NFS4_DATA_LIMIT)); 39167c478bd9Sstevel@tonic-gate } 39170a701b1eSRobert Gordon if (objp->rlist != NULL) { 39180a701b1eSRobert Gordon (void) xdrrdma_free_clist(objp->conn, objp->rlist); 39190a701b1eSRobert Gordon objp->rlist = NULL; 39200a701b1eSRobert Gordon objp->data_val = NULL; 39210a701b1eSRobert Gordon 39220a701b1eSRobert Gordon return (TRUE); 39230a701b1eSRobert Gordon } 39247c478bd9Sstevel@tonic-gate 39257c478bd9Sstevel@tonic-gate /* 39267c478bd9Sstevel@tonic-gate * Optimized free case 39277c478bd9Sstevel@tonic-gate */ 39287c478bd9Sstevel@tonic-gate if (objp->data_val != NULL) 39297c478bd9Sstevel@tonic-gate kmem_free(objp->data_val, objp->data_len); 39307c478bd9Sstevel@tonic-gate return (TRUE); 39317c478bd9Sstevel@tonic-gate } 39327c478bd9Sstevel@tonic-gate 39337c478bd9Sstevel@tonic-gate static bool_t 39347c478bd9Sstevel@tonic-gate xdr_WRITE4res(XDR *xdrs, WRITE4res *objp) 39357c478bd9Sstevel@tonic-gate { 39367c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 39377c478bd9Sstevel@tonic-gate return (FALSE); 39387c478bd9Sstevel@tonic-gate if (objp->status != NFS4_OK) 39397c478bd9Sstevel@tonic-gate return (TRUE); 39407c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->count)) 39417c478bd9Sstevel@tonic-gate return (FALSE); 39427c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->committed)) 39437c478bd9Sstevel@tonic-gate return (FALSE); 39447c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, 39457c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->writeverf)); 39467c478bd9Sstevel@tonic-gate } 39477c478bd9Sstevel@tonic-gate 39487c478bd9Sstevel@tonic-gate static bool_t 39497c46fb7fSek110237 xdr_snfs_argop4_free(XDR *xdrs, nfs_argop4 **arrayp, int len) 39507c478bd9Sstevel@tonic-gate { 39517c478bd9Sstevel@tonic-gate int i; 39527c478bd9Sstevel@tonic-gate nfs_argop4 *array = *arrayp; 39537c478bd9Sstevel@tonic-gate 39547c478bd9Sstevel@tonic-gate /* 39557c478bd9Sstevel@tonic-gate * Optimized XDR_FREE only args array 39567c478bd9Sstevel@tonic-gate */ 39577c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_FREE); 39587c478bd9Sstevel@tonic-gate 39597c478bd9Sstevel@tonic-gate /* 39607c478bd9Sstevel@tonic-gate * Nothing to do? 39617c478bd9Sstevel@tonic-gate */ 39627c478bd9Sstevel@tonic-gate if (array == NULL) 39637c478bd9Sstevel@tonic-gate return (TRUE); 39647c478bd9Sstevel@tonic-gate 39657c478bd9Sstevel@tonic-gate for (i = 0; i < len; i++) { 39667c478bd9Sstevel@tonic-gate /* 39677c478bd9Sstevel@tonic-gate * These should be ordered by frequency of use 39687c478bd9Sstevel@tonic-gate */ 39697c478bd9Sstevel@tonic-gate switch (array[i].argop) { 3970297b4d80SVitaliy Gusev case OP_PUTFH: { 3971297b4d80SVitaliy Gusev nfs_fh4 *objp = &array[i].nfs_argop4_u.opputfh.object; 3972297b4d80SVitaliy Gusev 3973297b4d80SVitaliy Gusev if (objp->nfs_fh4_val != NULL) { 3974297b4d80SVitaliy Gusev kmem_free(objp->nfs_fh4_val, objp->nfs_fh4_len); 39757c478bd9Sstevel@tonic-gate } 39767c478bd9Sstevel@tonic-gate continue; 3977297b4d80SVitaliy Gusev } 39787c478bd9Sstevel@tonic-gate case OP_GETATTR: 39797c478bd9Sstevel@tonic-gate case OP_GETFH: 39807c478bd9Sstevel@tonic-gate continue; 39817c478bd9Sstevel@tonic-gate case OP_LOOKUP: 39827c478bd9Sstevel@tonic-gate if (array[i].nfs_argop4_u.oplookup.objname. 39837c478bd9Sstevel@tonic-gate utf8string_val != NULL) { 39847c478bd9Sstevel@tonic-gate kmem_free(array[i].nfs_argop4_u.oplookup. 39857c478bd9Sstevel@tonic-gate objname.utf8string_val, 39867c478bd9Sstevel@tonic-gate array[i].nfs_argop4_u.oplookup. 39877c478bd9Sstevel@tonic-gate objname.utf8string_len); 39887c478bd9Sstevel@tonic-gate } 39897c478bd9Sstevel@tonic-gate continue; 39907c478bd9Sstevel@tonic-gate case OP_OPEN: 39917c478bd9Sstevel@tonic-gate (void) xdr_OPEN4args(xdrs, 39927c478bd9Sstevel@tonic-gate &array[i].nfs_argop4_u.opopen); 39937c478bd9Sstevel@tonic-gate continue; 39947c478bd9Sstevel@tonic-gate case OP_CLOSE: 39957c478bd9Sstevel@tonic-gate case OP_ACCESS: 39967c478bd9Sstevel@tonic-gate case OP_READ: 39977c478bd9Sstevel@tonic-gate continue; 39987c478bd9Sstevel@tonic-gate case OP_WRITE: 39997c478bd9Sstevel@tonic-gate (void) xdr_WRITE4args(xdrs, 40007c478bd9Sstevel@tonic-gate &array[i].nfs_argop4_u.opwrite); 40017c478bd9Sstevel@tonic-gate continue; 40027c478bd9Sstevel@tonic-gate case OP_DELEGRETURN: 40037c478bd9Sstevel@tonic-gate case OP_LOOKUPP: 40047c478bd9Sstevel@tonic-gate case OP_READDIR: 40057c478bd9Sstevel@tonic-gate continue; 40067c478bd9Sstevel@tonic-gate case OP_REMOVE: 40077c478bd9Sstevel@tonic-gate if (array[i].nfs_argop4_u.opremove.target. 40087c478bd9Sstevel@tonic-gate utf8string_val != NULL) { 40097c478bd9Sstevel@tonic-gate kmem_free(array[i].nfs_argop4_u.opremove.target. 40107c478bd9Sstevel@tonic-gate utf8string_val, 40117c478bd9Sstevel@tonic-gate array[i].nfs_argop4_u.opremove.target. 40127c478bd9Sstevel@tonic-gate utf8string_len); 40137c478bd9Sstevel@tonic-gate } 40147c478bd9Sstevel@tonic-gate continue; 40157c478bd9Sstevel@tonic-gate case OP_COMMIT: 40167c478bd9Sstevel@tonic-gate continue; 40177c478bd9Sstevel@tonic-gate case OP_CREATE: 40187c478bd9Sstevel@tonic-gate (void) xdr_CREATE4args(xdrs, 40197c478bd9Sstevel@tonic-gate &array[i].nfs_argop4_u.opcreate); 40207c478bd9Sstevel@tonic-gate continue; 40217c478bd9Sstevel@tonic-gate case OP_DELEGPURGE: 40227c478bd9Sstevel@tonic-gate continue; 40237c478bd9Sstevel@tonic-gate case OP_LINK: 40247c478bd9Sstevel@tonic-gate if (array[i].nfs_argop4_u.oplink.newname. 40257c478bd9Sstevel@tonic-gate utf8string_val != NULL) { 40267c478bd9Sstevel@tonic-gate kmem_free(array[i].nfs_argop4_u.oplink.newname. 40277c478bd9Sstevel@tonic-gate utf8string_val, 40287c478bd9Sstevel@tonic-gate array[i].nfs_argop4_u.oplink.newname. 40297c478bd9Sstevel@tonic-gate utf8string_len); 40307c478bd9Sstevel@tonic-gate } 40317c478bd9Sstevel@tonic-gate continue; 40327c478bd9Sstevel@tonic-gate case OP_LOCK: 40337c478bd9Sstevel@tonic-gate (void) xdr_LOCK4args(xdrs, 40347c478bd9Sstevel@tonic-gate &array[i].nfs_argop4_u.oplock); 40357c478bd9Sstevel@tonic-gate continue; 40367c478bd9Sstevel@tonic-gate case OP_LOCKT: 40377c478bd9Sstevel@tonic-gate (void) xdr_LOCKT4args(xdrs, 40387c478bd9Sstevel@tonic-gate &array[i].nfs_argop4_u.oplockt); 40397c478bd9Sstevel@tonic-gate continue; 40407c478bd9Sstevel@tonic-gate case OP_LOCKU: 40417c478bd9Sstevel@tonic-gate continue; 40427c478bd9Sstevel@tonic-gate case OP_NVERIFY: 40437c478bd9Sstevel@tonic-gate (void) xdr_fattr4(xdrs, 40447c478bd9Sstevel@tonic-gate &array[i].nfs_argop4_u.opnverify.obj_attributes); 40457c478bd9Sstevel@tonic-gate continue; 40467c478bd9Sstevel@tonic-gate case OP_OPENATTR: 40477c478bd9Sstevel@tonic-gate case OP_OPEN_CONFIRM: 40487c478bd9Sstevel@tonic-gate case OP_OPEN_DOWNGRADE: 40497c478bd9Sstevel@tonic-gate case OP_PUTPUBFH: 40507c478bd9Sstevel@tonic-gate case OP_PUTROOTFH: 40517c478bd9Sstevel@tonic-gate case OP_READLINK: 40527c478bd9Sstevel@tonic-gate continue; 40537c478bd9Sstevel@tonic-gate case OP_RENAME: 40547c478bd9Sstevel@tonic-gate if (array[i].nfs_argop4_u.oprename.oldname. 40557c478bd9Sstevel@tonic-gate utf8string_val != NULL) { 40567c478bd9Sstevel@tonic-gate kmem_free(array[i].nfs_argop4_u.oprename. 40577c478bd9Sstevel@tonic-gate oldname.utf8string_val, 40587c478bd9Sstevel@tonic-gate array[i].nfs_argop4_u.oprename. 40597c478bd9Sstevel@tonic-gate oldname.utf8string_len); 40607c478bd9Sstevel@tonic-gate } 40617c478bd9Sstevel@tonic-gate if (array[i].nfs_argop4_u.oprename.newname. 40627c478bd9Sstevel@tonic-gate utf8string_val != NULL) { 40637c478bd9Sstevel@tonic-gate kmem_free(array[i].nfs_argop4_u.oprename. 40647c478bd9Sstevel@tonic-gate newname.utf8string_val, 40657c478bd9Sstevel@tonic-gate array[i].nfs_argop4_u.oprename. 40667c478bd9Sstevel@tonic-gate newname.utf8string_len); 40677c478bd9Sstevel@tonic-gate } 40687c478bd9Sstevel@tonic-gate continue; 40697c478bd9Sstevel@tonic-gate case OP_RENEW: 40707c478bd9Sstevel@tonic-gate case OP_RESTOREFH: 40717c478bd9Sstevel@tonic-gate case OP_SAVEFH: 40727c478bd9Sstevel@tonic-gate continue; 40737c478bd9Sstevel@tonic-gate case OP_SECINFO: 40747c478bd9Sstevel@tonic-gate if (array[i].nfs_argop4_u.opsecinfo.name. 40757c478bd9Sstevel@tonic-gate utf8string_val != NULL) { 40767c478bd9Sstevel@tonic-gate kmem_free(array[i].nfs_argop4_u.opsecinfo.name. 40777c478bd9Sstevel@tonic-gate utf8string_val, 40787c478bd9Sstevel@tonic-gate array[i].nfs_argop4_u.opsecinfo.name. 40797c478bd9Sstevel@tonic-gate utf8string_len); 40807c478bd9Sstevel@tonic-gate } 40817c478bd9Sstevel@tonic-gate continue; 40827c478bd9Sstevel@tonic-gate case OP_SETATTR: 40837c478bd9Sstevel@tonic-gate (void) xdr_fattr4(xdrs, 40847c478bd9Sstevel@tonic-gate &array[i].nfs_argop4_u.opsetattr.obj_attributes); 40857c478bd9Sstevel@tonic-gate continue; 40867c478bd9Sstevel@tonic-gate case OP_SETCLIENTID: 40877c478bd9Sstevel@tonic-gate (void) xdr_SETCLIENTID4args(xdrs, 40887c478bd9Sstevel@tonic-gate &array[i].nfs_argop4_u.opsetclientid); 40897c478bd9Sstevel@tonic-gate continue; 40907c478bd9Sstevel@tonic-gate case OP_SETCLIENTID_CONFIRM: 40917c478bd9Sstevel@tonic-gate continue; 40927c478bd9Sstevel@tonic-gate case OP_VERIFY: 40937c478bd9Sstevel@tonic-gate (void) xdr_fattr4(xdrs, 40947c478bd9Sstevel@tonic-gate &array[i].nfs_argop4_u.opverify.obj_attributes); 40957c478bd9Sstevel@tonic-gate continue; 40967c478bd9Sstevel@tonic-gate case OP_RELEASE_LOCKOWNER: 40977c478bd9Sstevel@tonic-gate if (array[i].nfs_argop4_u.oprelease_lockowner. 40987c478bd9Sstevel@tonic-gate lock_owner.owner_val != NULL) { 40997c478bd9Sstevel@tonic-gate kmem_free(array[i].nfs_argop4_u. 41007c478bd9Sstevel@tonic-gate oprelease_lockowner.lock_owner.owner_val, 41017c478bd9Sstevel@tonic-gate array[i].nfs_argop4_u. 41027c478bd9Sstevel@tonic-gate oprelease_lockowner.lock_owner.owner_len); 41037c478bd9Sstevel@tonic-gate } 41047c478bd9Sstevel@tonic-gate continue; 41057c478bd9Sstevel@tonic-gate case OP_ILLEGAL: 41067c478bd9Sstevel@tonic-gate continue; 41077c478bd9Sstevel@tonic-gate default: 41087c478bd9Sstevel@tonic-gate /* 41097c478bd9Sstevel@tonic-gate * An invalid op is a coding error, it should never 41107c478bd9Sstevel@tonic-gate * have been decoded. 41117c478bd9Sstevel@tonic-gate * Don't error because the caller cannot finish 41127c478bd9Sstevel@tonic-gate * freeing the residual memory of the array. 41137c478bd9Sstevel@tonic-gate */ 41147c478bd9Sstevel@tonic-gate continue; 41157c478bd9Sstevel@tonic-gate } 41167c478bd9Sstevel@tonic-gate } 41177c478bd9Sstevel@tonic-gate 41187c478bd9Sstevel@tonic-gate kmem_free(*arrayp, len * sizeof (nfs_argop4)); 41197c478bd9Sstevel@tonic-gate *arrayp = NULL; 41207c478bd9Sstevel@tonic-gate return (TRUE); 41217c478bd9Sstevel@tonic-gate } 41227c478bd9Sstevel@tonic-gate 41237c478bd9Sstevel@tonic-gate static bool_t 41247c478bd9Sstevel@tonic-gate xdr_nfs_argop4(XDR *xdrs, nfs_argop4 *objp) 41257c478bd9Sstevel@tonic-gate { 41260a701b1eSRobert Gordon rdma_chunkinfo_t rci; 41270a701b1eSRobert Gordon struct xdr_ops *xops = xdrrdma_xops(); 41280a701b1eSRobert Gordon 41297c478bd9Sstevel@tonic-gate /* 41307c478bd9Sstevel@tonic-gate * These should be ordered by frequency of use 41317c478bd9Sstevel@tonic-gate */ 41327c478bd9Sstevel@tonic-gate switch (objp->argop) { 41337c478bd9Sstevel@tonic-gate case OP_PUTFH: 41347c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, 41357c478bd9Sstevel@tonic-gate (char **)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_val, 41367c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_argop4_u.opputfh.object.nfs_fh4_len, 41377c478bd9Sstevel@tonic-gate NFS4_FHSIZE)); 41387c478bd9Sstevel@tonic-gate case OP_GETATTR: 41398ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States /* 41408ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States * ACLs can become relatively large ( > 8K) and the default 41418ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States * 8K reply chunk of RDMA may not suffice. Check for 41428ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States * get ACL bit and if it's RDMA, add a chunk equal the size 41438ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States * of the transfer size to the reply chunk list. 41448ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States */ 41458ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) && 41468ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States (xdrs->x_op == XDR_ENCODE) && 41478ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States (objp->nfs_argop4_u.opgetattr.attr_request & 41488ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States FATTR4_ACL_MASK)) { 41498ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States rci.rci_type = RCI_REPLY_CHUNK; 41508ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States rci.rci_len = objp->nfs_argop4_u.opgetattr.mi->mi_tsize; 41518ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci); 41528ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States 41538ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States DTRACE_PROBE1(xdr__i__argop4__getattr, int, 41548ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States rci.rci_len); 41558ca9c6bbSFaramarz Jalalian - Sun Microsystems - Irvine United States } 41567c478bd9Sstevel@tonic-gate return (xdr_bitmap4(xdrs, 41577c478bd9Sstevel@tonic-gate &objp->nfs_argop4_u.opgetattr.attr_request)); 41587c478bd9Sstevel@tonic-gate case OP_GETFH: 41597c478bd9Sstevel@tonic-gate return (TRUE); 41607c478bd9Sstevel@tonic-gate case OP_LOOKUP: 41617c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oplookup. 41627c478bd9Sstevel@tonic-gate objname.utf8string_val, 41637c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_argop4_u.oplookup. 41647c478bd9Sstevel@tonic-gate objname.utf8string_len, 41657c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 41667c478bd9Sstevel@tonic-gate case OP_OPEN: 41677c478bd9Sstevel@tonic-gate return (xdr_OPEN4args(xdrs, &objp->nfs_argop4_u.opopen)); 41687c478bd9Sstevel@tonic-gate case OP_CLOSE: 41697c478bd9Sstevel@tonic-gate return (xdr_CLOSE4args(xdrs, &objp->nfs_argop4_u.opclose)); 41707c478bd9Sstevel@tonic-gate case OP_ACCESS: 41717c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, 41727c478bd9Sstevel@tonic-gate &objp->nfs_argop4_u.opaccess.access)); 41737c478bd9Sstevel@tonic-gate case OP_READ: 41747c478bd9Sstevel@tonic-gate return (xdr_READ4args(xdrs, &objp->nfs_argop4_u.opread)); 41757c478bd9Sstevel@tonic-gate case OP_WRITE: 41767c478bd9Sstevel@tonic-gate return (xdr_WRITE4args(xdrs, &objp->nfs_argop4_u.opwrite)); 41777c478bd9Sstevel@tonic-gate case OP_DELEGRETURN: 41787c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, 41797c478bd9Sstevel@tonic-gate &objp->nfs_argop4_u.opdelegreturn.deleg_stateid.seqid)) 41807c478bd9Sstevel@tonic-gate return (FALSE); 41817c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 4182bbe876c0SMarcel Telka objp->nfs_argop4_u.opdelegreturn.deleg_stateid.other, 4183bbe876c0SMarcel Telka NFS4_OTHER_SIZE)); 41847c478bd9Sstevel@tonic-gate case OP_LOOKUPP: 41857c478bd9Sstevel@tonic-gate return (TRUE); 41867c478bd9Sstevel@tonic-gate case OP_READDIR: 41877c478bd9Sstevel@tonic-gate return (xdr_READDIR4args(xdrs, &objp->nfs_argop4_u.opreaddir)); 41887c478bd9Sstevel@tonic-gate case OP_REMOVE: 41897c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.opremove. 41907c478bd9Sstevel@tonic-gate target.utf8string_val, 41917c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_argop4_u.opremove. 41927c478bd9Sstevel@tonic-gate target.utf8string_len, 41937c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 41947c478bd9Sstevel@tonic-gate case OP_COMMIT: 41957c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 41967c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->nfs_argop4_u.opcommit.offset)) 41977c478bd9Sstevel@tonic-gate return (FALSE); 41987c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opcommit.count)); 41997c478bd9Sstevel@tonic-gate case OP_CREATE: 42007c478bd9Sstevel@tonic-gate return (xdr_CREATE4args(xdrs, &objp->nfs_argop4_u.opcreate)); 42017c478bd9Sstevel@tonic-gate case OP_DELEGPURGE: 42027c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, 42037c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->nfs_argop4_u.opdelegpurge.clientid)); 42047c478bd9Sstevel@tonic-gate case OP_LINK: 42057c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, 42067c478bd9Sstevel@tonic-gate (char **)&objp->nfs_argop4_u.oplink.newname.utf8string_val, 42077c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_argop4_u.oplink.newname.utf8string_len, 42087c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 42097c478bd9Sstevel@tonic-gate case OP_LOCK: 42107c478bd9Sstevel@tonic-gate return (xdr_LOCK4args(xdrs, &objp->nfs_argop4_u.oplock)); 42117c478bd9Sstevel@tonic-gate case OP_LOCKT: 42127c478bd9Sstevel@tonic-gate return (xdr_LOCKT4args(xdrs, &objp->nfs_argop4_u.oplockt)); 42137c478bd9Sstevel@tonic-gate case OP_LOCKU: 42147c478bd9Sstevel@tonic-gate return (xdr_LOCKU4args(xdrs, &objp->nfs_argop4_u.oplocku)); 42157c478bd9Sstevel@tonic-gate case OP_NVERIFY: 42167c478bd9Sstevel@tonic-gate return (xdr_fattr4(xdrs, 42177c478bd9Sstevel@tonic-gate &objp->nfs_argop4_u.opnverify.obj_attributes)); 42187c478bd9Sstevel@tonic-gate case OP_OPENATTR: 42197c478bd9Sstevel@tonic-gate return (xdr_bool(xdrs, 42207c478bd9Sstevel@tonic-gate &objp->nfs_argop4_u.opopenattr.createdir)); 42217c478bd9Sstevel@tonic-gate case OP_OPEN_CONFIRM: 42227c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm. 42237c478bd9Sstevel@tonic-gate open_stateid.seqid)) 42247c478bd9Sstevel@tonic-gate return (FALSE); 42257c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opopen_confirm. 4226bbe876c0SMarcel Telka open_stateid.other, NFS4_OTHER_SIZE)) 42277c478bd9Sstevel@tonic-gate return (FALSE); 42287c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->nfs_argop4_u.opopen_confirm. 42297c478bd9Sstevel@tonic-gate seqid)); 42307c478bd9Sstevel@tonic-gate case OP_OPEN_DOWNGRADE: 42317c478bd9Sstevel@tonic-gate return (xdr_OPEN_DOWNGRADE4args(xdrs, 42327c478bd9Sstevel@tonic-gate &objp->nfs_argop4_u.opopen_downgrade)); 42337c478bd9Sstevel@tonic-gate case OP_PUTPUBFH: 42347c478bd9Sstevel@tonic-gate return (TRUE); 42357c478bd9Sstevel@tonic-gate case OP_PUTROOTFH: 42367c478bd9Sstevel@tonic-gate return (TRUE); 42377c478bd9Sstevel@tonic-gate case OP_READLINK: 42380a701b1eSRobert Gordon if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) && 42390a701b1eSRobert Gordon xdrs->x_op == XDR_ENCODE) { 42400a701b1eSRobert Gordon rci.rci_type = RCI_REPLY_CHUNK; 42410a701b1eSRobert Gordon rci.rci_len = MAXPATHLEN; 42420a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci); 42430a701b1eSRobert Gordon } 42447c478bd9Sstevel@tonic-gate return (TRUE); 42457c478bd9Sstevel@tonic-gate case OP_RENAME: 42467c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename. 42477c478bd9Sstevel@tonic-gate oldname.utf8string_val, 42487c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_argop4_u.oprename. 42497c478bd9Sstevel@tonic-gate oldname.utf8string_len, 42507c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)) 42517c478bd9Sstevel@tonic-gate return (FALSE); 42527c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->nfs_argop4_u.oprename. 42537c478bd9Sstevel@tonic-gate newname.utf8string_val, 42547c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_argop4_u.oprename. 42557c478bd9Sstevel@tonic-gate newname.utf8string_len, 42567c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 42577c478bd9Sstevel@tonic-gate case OP_RENEW: 42587c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, 42597c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->nfs_argop4_u.oprenew.clientid)); 42607c478bd9Sstevel@tonic-gate case OP_RESTOREFH: 42617c478bd9Sstevel@tonic-gate return (TRUE); 42627c478bd9Sstevel@tonic-gate case OP_SAVEFH: 42637c478bd9Sstevel@tonic-gate return (TRUE); 42647c478bd9Sstevel@tonic-gate case OP_SECINFO: 42657c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, 42667c478bd9Sstevel@tonic-gate (char **)&objp->nfs_argop4_u.opsecinfo.name.utf8string_val, 42677c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_argop4_u.opsecinfo.name.utf8string_len, 42687c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)); 42697c478bd9Sstevel@tonic-gate case OP_SETATTR: 42707c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->nfs_argop4_u.opsetattr. 42717c478bd9Sstevel@tonic-gate stateid.seqid)) 42727c478bd9Sstevel@tonic-gate return (FALSE); 42737c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->nfs_argop4_u.opsetattr. 4274bbe876c0SMarcel Telka stateid.other, NFS4_OTHER_SIZE)) 42757c478bd9Sstevel@tonic-gate return (FALSE); 42767c478bd9Sstevel@tonic-gate return (xdr_fattr4(xdrs, &objp->nfs_argop4_u.opsetattr. 42777c478bd9Sstevel@tonic-gate obj_attributes)); 42787c478bd9Sstevel@tonic-gate case OP_SETCLIENTID: 42797c478bd9Sstevel@tonic-gate return (xdr_SETCLIENTID4args(xdrs, 42807c478bd9Sstevel@tonic-gate &objp->nfs_argop4_u.opsetclientid)); 42817c478bd9Sstevel@tonic-gate case OP_SETCLIENTID_CONFIRM: 42827c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->nfs_argop4_u. 42837c478bd9Sstevel@tonic-gate opsetclientid_confirm.clientid)) 42847c478bd9Sstevel@tonic-gate return (FALSE); 42857c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, 42867c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->nfs_argop4_u. 42877c478bd9Sstevel@tonic-gate opsetclientid_confirm.setclientid_confirm)); 42887c478bd9Sstevel@tonic-gate case OP_VERIFY: 42897c478bd9Sstevel@tonic-gate return (xdr_fattr4(xdrs, 42907c478bd9Sstevel@tonic-gate &objp->nfs_argop4_u.opverify.obj_attributes)); 42917c478bd9Sstevel@tonic-gate case OP_RELEASE_LOCKOWNER: 42927c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, 42937c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->nfs_argop4_u. 42947c478bd9Sstevel@tonic-gate oprelease_lockowner.lock_owner.clientid)) 42957c478bd9Sstevel@tonic-gate return (FALSE); 42967c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, 42977c478bd9Sstevel@tonic-gate (char **)&objp->nfs_argop4_u.oprelease_lockowner. 42987c478bd9Sstevel@tonic-gate lock_owner.owner_val, 42997c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_argop4_u.oprelease_lockowner. 43007c478bd9Sstevel@tonic-gate lock_owner.owner_len, NFS4_OPAQUE_LIMIT)); 43017c478bd9Sstevel@tonic-gate case OP_ILLEGAL: 43027c478bd9Sstevel@tonic-gate return (TRUE); 43037c478bd9Sstevel@tonic-gate } 43047c478bd9Sstevel@tonic-gate return (FALSE); 43057c478bd9Sstevel@tonic-gate } 43067c478bd9Sstevel@tonic-gate 43077c46fb7fSek110237 static bool_t 43087c46fb7fSek110237 xdr_cnfs_argop4_wrap(XDR *xdrs, nfs_argop4 *objp) 43097c46fb7fSek110237 { 43107c46fb7fSek110237 if (!xdr_int(xdrs, (int *)&objp->argop)) 43117c46fb7fSek110237 return (FALSE); 43127c46fb7fSek110237 43137c46fb7fSek110237 return (xdr_nfs_argop4(xdrs, objp)); 43147c46fb7fSek110237 } 43157c46fb7fSek110237 43167c46fb7fSek110237 static bool_t 43177c46fb7fSek110237 xdr_snfs_argop4(XDR *xdrs, nfs_argop4 *objp) 43187c46fb7fSek110237 { 43197c46fb7fSek110237 if (!xdr_int(xdrs, (int *)&objp->argop)) 43207c46fb7fSek110237 return (FALSE); 43217c46fb7fSek110237 43227c46fb7fSek110237 switch (objp->argop) { 43237c46fb7fSek110237 case OP_PUTFH: 4324*c93d332cSDan McDonald return (xdr_decode_nfs_fh4(xdrs, 4325*c93d332cSDan McDonald &objp->nfs_argop4_u.opputfh.object)); 43267c46fb7fSek110237 default: 4327*c93d332cSDan McDonald return (xdr_nfs_argop4(xdrs, objp)); 43287c46fb7fSek110237 } 43297c46fb7fSek110237 } 43307c46fb7fSek110237 43317c478bd9Sstevel@tonic-gate /* 43327c478bd9Sstevel@tonic-gate * Client side encode only arg op processing 43337c478bd9Sstevel@tonic-gate */ 43347c478bd9Sstevel@tonic-gate static bool_t 43357c478bd9Sstevel@tonic-gate xdr_cnfs_argop4(XDR *xdrs, nfs_argop4 *objp) 43367c478bd9Sstevel@tonic-gate { 43377c478bd9Sstevel@tonic-gate int len; 43387c478bd9Sstevel@tonic-gate int op; 43397c478bd9Sstevel@tonic-gate nfs4_sharedfh_t *sfh; 43407c478bd9Sstevel@tonic-gate mntinfo4_t *mi; 43417c478bd9Sstevel@tonic-gate rpc_inline_t *ptr; 43427c478bd9Sstevel@tonic-gate 43437c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_ENCODE); 43447c478bd9Sstevel@tonic-gate 43457c478bd9Sstevel@tonic-gate /* 43467c478bd9Sstevel@tonic-gate * Special case the private pseudo ops 43477c478bd9Sstevel@tonic-gate */ 43487c478bd9Sstevel@tonic-gate if (!(objp->argop & SUNW_PRIVATE_OP)) 43497c46fb7fSek110237 return (xdr_cnfs_argop4_wrap(xdrs, objp)); 43507c478bd9Sstevel@tonic-gate 43517c478bd9Sstevel@tonic-gate /* 43527c478bd9Sstevel@tonic-gate * These should be ordered by frequency of use 43537c478bd9Sstevel@tonic-gate */ 43547c478bd9Sstevel@tonic-gate switch (objp->argop) { 43557c478bd9Sstevel@tonic-gate case OP_CPUTFH: 43567c478bd9Sstevel@tonic-gate /* 43577c478bd9Sstevel@tonic-gate * We are passed in the file handle as a nfs4_sharedfh_t * 43587c478bd9Sstevel@tonic-gate * We need to acquire the correct locks so we can copy it out. 43597c478bd9Sstevel@tonic-gate */ 43607c478bd9Sstevel@tonic-gate sfh = (nfs4_sharedfh_t *)objp->nfs_argop4_u.opcputfh.sfh; 43617c478bd9Sstevel@tonic-gate mi = sfh->sfh_mi; 43627c478bd9Sstevel@tonic-gate (void) nfs_rw_enter_sig(&mi->mi_fh_lock, RW_READER, 0); 43637c478bd9Sstevel@tonic-gate 43647c478bd9Sstevel@tonic-gate len = sfh->sfh_fh.nfs_fh4_len; 43657c478bd9Sstevel@tonic-gate ASSERT(len <= NFS4_FHSIZE); 43667c478bd9Sstevel@tonic-gate 43677c478bd9Sstevel@tonic-gate /* 43687c478bd9Sstevel@tonic-gate * First try and inline the copy 43697c478bd9Sstevel@tonic-gate * Must first be a multiple of BYTES_PER_XDR_UNIT 43707c478bd9Sstevel@tonic-gate */ 43717c478bd9Sstevel@tonic-gate if (!(len % BYTES_PER_XDR_UNIT) && 43727c478bd9Sstevel@tonic-gate (ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT + len)) != 43737c478bd9Sstevel@tonic-gate NULL) { 43747c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, OP_PUTFH); 43757c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, len); 43767c478bd9Sstevel@tonic-gate bcopy(sfh->sfh_fh.nfs_fh4_val, ptr, len); 43777c478bd9Sstevel@tonic-gate nfs_rw_exit(&mi->mi_fh_lock); 43787c478bd9Sstevel@tonic-gate return (TRUE); 43797c478bd9Sstevel@tonic-gate } 43807c478bd9Sstevel@tonic-gate 43817c478bd9Sstevel@tonic-gate op = OP_PUTFH; 43827c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &op)) { 43837c478bd9Sstevel@tonic-gate nfs_rw_exit(&mi->mi_fh_lock); 43847c478bd9Sstevel@tonic-gate return (FALSE); 43857c478bd9Sstevel@tonic-gate } 43867c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &len)) { 43877c478bd9Sstevel@tonic-gate nfs_rw_exit(&mi->mi_fh_lock); 43887c478bd9Sstevel@tonic-gate return (FALSE); 43897c478bd9Sstevel@tonic-gate } 43907c478bd9Sstevel@tonic-gate if (!(len % BYTES_PER_XDR_UNIT)) { 43917c478bd9Sstevel@tonic-gate if (XDR_PUTBYTES(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) { 43927c478bd9Sstevel@tonic-gate nfs_rw_exit(&mi->mi_fh_lock); 43937c478bd9Sstevel@tonic-gate return (TRUE); 43947c478bd9Sstevel@tonic-gate } 43957c478bd9Sstevel@tonic-gate } else if (xdr_opaque(xdrs, sfh->sfh_fh.nfs_fh4_val, len)) { 43967c478bd9Sstevel@tonic-gate nfs_rw_exit(&mi->mi_fh_lock); 43977c478bd9Sstevel@tonic-gate return (TRUE); 43987c478bd9Sstevel@tonic-gate } 43997c478bd9Sstevel@tonic-gate nfs_rw_exit(&mi->mi_fh_lock); 44007c478bd9Sstevel@tonic-gate return (FALSE); 44017c478bd9Sstevel@tonic-gate case OP_CLOOKUP: 44027c478bd9Sstevel@tonic-gate len = strlen(objp->nfs_argop4_u.opclookup.cname); 44037c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 44047c478bd9Sstevel@tonic-gate return (FALSE); 44057c478bd9Sstevel@tonic-gate op = OP_LOOKUP; 44067c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &op)) { 44077c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &len)) { 44087c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 44097c478bd9Sstevel@tonic-gate objp->nfs_argop4_u.opclookup.cname, 44107c478bd9Sstevel@tonic-gate len)); 44117c478bd9Sstevel@tonic-gate } 44127c478bd9Sstevel@tonic-gate } 44137c478bd9Sstevel@tonic-gate return (FALSE); 44147c478bd9Sstevel@tonic-gate case OP_COPEN: 44157c478bd9Sstevel@tonic-gate /* op processing inlined in xdr_OPEN4cargs */ 44167c478bd9Sstevel@tonic-gate return (xdr_OPEN4cargs(xdrs, &objp->nfs_argop4_u.opcopen)); 44177c478bd9Sstevel@tonic-gate case OP_CREMOVE: 44187c478bd9Sstevel@tonic-gate len = strlen(objp->nfs_argop4_u.opcremove.ctarget); 44197c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 44207c478bd9Sstevel@tonic-gate return (FALSE); 44217c478bd9Sstevel@tonic-gate op = OP_REMOVE; 44227c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &op)) { 44237c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &len)) { 44247c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 44257c478bd9Sstevel@tonic-gate objp->nfs_argop4_u.opcremove.ctarget, 44267c478bd9Sstevel@tonic-gate len)); 44277c478bd9Sstevel@tonic-gate } 44287c478bd9Sstevel@tonic-gate } 44297c478bd9Sstevel@tonic-gate return (FALSE); 44307c478bd9Sstevel@tonic-gate case OP_CCREATE: 44317c478bd9Sstevel@tonic-gate op = OP_CREATE; 44327c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &op)) 44337c478bd9Sstevel@tonic-gate return (FALSE); 44347c478bd9Sstevel@tonic-gate return (xdr_CREATE4cargs(xdrs, &objp->nfs_argop4_u.opccreate)); 44357c478bd9Sstevel@tonic-gate case OP_CLINK: 44367c478bd9Sstevel@tonic-gate len = strlen(objp->nfs_argop4_u.opclink.cnewname); 44377c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 44387c478bd9Sstevel@tonic-gate return (FALSE); 44397c478bd9Sstevel@tonic-gate op = OP_LINK; 44407c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &op)) { 44417c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &len)) { 44427c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 44437c478bd9Sstevel@tonic-gate objp->nfs_argop4_u.opclink.cnewname, 44447c478bd9Sstevel@tonic-gate len)); 44457c478bd9Sstevel@tonic-gate } 44467c478bd9Sstevel@tonic-gate } 44477c478bd9Sstevel@tonic-gate return (FALSE); 44487c478bd9Sstevel@tonic-gate case OP_CRENAME: 44497c478bd9Sstevel@tonic-gate len = strlen(objp->nfs_argop4_u.opcrename.coldname); 44507c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 44517c478bd9Sstevel@tonic-gate return (FALSE); 44527c478bd9Sstevel@tonic-gate op = OP_RENAME; 44537c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &op)) 44547c478bd9Sstevel@tonic-gate return (FALSE); 44557c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &len)) 44567c478bd9Sstevel@tonic-gate return (FALSE); 44577c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, 44587c478bd9Sstevel@tonic-gate objp->nfs_argop4_u.opcrename.coldname, len)) 44597c478bd9Sstevel@tonic-gate return (FALSE); 44607c478bd9Sstevel@tonic-gate len = strlen(objp->nfs_argop4_u.opcrename.cnewname); 44617c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 44627c478bd9Sstevel@tonic-gate return (FALSE); 44637c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &len)) { 44647c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 44657c478bd9Sstevel@tonic-gate objp->nfs_argop4_u.opcrename.cnewname, len)); 44667c478bd9Sstevel@tonic-gate } 44677c478bd9Sstevel@tonic-gate return (FALSE); 44687c478bd9Sstevel@tonic-gate case OP_CSECINFO: 44697c478bd9Sstevel@tonic-gate len = strlen(objp->nfs_argop4_u.opcsecinfo.cname); 44707c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 44717c478bd9Sstevel@tonic-gate return (FALSE); 44727c478bd9Sstevel@tonic-gate op = OP_SECINFO; 44737c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &op)) { 44747c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, &len)) { 44757c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 44767c478bd9Sstevel@tonic-gate objp->nfs_argop4_u.opcsecinfo.cname, 44777c478bd9Sstevel@tonic-gate len)); 44787c478bd9Sstevel@tonic-gate } 44797c478bd9Sstevel@tonic-gate } 44807c478bd9Sstevel@tonic-gate return (FALSE); 44817c478bd9Sstevel@tonic-gate } 44827c478bd9Sstevel@tonic-gate return (FALSE); 44837c478bd9Sstevel@tonic-gate } 44847c478bd9Sstevel@tonic-gate 44857c478bd9Sstevel@tonic-gate /* 44867c478bd9Sstevel@tonic-gate * Note that the len and decode_len will only be different in the case 44877c478bd9Sstevel@tonic-gate * of the client's use of this free function. If the server is 44887c478bd9Sstevel@tonic-gate * freeing results, then the len/decode_len will always match. 44897c478bd9Sstevel@tonic-gate */ 44907c478bd9Sstevel@tonic-gate static bool_t 44917c478bd9Sstevel@tonic-gate xdr_nfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len) 44927c478bd9Sstevel@tonic-gate { 44937c478bd9Sstevel@tonic-gate int i; 44947c478bd9Sstevel@tonic-gate nfs_resop4 *array = *arrayp; 44952f172c55SRobert Thurlow nfs4_ga_res_t *gr; 44967c478bd9Sstevel@tonic-gate 44977c478bd9Sstevel@tonic-gate /* 44987c478bd9Sstevel@tonic-gate * Optimized XDR_FREE only results array 44997c478bd9Sstevel@tonic-gate */ 45007c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_FREE); 45017c478bd9Sstevel@tonic-gate 45027c478bd9Sstevel@tonic-gate if (array == NULL) 45037c478bd9Sstevel@tonic-gate return (TRUE); 45047c478bd9Sstevel@tonic-gate 45057c478bd9Sstevel@tonic-gate for (i = 0; i < decode_len; i++) { 45067c478bd9Sstevel@tonic-gate /* 45077c478bd9Sstevel@tonic-gate * These should be ordered by frequency of use 45087c478bd9Sstevel@tonic-gate */ 45097c478bd9Sstevel@tonic-gate switch (array[i].resop) { 45107c478bd9Sstevel@tonic-gate case OP_PUTFH: 45117c478bd9Sstevel@tonic-gate continue; 45127c478bd9Sstevel@tonic-gate case OP_GETATTR: 45137c478bd9Sstevel@tonic-gate if (array[i].nfs_resop4_u.opgetattr.status != NFS4_OK) 45147c478bd9Sstevel@tonic-gate continue; 45152f172c55SRobert Thurlow 45162f172c55SRobert Thurlow gr = &array[i].nfs_resop4_u.opgetattr.ga_res; 45172f172c55SRobert Thurlow if (gr->n4g_ext_res) { 45182f172c55SRobert Thurlow if (gr->n4g_resbmap & FATTR4_FS_LOCATIONS_MASK) 45192f172c55SRobert Thurlow (void) xdr_fattr4_fs_locations(xdrs, 45202f172c55SRobert Thurlow &gr->n4g_ext_res->n4g_fslocations); 45212f172c55SRobert Thurlow kmem_free(gr->n4g_ext_res, 45227c478bd9Sstevel@tonic-gate sizeof (struct nfs4_ga_ext_res)); 45232f172c55SRobert Thurlow } 45247c478bd9Sstevel@tonic-gate continue; 45257c478bd9Sstevel@tonic-gate case OP_GETFH: 45267c478bd9Sstevel@tonic-gate if (array[i].nfs_resop4_u.opgetfh.status != NFS4_OK) 45277c478bd9Sstevel@tonic-gate continue; 45287c478bd9Sstevel@tonic-gate if (array[i].nfs_resop4_u.opgetfh.object.nfs_fh4_val != 45297c478bd9Sstevel@tonic-gate NULL) { 45307c478bd9Sstevel@tonic-gate kmem_free(array[i].nfs_resop4_u.opgetfh.object. 45317c478bd9Sstevel@tonic-gate nfs_fh4_val, 45327c478bd9Sstevel@tonic-gate array[i].nfs_resop4_u.opgetfh.object. 45337c478bd9Sstevel@tonic-gate nfs_fh4_len); 45347c478bd9Sstevel@tonic-gate } 45357c478bd9Sstevel@tonic-gate continue; 45367c478bd9Sstevel@tonic-gate case OP_LOOKUP: 45377c478bd9Sstevel@tonic-gate continue; 45387c478bd9Sstevel@tonic-gate case OP_OPEN: 45397c478bd9Sstevel@tonic-gate (void) xdr_OPEN4res(xdrs, &array[i].nfs_resop4_u. 45407c478bd9Sstevel@tonic-gate opopen); 45417c478bd9Sstevel@tonic-gate continue; 45427c478bd9Sstevel@tonic-gate case OP_CLOSE: 45437c478bd9Sstevel@tonic-gate case OP_ACCESS: 45447c478bd9Sstevel@tonic-gate continue; 45457c478bd9Sstevel@tonic-gate case OP_READ: 45467c478bd9Sstevel@tonic-gate (void) xdr_READ4res(xdrs, 45470a701b1eSRobert Gordon &array[i].nfs_resop4_u.opread); 45487c478bd9Sstevel@tonic-gate continue; 45497c478bd9Sstevel@tonic-gate case OP_WRITE: 45507c478bd9Sstevel@tonic-gate case OP_DELEGRETURN: 45517c478bd9Sstevel@tonic-gate case OP_LOOKUPP: 45527c478bd9Sstevel@tonic-gate case OP_READDIR: 45537c478bd9Sstevel@tonic-gate case OP_REMOVE: 45547c478bd9Sstevel@tonic-gate case OP_COMMIT: 45557c478bd9Sstevel@tonic-gate case OP_CREATE: 45567c478bd9Sstevel@tonic-gate case OP_DELEGPURGE: 45577c478bd9Sstevel@tonic-gate case OP_LINK: 45587c478bd9Sstevel@tonic-gate continue; 45597c478bd9Sstevel@tonic-gate case OP_LOCK: 45607c478bd9Sstevel@tonic-gate (void) xdr_LOCK4res(xdrs, &array[i].nfs_resop4_u. 45617c478bd9Sstevel@tonic-gate oplock); 45627c478bd9Sstevel@tonic-gate continue; 45637c478bd9Sstevel@tonic-gate case OP_LOCKT: 45647c478bd9Sstevel@tonic-gate (void) xdr_LOCKT4res(xdrs, &array[i].nfs_resop4_u. 45657c478bd9Sstevel@tonic-gate oplockt); 45667c478bd9Sstevel@tonic-gate continue; 45677c478bd9Sstevel@tonic-gate case OP_LOCKU: 45687c478bd9Sstevel@tonic-gate case OP_NVERIFY: 45697c478bd9Sstevel@tonic-gate case OP_OPENATTR: 45707c478bd9Sstevel@tonic-gate case OP_OPEN_CONFIRM: 45717c478bd9Sstevel@tonic-gate case OP_OPEN_DOWNGRADE: 45727c478bd9Sstevel@tonic-gate case OP_PUTPUBFH: 45737c478bd9Sstevel@tonic-gate case OP_PUTROOTFH: 45747c478bd9Sstevel@tonic-gate case OP_RENAME: 45757c478bd9Sstevel@tonic-gate case OP_RENEW: 45767c478bd9Sstevel@tonic-gate case OP_RESTOREFH: 45777c478bd9Sstevel@tonic-gate case OP_SAVEFH: 45787c478bd9Sstevel@tonic-gate continue; 45797c478bd9Sstevel@tonic-gate case OP_READLINK: 45807c478bd9Sstevel@tonic-gate (void) xdr_READLINK4res(xdrs, &array[i].nfs_resop4_u. 45817c478bd9Sstevel@tonic-gate opreadlink); 45827c478bd9Sstevel@tonic-gate continue; 45837c478bd9Sstevel@tonic-gate case OP_SECINFO: 45847c478bd9Sstevel@tonic-gate (void) xdr_array(xdrs, 45857c478bd9Sstevel@tonic-gate (char **)&array[i].nfs_resop4_u.opsecinfo. 45867c478bd9Sstevel@tonic-gate SECINFO4resok_val, 45877c478bd9Sstevel@tonic-gate (uint_t *)&array[i].nfs_resop4_u.opsecinfo. 45887c478bd9Sstevel@tonic-gate SECINFO4resok_len, 45897c478bd9Sstevel@tonic-gate NFS4_SECINFO_LIMIT, sizeof (secinfo4), 45907c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_secinfo4); 45917c478bd9Sstevel@tonic-gate continue; 45927c478bd9Sstevel@tonic-gate case OP_SETCLIENTID: 45937c478bd9Sstevel@tonic-gate (void) xdr_SETCLIENTID4res(xdrs, 45947c478bd9Sstevel@tonic-gate &array[i].nfs_resop4_u.opsetclientid); 45957c478bd9Sstevel@tonic-gate continue; 45967c478bd9Sstevel@tonic-gate case OP_SETATTR: 45977c478bd9Sstevel@tonic-gate case OP_SETCLIENTID_CONFIRM: 45987c478bd9Sstevel@tonic-gate case OP_VERIFY: 45997c478bd9Sstevel@tonic-gate case OP_RELEASE_LOCKOWNER: 46007c478bd9Sstevel@tonic-gate case OP_ILLEGAL: 46017c478bd9Sstevel@tonic-gate continue; 46027c478bd9Sstevel@tonic-gate default: 46037c478bd9Sstevel@tonic-gate /* 46047c478bd9Sstevel@tonic-gate * An invalid op is a coding error, it should never 46057c478bd9Sstevel@tonic-gate * have been decoded. 46067c478bd9Sstevel@tonic-gate * Don't error because the caller cannot finish 46077c478bd9Sstevel@tonic-gate * freeing the residual memory of the array. 46087c478bd9Sstevel@tonic-gate */ 46097c478bd9Sstevel@tonic-gate continue; 46107c478bd9Sstevel@tonic-gate } 46117c478bd9Sstevel@tonic-gate } 46127c478bd9Sstevel@tonic-gate 46137c478bd9Sstevel@tonic-gate kmem_free(*arrayp, len * sizeof (nfs_resop4)); 46147c478bd9Sstevel@tonic-gate *arrayp = NULL; 46157c478bd9Sstevel@tonic-gate return (TRUE); 46167c478bd9Sstevel@tonic-gate } 46177c478bd9Sstevel@tonic-gate 46187c478bd9Sstevel@tonic-gate static bool_t 46197c46fb7fSek110237 xdr_snfs_resop4_free(XDR *xdrs, nfs_resop4 **arrayp, int len, int decode_len) 46207c46fb7fSek110237 { 46217c46fb7fSek110237 return (xdr_nfs_resop4_free(xdrs, arrayp, len, decode_len)); 46227c46fb7fSek110237 } 46237c46fb7fSek110237 46247c46fb7fSek110237 static bool_t 46257c478bd9Sstevel@tonic-gate xdr_nfs_resop4(XDR *xdrs, nfs_resop4 *objp) 46267c478bd9Sstevel@tonic-gate { 46277c478bd9Sstevel@tonic-gate /* 46287c478bd9Sstevel@tonic-gate * These should be ordered by frequency of use 46297c478bd9Sstevel@tonic-gate */ 46307c478bd9Sstevel@tonic-gate switch (objp->resop) { 46317c478bd9Sstevel@tonic-gate case OP_PUTFH: 46327c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 46337c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opputfh.status)); 46347c478bd9Sstevel@tonic-gate case OP_GETATTR: 46357c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 46367c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opgetattr.status)) 46377c478bd9Sstevel@tonic-gate return (FALSE); 46387c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK) 46397c478bd9Sstevel@tonic-gate return (TRUE); 46407c478bd9Sstevel@tonic-gate return (xdr_fattr4(xdrs, 46417c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opgetattr.obj_attributes)); 46427c478bd9Sstevel@tonic-gate case OP_GETFH: 46437c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 46447c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opgetfh.status)) 46457c478bd9Sstevel@tonic-gate return (FALSE); 46467c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK) 46477c478bd9Sstevel@tonic-gate return (TRUE); 46487c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, 46497c478bd9Sstevel@tonic-gate (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val, 46507c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len, 46517c478bd9Sstevel@tonic-gate NFS4_FHSIZE)); 46527c478bd9Sstevel@tonic-gate case OP_LOOKUP: 46537c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 46547c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oplookup.status)); 46557c478bd9Sstevel@tonic-gate case OP_OPEN: 46567c478bd9Sstevel@tonic-gate return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen)); 46577c478bd9Sstevel@tonic-gate case OP_CLOSE: 46587c478bd9Sstevel@tonic-gate return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose)); 46597c478bd9Sstevel@tonic-gate case OP_ACCESS: 46607c478bd9Sstevel@tonic-gate return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess)); 46617c478bd9Sstevel@tonic-gate case OP_READ: 46627c478bd9Sstevel@tonic-gate return (xdr_READ4res(xdrs, &objp->nfs_resop4_u.opread)); 46637c478bd9Sstevel@tonic-gate case OP_WRITE: 46647c478bd9Sstevel@tonic-gate return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite)); 46657c478bd9Sstevel@tonic-gate case OP_DELEGRETURN: 46667c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 46677c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status)); 46687c478bd9Sstevel@tonic-gate case OP_LOOKUPP: 46697c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 46707c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oplookupp.status)); 46717c478bd9Sstevel@tonic-gate case OP_READDIR: 46727c478bd9Sstevel@tonic-gate return (xdr_READDIR4res(xdrs, &objp->nfs_resop4_u.opreaddir)); 46737c478bd9Sstevel@tonic-gate case OP_REMOVE: 46747c478bd9Sstevel@tonic-gate return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove)); 46757c478bd9Sstevel@tonic-gate 46767c478bd9Sstevel@tonic-gate case OP_COMMIT: 46777c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 46787c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opcommit.status)) 46797c478bd9Sstevel@tonic-gate return (FALSE); 46807c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.opcommit.status != NFS4_OK) 46817c478bd9Sstevel@tonic-gate return (TRUE); 46827c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, 46837c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->nfs_resop4_u.opcommit. 46847c478bd9Sstevel@tonic-gate writeverf)); 46857c478bd9Sstevel@tonic-gate case OP_CREATE: 46867c478bd9Sstevel@tonic-gate return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate)); 46877c478bd9Sstevel@tonic-gate case OP_DELEGPURGE: 46887c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 46897c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status)); 46907c478bd9Sstevel@tonic-gate case OP_LINK: 46917c478bd9Sstevel@tonic-gate return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink)); 46927c478bd9Sstevel@tonic-gate case OP_LOCK: 46937c478bd9Sstevel@tonic-gate return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock)); 46947c478bd9Sstevel@tonic-gate case OP_LOCKT: 46957c478bd9Sstevel@tonic-gate return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt)); 46967c478bd9Sstevel@tonic-gate case OP_LOCKU: 46977c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 46987c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oplocku.status)) 46997c478bd9Sstevel@tonic-gate return (FALSE); 47007c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.oplocku.status != NFS4_OK) 47017c478bd9Sstevel@tonic-gate return (TRUE); 47027c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, 47037c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.oplocku.lock_stateid.seqid)) 47047c478bd9Sstevel@tonic-gate return (FALSE); 47057c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 47067c478bd9Sstevel@tonic-gate objp->nfs_resop4_u.oplocku.lock_stateid.other, 4707bbe876c0SMarcel Telka NFS4_OTHER_SIZE)); 47087c478bd9Sstevel@tonic-gate case OP_NVERIFY: 47097c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47107c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opnverify.status)); 47117c478bd9Sstevel@tonic-gate case OP_OPENATTR: 47127c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47137c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opopenattr.status)); 47147c478bd9Sstevel@tonic-gate case OP_OPEN_CONFIRM: 47157c478bd9Sstevel@tonic-gate return (xdr_OPEN_CONFIRM4res(xdrs, 47167c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opopen_confirm)); 47177c478bd9Sstevel@tonic-gate case OP_OPEN_DOWNGRADE: 47187c478bd9Sstevel@tonic-gate return (xdr_OPEN_DOWNGRADE4res(xdrs, 47197c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opopen_downgrade)); 47207c478bd9Sstevel@tonic-gate case OP_PUTPUBFH: 47217c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47227c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opputpubfh.status)); 47237c478bd9Sstevel@tonic-gate case OP_PUTROOTFH: 47247c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47257c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opputrootfh.status)); 47267c478bd9Sstevel@tonic-gate case OP_READLINK: 47277c478bd9Sstevel@tonic-gate return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink)); 47287c478bd9Sstevel@tonic-gate case OP_RENAME: 47297c478bd9Sstevel@tonic-gate return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename)); 47307c478bd9Sstevel@tonic-gate case OP_RENEW: 47317c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47327c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oprenew.status)); 47337c478bd9Sstevel@tonic-gate case OP_RESTOREFH: 47347c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47357c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oprestorefh.status)); 47367c478bd9Sstevel@tonic-gate case OP_SAVEFH: 47377c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47387c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opsavefh.status)); 47397c478bd9Sstevel@tonic-gate case OP_SECINFO: 47407c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo. 47417c478bd9Sstevel@tonic-gate status)) 47427c478bd9Sstevel@tonic-gate return (FALSE); 47437c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK) 47447c478bd9Sstevel@tonic-gate return (TRUE); 47457c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo. 47467c478bd9Sstevel@tonic-gate SECINFO4resok_val, 47477c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_resop4_u.opsecinfo. 47487c478bd9Sstevel@tonic-gate SECINFO4resok_len, 47497c478bd9Sstevel@tonic-gate NFS4_SECINFO_LIMIT, sizeof (secinfo4), 47507c478bd9Sstevel@tonic-gate (xdrproc_t)xdr_secinfo4)); 47517c478bd9Sstevel@tonic-gate case OP_SETATTR: 47527c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr. 47537c478bd9Sstevel@tonic-gate status)) 47547c478bd9Sstevel@tonic-gate return (FALSE); 47557c478bd9Sstevel@tonic-gate return (xdr_bitmap4(xdrs, 47567c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opsetattr.attrsset)); 47577c478bd9Sstevel@tonic-gate case OP_SETCLIENTID: 47587c478bd9Sstevel@tonic-gate return (xdr_SETCLIENTID4res(xdrs, 47597c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opsetclientid)); 47607c478bd9Sstevel@tonic-gate case OP_SETCLIENTID_CONFIRM: 47617c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47627c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm. 47637c478bd9Sstevel@tonic-gate status)); 47647c478bd9Sstevel@tonic-gate case OP_VERIFY: 47657c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47667c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opverify.status)); 47677c478bd9Sstevel@tonic-gate case OP_RELEASE_LOCKOWNER: 47687c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47697c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status)); 47707c478bd9Sstevel@tonic-gate case OP_ILLEGAL: 47717c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 47727c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opillegal.status)); 47737c478bd9Sstevel@tonic-gate } 47747c478bd9Sstevel@tonic-gate return (FALSE); 47757c478bd9Sstevel@tonic-gate } 47767c478bd9Sstevel@tonic-gate 47777c478bd9Sstevel@tonic-gate static bool_t 47787c46fb7fSek110237 xdr_snfs_resop4(XDR *xdrs, nfs_resop4 *objp) 47797c46fb7fSek110237 { 47807c46fb7fSek110237 if (!xdr_int(xdrs, (int *)&objp->resop)) 47817c46fb7fSek110237 return (FALSE); 47827c46fb7fSek110237 47837c46fb7fSek110237 switch (objp->resop) { 47847c46fb7fSek110237 case OP_GETFH: 47857c46fb7fSek110237 if (!XDR_PUTINT32(xdrs, 47867c46fb7fSek110237 (int32_t *)&objp->nfs_resop4_u.opgetfh.status)) 47877c46fb7fSek110237 return (FALSE); 47887c46fb7fSek110237 if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK) 4789*c93d332cSDan McDonald return (TRUE); 4790*c93d332cSDan McDonald return (xdr_encode_nfs_fh4(xdrs, 4791*c93d332cSDan McDonald &objp->nfs_resop4_u.opgetfh.object)); 47927c46fb7fSek110237 default: 4793*c93d332cSDan McDonald return (xdr_nfs_resop4(xdrs, objp)); 47947c46fb7fSek110237 } 47957c46fb7fSek110237 } 47967c46fb7fSek110237 47977c46fb7fSek110237 static bool_t 47987c478bd9Sstevel@tonic-gate xdr_nfs_resop4_clnt(XDR *xdrs, nfs_resop4 *objp, nfs_argop4 *aobjp) 47997c478bd9Sstevel@tonic-gate { 48007c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int *)&objp->resop)) 48017c478bd9Sstevel@tonic-gate return (FALSE); 48027c478bd9Sstevel@tonic-gate /* 48037c478bd9Sstevel@tonic-gate * These should be ordered by frequency of use 48047c478bd9Sstevel@tonic-gate */ 48057c478bd9Sstevel@tonic-gate switch (objp->resop) { 48067c478bd9Sstevel@tonic-gate case OP_PUTFH: 48077c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 48087c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opputfh.status)); 48097c478bd9Sstevel@tonic-gate case OP_GETATTR: 48107c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 48117c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opgetattr.status)) 48127c478bd9Sstevel@tonic-gate return (FALSE); 48137c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.opgetattr.status != NFS4_OK) 48147c478bd9Sstevel@tonic-gate return (TRUE); 48157c478bd9Sstevel@tonic-gate return (xdr_ga_res(xdrs, 48167c478bd9Sstevel@tonic-gate (GETATTR4res *)&objp->nfs_resop4_u.opgetattr, 48177c478bd9Sstevel@tonic-gate &aobjp->nfs_argop4_u.opgetattr)); 48187c478bd9Sstevel@tonic-gate case OP_GETFH: 48197c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 48207c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opgetfh.status)) 48217c478bd9Sstevel@tonic-gate return (FALSE); 48227c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.opgetfh.status != NFS4_OK) 48237c478bd9Sstevel@tonic-gate return (TRUE); 48247c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, 48257c478bd9Sstevel@tonic-gate (char **)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_val, 48267c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_resop4_u.opgetfh.object.nfs_fh4_len, 48277c478bd9Sstevel@tonic-gate NFS4_FHSIZE)); 48287c478bd9Sstevel@tonic-gate case OP_LOOKUP: 48297c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 48307c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oplookup.status)); 48317c478bd9Sstevel@tonic-gate case OP_NVERIFY: 48327c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 48337c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opnverify.status)); 48347c478bd9Sstevel@tonic-gate case OP_OPEN: 48357c478bd9Sstevel@tonic-gate return (xdr_OPEN4res(xdrs, &objp->nfs_resop4_u.opopen)); 48367c478bd9Sstevel@tonic-gate case OP_CLOSE: 48377c478bd9Sstevel@tonic-gate return (xdr_CLOSE4res(xdrs, &objp->nfs_resop4_u.opclose)); 48387c478bd9Sstevel@tonic-gate case OP_ACCESS: 48397c478bd9Sstevel@tonic-gate return (xdr_ACCESS4res(xdrs, &objp->nfs_resop4_u.opaccess)); 48407c478bd9Sstevel@tonic-gate case OP_READ: 48417c478bd9Sstevel@tonic-gate return (xdr_READ4res_clnt(xdrs, &objp->nfs_resop4_u.opread, 48427c478bd9Sstevel@tonic-gate &aobjp->nfs_argop4_u.opread)); 48437c478bd9Sstevel@tonic-gate case OP_WRITE: 48447c478bd9Sstevel@tonic-gate return (xdr_WRITE4res(xdrs, &objp->nfs_resop4_u.opwrite)); 48457c478bd9Sstevel@tonic-gate case OP_DELEGRETURN: 48467c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 48477c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opdelegreturn.status)); 48487c478bd9Sstevel@tonic-gate case OP_LOOKUPP: 48497c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 48507c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oplookupp.status)); 48517c478bd9Sstevel@tonic-gate case OP_READDIR: 48527c478bd9Sstevel@tonic-gate return (xdr_READDIR4res_clnt(xdrs, 48537c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opreaddirclnt, 48547c478bd9Sstevel@tonic-gate &aobjp->nfs_argop4_u.opreaddir)); 48557c478bd9Sstevel@tonic-gate case OP_REMOVE: 48567c478bd9Sstevel@tonic-gate return (xdr_REMOVE4res(xdrs, &objp->nfs_resop4_u.opremove)); 48577c478bd9Sstevel@tonic-gate 48587c478bd9Sstevel@tonic-gate case OP_COMMIT: 48597c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 48607c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opcommit.status)) 48617c478bd9Sstevel@tonic-gate return (FALSE); 48627c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.opcommit.status != NFS4_OK) 48637c478bd9Sstevel@tonic-gate return (TRUE); 48647c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, 48657c478bd9Sstevel@tonic-gate (u_longlong_t *)&objp->nfs_resop4_u.opcommit. 48667c478bd9Sstevel@tonic-gate writeverf)); 48677c478bd9Sstevel@tonic-gate case OP_CREATE: 48687c478bd9Sstevel@tonic-gate return (xdr_CREATE4res(xdrs, &objp->nfs_resop4_u.opcreate)); 48697c478bd9Sstevel@tonic-gate case OP_DELEGPURGE: 48707c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 48717c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opdelegpurge.status)); 48727c478bd9Sstevel@tonic-gate case OP_LINK: 48737c478bd9Sstevel@tonic-gate return (xdr_LINK4res(xdrs, &objp->nfs_resop4_u.oplink)); 48747c478bd9Sstevel@tonic-gate case OP_LOCK: 48757c478bd9Sstevel@tonic-gate return (xdr_LOCK4res(xdrs, &objp->nfs_resop4_u.oplock)); 48767c478bd9Sstevel@tonic-gate case OP_LOCKT: 48777c478bd9Sstevel@tonic-gate return (xdr_LOCKT4res(xdrs, &objp->nfs_resop4_u.oplockt)); 48787c478bd9Sstevel@tonic-gate case OP_LOCKU: 48797c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 48807c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oplocku.status)) 48817c478bd9Sstevel@tonic-gate return (FALSE); 48827c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.oplocku.status != NFS4_OK) 48837c478bd9Sstevel@tonic-gate return (TRUE); 48847c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, 48857c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.oplocku.lock_stateid.seqid)) 48867c478bd9Sstevel@tonic-gate return (FALSE); 48877c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, 48887c478bd9Sstevel@tonic-gate objp->nfs_resop4_u.oplocku.lock_stateid.other, 4889bbe876c0SMarcel Telka NFS4_OTHER_SIZE)); 48907c478bd9Sstevel@tonic-gate case OP_OPENATTR: 48917c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 48927c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opopenattr.status)); 48937c478bd9Sstevel@tonic-gate case OP_OPEN_CONFIRM: 48947c478bd9Sstevel@tonic-gate return (xdr_OPEN_CONFIRM4res(xdrs, 48957c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opopen_confirm)); 48967c478bd9Sstevel@tonic-gate case OP_OPEN_DOWNGRADE: 48977c478bd9Sstevel@tonic-gate return (xdr_OPEN_DOWNGRADE4res(xdrs, 48987c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opopen_downgrade)); 48997c478bd9Sstevel@tonic-gate case OP_PUTPUBFH: 49007c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 49017c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opputpubfh.status)); 49027c478bd9Sstevel@tonic-gate case OP_PUTROOTFH: 49037c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 49047c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opputrootfh.status)); 49057c478bd9Sstevel@tonic-gate case OP_READLINK: 49067c478bd9Sstevel@tonic-gate return (xdr_READLINK4res(xdrs, &objp->nfs_resop4_u.opreadlink)); 49077c478bd9Sstevel@tonic-gate case OP_RENAME: 49087c478bd9Sstevel@tonic-gate return (xdr_RENAME4res(xdrs, &objp->nfs_resop4_u.oprename)); 49097c478bd9Sstevel@tonic-gate case OP_RENEW: 49107c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 49117c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oprenew.status)); 49127c478bd9Sstevel@tonic-gate case OP_RESTOREFH: 49137c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 49147c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oprestorefh.status)); 49157c478bd9Sstevel@tonic-gate case OP_SAVEFH: 49167c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 49177c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opsavefh.status)); 49187c478bd9Sstevel@tonic-gate case OP_SECINFO: 49197c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsecinfo. 49207c478bd9Sstevel@tonic-gate status)) 49217c478bd9Sstevel@tonic-gate return (FALSE); 49227c478bd9Sstevel@tonic-gate if (objp->nfs_resop4_u.opsecinfo.status != NFS4_OK) 49237c478bd9Sstevel@tonic-gate return (TRUE); 49247c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->nfs_resop4_u.opsecinfo. 49257c478bd9Sstevel@tonic-gate SECINFO4resok_val, 49267c478bd9Sstevel@tonic-gate (uint_t *)&objp->nfs_resop4_u.opsecinfo. 49277c478bd9Sstevel@tonic-gate SECINFO4resok_len, 49287c478bd9Sstevel@tonic-gate ~0, sizeof (secinfo4), (xdrproc_t)xdr_secinfo4)); 49297c478bd9Sstevel@tonic-gate case OP_SETATTR: 49307c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->nfs_resop4_u.opsetattr. 49317c478bd9Sstevel@tonic-gate status)) 49327c478bd9Sstevel@tonic-gate return (FALSE); 49337c478bd9Sstevel@tonic-gate return (xdr_bitmap4(xdrs, 49347c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opsetattr.attrsset)); 49357c478bd9Sstevel@tonic-gate case OP_SETCLIENTID: 49367c478bd9Sstevel@tonic-gate return (xdr_SETCLIENTID4res(xdrs, 49377c478bd9Sstevel@tonic-gate &objp->nfs_resop4_u.opsetclientid)); 49387c478bd9Sstevel@tonic-gate case OP_SETCLIENTID_CONFIRM: 49397c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 49407c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opsetclientid_confirm. 49417c478bd9Sstevel@tonic-gate status)); 49427c478bd9Sstevel@tonic-gate case OP_VERIFY: 49437c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 49447c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opverify.status)); 49457c478bd9Sstevel@tonic-gate case OP_RELEASE_LOCKOWNER: 49467c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 49477c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.oprelease_lockowner.status)); 49487c478bd9Sstevel@tonic-gate case OP_ILLEGAL: 49497c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 49507c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_resop4_u.opillegal.status)); 49517c478bd9Sstevel@tonic-gate } 49527c478bd9Sstevel@tonic-gate return (FALSE); 49537c478bd9Sstevel@tonic-gate } 49547c478bd9Sstevel@tonic-gate 49557c478bd9Sstevel@tonic-gate bool_t 49567c478bd9Sstevel@tonic-gate xdr_COMPOUND4args_clnt(XDR *xdrs, COMPOUND4args_clnt *objp) 49577c478bd9Sstevel@tonic-gate { 49587c478bd9Sstevel@tonic-gate static int32_t twelve = 12; 49597c478bd9Sstevel@tonic-gate static int32_t minorversion = NFS4_MINORVERSION; 49607c478bd9Sstevel@tonic-gate uint32_t *ctagp; 49617c478bd9Sstevel@tonic-gate rpc_inline_t *ptr; 49620a701b1eSRobert Gordon rdma_chunkinfo_t rci; 49630a701b1eSRobert Gordon struct xdr_ops *xops = xdrrdma_xops(); 49647c478bd9Sstevel@tonic-gate 49657c478bd9Sstevel@tonic-gate /* 49667c478bd9Sstevel@tonic-gate * XDR_ENCODE only 49677c478bd9Sstevel@tonic-gate */ 49687c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 49697c478bd9Sstevel@tonic-gate return (TRUE); 49707c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) 49717c478bd9Sstevel@tonic-gate return (FALSE); 49727c478bd9Sstevel@tonic-gate 49737c478bd9Sstevel@tonic-gate ctagp = (uint32_t *)&nfs4_ctags[objp->ctag].ct_tag; 49747c478bd9Sstevel@tonic-gate 49757c478bd9Sstevel@tonic-gate if ((ptr = XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT)) != NULL) { 49767c478bd9Sstevel@tonic-gate /* 49777c478bd9Sstevel@tonic-gate * Efficiently encode fixed length tags, could be longlongs 49787c478bd9Sstevel@tonic-gate * but 8 byte XDR alignment not assured 49797c478bd9Sstevel@tonic-gate */ 49807c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, 12); 49817c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, ctagp[0]); 49827c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, ctagp[1]); 49837c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, ctagp[2]); 49847c478bd9Sstevel@tonic-gate 49857c478bd9Sstevel@tonic-gate /* 49867c478bd9Sstevel@tonic-gate * Fixed minor version for now 49877c478bd9Sstevel@tonic-gate */ 49887c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, NFS4_MINORVERSION); 49897c478bd9Sstevel@tonic-gate } else { 49907c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, &twelve)) 49917c478bd9Sstevel@tonic-gate return (FALSE); 49927c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[0])) 49937c478bd9Sstevel@tonic-gate return (FALSE); 49947c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[1])) 49957c478bd9Sstevel@tonic-gate return (FALSE); 49967c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&ctagp[2])) 49977c478bd9Sstevel@tonic-gate return (FALSE); 49987c478bd9Sstevel@tonic-gate if (!XDR_PUTINT32(xdrs, (int32_t *)&minorversion)) 49997c478bd9Sstevel@tonic-gate return (FALSE); 50007c478bd9Sstevel@tonic-gate } 50010a701b1eSRobert Gordon if (xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) { 50020a701b1eSRobert Gordon rci.rci_type = RCI_REPLY_CHUNK; 50030a701b1eSRobert Gordon rci.rci_len = MAXPATHLEN * 2; 50040a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci); 50050a701b1eSRobert Gordon } 50067c478bd9Sstevel@tonic-gate 50077c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->array, 50087c478bd9Sstevel@tonic-gate (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, 50097c478bd9Sstevel@tonic-gate sizeof (nfs_argop4), (xdrproc_t)xdr_cnfs_argop4)); 50107c478bd9Sstevel@tonic-gate } 50117c478bd9Sstevel@tonic-gate 50127c478bd9Sstevel@tonic-gate bool_t 50137c46fb7fSek110237 xdr_COMPOUND4args_srv(XDR *xdrs, COMPOUND4args *objp) 50147c478bd9Sstevel@tonic-gate { 50157c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val, 50167c478bd9Sstevel@tonic-gate (uint_t *)&objp->tag.utf8string_len, 50177c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)) 50187c478bd9Sstevel@tonic-gate return (FALSE); 50197c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->minorversion)) 50207c478bd9Sstevel@tonic-gate return (FALSE); 50217c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) 50227c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->array, 50237c478bd9Sstevel@tonic-gate (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, 50247c46fb7fSek110237 sizeof (nfs_argop4), (xdrproc_t)xdr_snfs_argop4)); 50257c478bd9Sstevel@tonic-gate 50267c46fb7fSek110237 return (xdr_snfs_argop4_free(xdrs, &objp->array, objp->array_len)); 50277c478bd9Sstevel@tonic-gate } 50287c478bd9Sstevel@tonic-gate 50297c478bd9Sstevel@tonic-gate bool_t 50307c478bd9Sstevel@tonic-gate xdr_COMPOUND4res_clnt(XDR *xdrs, COMPOUND4res_clnt *objp) 50317c478bd9Sstevel@tonic-gate { 50327c478bd9Sstevel@tonic-gate uint32_t len; 50337c478bd9Sstevel@tonic-gate int32_t *ptr; 50347c478bd9Sstevel@tonic-gate nfs_argop4 *argop; 50357c478bd9Sstevel@tonic-gate nfs_resop4 *resop; 50367c478bd9Sstevel@tonic-gate 50377c478bd9Sstevel@tonic-gate /* 50387c478bd9Sstevel@tonic-gate * No XDR_ENCODE 50397c478bd9Sstevel@tonic-gate */ 50407c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) 50417c478bd9Sstevel@tonic-gate return (FALSE); 50427c478bd9Sstevel@tonic-gate 50437c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) { 50447c478bd9Sstevel@tonic-gate if ((ptr = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT)) != NULL) { 50457c478bd9Sstevel@tonic-gate objp->status = IXDR_GET_U_INT32(ptr); 50467c478bd9Sstevel@tonic-gate len = IXDR_GET_U_INT32(ptr); 50477c478bd9Sstevel@tonic-gate } else { 50487c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 50497c478bd9Sstevel@tonic-gate return (FALSE); 50507c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, (uint32_t *)&len)) 50517c478bd9Sstevel@tonic-gate return (FALSE); 50527c478bd9Sstevel@tonic-gate } 50537c478bd9Sstevel@tonic-gate if (len > NFS4_MAX_UTF8STRING) 50547c478bd9Sstevel@tonic-gate return (FALSE); 50557c478bd9Sstevel@tonic-gate /* 50567c478bd9Sstevel@tonic-gate * Ignore the tag 50577c478bd9Sstevel@tonic-gate */ 50587c478bd9Sstevel@tonic-gate if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &len)) 50597c478bd9Sstevel@tonic-gate return (FALSE); 50607c478bd9Sstevel@tonic-gate 50617c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->array_len)) 50627c478bd9Sstevel@tonic-gate return (FALSE); 50637c478bd9Sstevel@tonic-gate 50647c478bd9Sstevel@tonic-gate if (objp->array_len > objp->argsp->array_len) 50657c478bd9Sstevel@tonic-gate return (FALSE); 50667c478bd9Sstevel@tonic-gate 50672c2d21e9SRichard Lowe if (objp->status == NFS4_OK && 50687c478bd9Sstevel@tonic-gate objp->array_len != objp->argsp->array_len) 50697c478bd9Sstevel@tonic-gate return (FALSE); 50707c478bd9Sstevel@tonic-gate 50717c478bd9Sstevel@tonic-gate /* Alloc the results array */ 50727c478bd9Sstevel@tonic-gate argop = objp->argsp->array; 50737c478bd9Sstevel@tonic-gate len = objp->array_len * sizeof (nfs_resop4); 50747c478bd9Sstevel@tonic-gate objp->decode_len = 0; 50757c478bd9Sstevel@tonic-gate objp->array = resop = kmem_zalloc(len, KM_SLEEP); 50767c478bd9Sstevel@tonic-gate 50777c478bd9Sstevel@tonic-gate for (len = 0; len < objp->array_len; 50787c478bd9Sstevel@tonic-gate len++, resop++, argop++, objp->decode_len++) { 50797c478bd9Sstevel@tonic-gate if (!xdr_nfs_resop4_clnt(xdrs, resop, argop)) { 50807c478bd9Sstevel@tonic-gate /* 50817c478bd9Sstevel@tonic-gate * Make sure to free anything that may 50827c478bd9Sstevel@tonic-gate * have been allocated along the way. 50837c478bd9Sstevel@tonic-gate */ 50847c478bd9Sstevel@tonic-gate xdrs->x_op = XDR_FREE; 50857c478bd9Sstevel@tonic-gate (void) xdr_nfs_resop4_free(xdrs, &objp->array, 50867c478bd9Sstevel@tonic-gate objp->array_len, 50877c478bd9Sstevel@tonic-gate objp->decode_len); 50887c478bd9Sstevel@tonic-gate return (FALSE); 50897c478bd9Sstevel@tonic-gate } 50907c478bd9Sstevel@tonic-gate } 50917c478bd9Sstevel@tonic-gate return (TRUE); 50927c478bd9Sstevel@tonic-gate } 50937c478bd9Sstevel@tonic-gate return (xdr_nfs_resop4_free(xdrs, &objp->array, 50947c478bd9Sstevel@tonic-gate objp->array_len, objp->decode_len)); 50957c478bd9Sstevel@tonic-gate } 50967c478bd9Sstevel@tonic-gate 50977c478bd9Sstevel@tonic-gate bool_t 50987c46fb7fSek110237 xdr_COMPOUND4res_srv(XDR *xdrs, COMPOUND4res *objp) 50997c478bd9Sstevel@tonic-gate { 51007c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 51017c478bd9Sstevel@tonic-gate return (FALSE); 51027c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val, 51037c478bd9Sstevel@tonic-gate (uint_t *)&objp->tag.utf8string_len, 51047c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)) 51057c478bd9Sstevel@tonic-gate return (FALSE); 51067c478bd9Sstevel@tonic-gate 51077c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_FREE) 51087c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->array, 51097c478bd9Sstevel@tonic-gate (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, 51107c46fb7fSek110237 sizeof (nfs_resop4), (xdrproc_t)xdr_snfs_resop4)); 51117c478bd9Sstevel@tonic-gate 51127c46fb7fSek110237 return (xdr_snfs_resop4_free(xdrs, &objp->array, 51137c478bd9Sstevel@tonic-gate objp->array_len, objp->array_len)); 51147c478bd9Sstevel@tonic-gate } 51157c478bd9Sstevel@tonic-gate 5116eac3aab7Srobinson /* 5117eac3aab7Srobinson * NFS server side callback, initiating the callback request so it 5118eac3aab7Srobinson * is the RPC client. Must convert from server's internal filehandle 5119eac3aab7Srobinson * format to wire format. 5120eac3aab7Srobinson */ 51217c478bd9Sstevel@tonic-gate static bool_t 5122eac3aab7Srobinson xdr_snfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp) 51237c478bd9Sstevel@tonic-gate { 5124eac3aab7Srobinson CB_GETATTR4args *gargs; 5125eac3aab7Srobinson CB_RECALL4args *rargs; 5126eac3aab7Srobinson 5127eac3aab7Srobinson ASSERT(xdrs->x_op == XDR_ENCODE); 5128eac3aab7Srobinson 5129eac3aab7Srobinson if (!XDR_PUTINT32(xdrs, (int32_t *)&objp->argop)) 5130eac3aab7Srobinson return (FALSE); 5131eac3aab7Srobinson 5132eac3aab7Srobinson switch (objp->argop) { 5133eac3aab7Srobinson case OP_CB_GETATTR: 5134eac3aab7Srobinson gargs = &objp->nfs_cb_argop4_u.opcbgetattr; 5135eac3aab7Srobinson 5136eac3aab7Srobinson if (!xdr_encode_nfs_fh4(xdrs, &gargs->fh)) 5137eac3aab7Srobinson return (FALSE); 5138eac3aab7Srobinson return (xdr_bitmap4(xdrs, &gargs->attr_request)); 5139eac3aab7Srobinson case OP_CB_RECALL: 5140eac3aab7Srobinson rargs = &objp->nfs_cb_argop4_u.opcbrecall; 5141eac3aab7Srobinson 5142eac3aab7Srobinson if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->stateid.seqid)) 5143eac3aab7Srobinson return (FALSE); 5144bbe876c0SMarcel Telka if (!xdr_opaque(xdrs, rargs->stateid.other, NFS4_OTHER_SIZE)) 5145eac3aab7Srobinson return (FALSE); 5146eac3aab7Srobinson if (!XDR_PUTINT32(xdrs, (int32_t *)&rargs->truncate)) 5147eac3aab7Srobinson return (FALSE); 5148eac3aab7Srobinson return (xdr_encode_nfs_fh4(xdrs, &rargs->fh)); 5149eac3aab7Srobinson case OP_CB_ILLEGAL: 5150eac3aab7Srobinson return (TRUE); 5151eac3aab7Srobinson } 5152eac3aab7Srobinson return (FALSE); 5153eac3aab7Srobinson } 5154eac3aab7Srobinson 5155eac3aab7Srobinson /* 5156eac3aab7Srobinson * NFS client side callback, receiving the callback request so it 5157eac3aab7Srobinson * is the RPC server. Must treat the file handles as opaque. 5158eac3aab7Srobinson */ 5159eac3aab7Srobinson static bool_t 5160eac3aab7Srobinson xdr_cnfs_cb_argop4(XDR *xdrs, nfs_cb_argop4 *objp) 5161eac3aab7Srobinson { 5162eac3aab7Srobinson CB_GETATTR4args *gargs; 5163eac3aab7Srobinson CB_RECALL4args *rargs; 5164eac3aab7Srobinson 5165eac3aab7Srobinson ASSERT(xdrs->x_op != XDR_ENCODE); 5166eac3aab7Srobinson 51677c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->argop)) 51687c478bd9Sstevel@tonic-gate return (FALSE); 51697c478bd9Sstevel@tonic-gate switch (objp->argop) { 51707c478bd9Sstevel@tonic-gate case OP_CB_GETATTR: 5171eac3aab7Srobinson gargs = &objp->nfs_cb_argop4_u.opcbgetattr; 5172eac3aab7Srobinson 5173eac3aab7Srobinson if (!xdr_bytes(xdrs, (char **)&gargs->fh.nfs_fh4_val, 5174eac3aab7Srobinson (uint_t *)&gargs->fh.nfs_fh4_len, NFS4_FHSIZE)) 51757c478bd9Sstevel@tonic-gate return (FALSE); 5176eac3aab7Srobinson return (xdr_bitmap4(xdrs, &gargs->attr_request)); 51777c478bd9Sstevel@tonic-gate case OP_CB_RECALL: 5178eac3aab7Srobinson rargs = &objp->nfs_cb_argop4_u.opcbrecall; 5179eac3aab7Srobinson 5180eac3aab7Srobinson if (!xdr_u_int(xdrs, &rargs->stateid.seqid)) 51817c478bd9Sstevel@tonic-gate return (FALSE); 5182bbe876c0SMarcel Telka if (!xdr_opaque(xdrs, rargs->stateid.other, NFS4_OTHER_SIZE)) 51837c478bd9Sstevel@tonic-gate return (FALSE); 5184eac3aab7Srobinson if (!xdr_bool(xdrs, &rargs->truncate)) 51857c478bd9Sstevel@tonic-gate return (FALSE); 5186eac3aab7Srobinson return (xdr_bytes(xdrs, (char **)&rargs->fh.nfs_fh4_val, 5187eac3aab7Srobinson (uint_t *)&rargs->fh.nfs_fh4_len, NFS4_FHSIZE)); 51887c478bd9Sstevel@tonic-gate case OP_CB_ILLEGAL: 51897c478bd9Sstevel@tonic-gate return (TRUE); 51907c478bd9Sstevel@tonic-gate } 51917c478bd9Sstevel@tonic-gate return (FALSE); 51927c478bd9Sstevel@tonic-gate } 51937c478bd9Sstevel@tonic-gate 51947c478bd9Sstevel@tonic-gate static bool_t 51957c478bd9Sstevel@tonic-gate xdr_nfs_cb_resop4(XDR *xdrs, nfs_cb_resop4 *objp) 51967c478bd9Sstevel@tonic-gate { 51977c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->resop)) 51987c478bd9Sstevel@tonic-gate return (FALSE); 51997c478bd9Sstevel@tonic-gate switch (objp->resop) { 52007c478bd9Sstevel@tonic-gate case OP_CB_GETATTR: 52017c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, 52027c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_cb_resop4_u.opcbgetattr. 52037c478bd9Sstevel@tonic-gate status)) 52047c478bd9Sstevel@tonic-gate return (FALSE); 52057c478bd9Sstevel@tonic-gate if (objp->nfs_cb_resop4_u.opcbgetattr.status != NFS4_OK) 52067c478bd9Sstevel@tonic-gate return (TRUE); 52077c478bd9Sstevel@tonic-gate return (xdr_fattr4(xdrs, 52087c478bd9Sstevel@tonic-gate &objp->nfs_cb_resop4_u.opcbgetattr. 52097c478bd9Sstevel@tonic-gate obj_attributes)); 52107c478bd9Sstevel@tonic-gate case OP_CB_RECALL: 52117c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 52127c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_cb_resop4_u.opcbrecall.status)); 52137c478bd9Sstevel@tonic-gate case OP_CB_ILLEGAL: 52147c478bd9Sstevel@tonic-gate return (xdr_int(xdrs, 52157c478bd9Sstevel@tonic-gate (int32_t *)&objp->nfs_cb_resop4_u.opcbillegal.status)); 52167c478bd9Sstevel@tonic-gate } 52177c478bd9Sstevel@tonic-gate return (FALSE); 52187c478bd9Sstevel@tonic-gate } 52197c478bd9Sstevel@tonic-gate 5220eac3aab7Srobinson /* 5221eac3aab7Srobinson * The NFS client side callback, RPC server 5222eac3aab7Srobinson */ 52237c478bd9Sstevel@tonic-gate bool_t 5224eac3aab7Srobinson xdr_CB_COMPOUND4args_clnt(XDR *xdrs, CB_COMPOUND4args *objp) 52257c478bd9Sstevel@tonic-gate { 52267c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val, 52277c478bd9Sstevel@tonic-gate (uint_t *)&objp->tag.utf8string_len, 52287c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)) 52297c478bd9Sstevel@tonic-gate return (FALSE); 52307c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->minorversion)) 52317c478bd9Sstevel@tonic-gate return (FALSE); 52327c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->callback_ident)) 52337c478bd9Sstevel@tonic-gate return (FALSE); 52347c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->array, 52357c478bd9Sstevel@tonic-gate (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, 5236eac3aab7Srobinson sizeof (nfs_cb_argop4), (xdrproc_t)xdr_cnfs_cb_argop4)); 5237eac3aab7Srobinson } 5238eac3aab7Srobinson 5239eac3aab7Srobinson /* 5240eac3aab7Srobinson * The NFS server side callback, RPC client 5241eac3aab7Srobinson */ 5242eac3aab7Srobinson bool_t 5243eac3aab7Srobinson xdr_CB_COMPOUND4args_srv(XDR *xdrs, CB_COMPOUND4args *objp) 5244eac3aab7Srobinson { 5245eac3aab7Srobinson if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val, 5246eac3aab7Srobinson (uint_t *)&objp->tag.utf8string_len, 5247eac3aab7Srobinson NFS4_MAX_UTF8STRING)) 5248eac3aab7Srobinson return (FALSE); 5249eac3aab7Srobinson if (!xdr_u_int(xdrs, &objp->minorversion)) 5250eac3aab7Srobinson return (FALSE); 5251eac3aab7Srobinson if (!xdr_u_int(xdrs, &objp->callback_ident)) 5252eac3aab7Srobinson return (FALSE); 5253eac3aab7Srobinson return (xdr_array(xdrs, (char **)&objp->array, 5254eac3aab7Srobinson (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, 5255eac3aab7Srobinson sizeof (nfs_cb_argop4), (xdrproc_t)xdr_snfs_cb_argop4)); 52567c478bd9Sstevel@tonic-gate } 52577c478bd9Sstevel@tonic-gate 52587c478bd9Sstevel@tonic-gate bool_t 52597c478bd9Sstevel@tonic-gate xdr_CB_COMPOUND4res(XDR *xdrs, CB_COMPOUND4res *objp) 52607c478bd9Sstevel@tonic-gate { 52617c478bd9Sstevel@tonic-gate if (!xdr_int(xdrs, (int32_t *)&objp->status)) 52627c478bd9Sstevel@tonic-gate return (FALSE); 52637c478bd9Sstevel@tonic-gate if (!xdr_bytes(xdrs, (char **)&objp->tag.utf8string_val, 52647c478bd9Sstevel@tonic-gate (uint_t *)&objp->tag.utf8string_len, 52657c478bd9Sstevel@tonic-gate NFS4_MAX_UTF8STRING)) 52667c478bd9Sstevel@tonic-gate return (FALSE); 52677c478bd9Sstevel@tonic-gate return (xdr_array(xdrs, (char **)&objp->array, 52687c478bd9Sstevel@tonic-gate (uint_t *)&objp->array_len, NFS4_COMPOUND_LIMIT, 52697c478bd9Sstevel@tonic-gate sizeof (nfs_cb_resop4), (xdrproc_t)xdr_nfs_cb_resop4)); 52707c478bd9Sstevel@tonic-gate } 5271