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 */ 217c478bd9Sstevel@tonic-gate /* 22c242f9a0Schunli zhang - Sun Microsystems - Irvine United States * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 277c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 287c478bd9Sstevel@tonic-gate 29*e36d7b11SSebastien Roy /* 30*e36d7b11SSebastien Roy * Copyright (c) 2013 by Delphix. All rights reserved. 31*e36d7b11SSebastien Roy */ 32*e36d7b11SSebastien Roy 337c478bd9Sstevel@tonic-gate #include <sys/param.h> 347c478bd9Sstevel@tonic-gate #include <sys/types.h> 357c478bd9Sstevel@tonic-gate #include <sys/systm.h> 367c478bd9Sstevel@tonic-gate #include <sys/user.h> 377c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 387c478bd9Sstevel@tonic-gate #include <sys/file.h> 397c478bd9Sstevel@tonic-gate #include <sys/dirent.h> 407c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 417c478bd9Sstevel@tonic-gate #include <sys/stream.h> 427c478bd9Sstevel@tonic-gate #include <sys/strsubr.h> 437c478bd9Sstevel@tonic-gate #include <sys/debug.h> 447c478bd9Sstevel@tonic-gate #include <sys/t_lock.h> 457c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h> 467c478bd9Sstevel@tonic-gate #include <sys/dnlc.h> 477c478bd9Sstevel@tonic-gate #include <sys/cred.h> 487c478bd9Sstevel@tonic-gate #include <sys/time.h> 4927242a7cSthurlow #include <sys/sdt.h> 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #include <rpc/types.h> 527c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate #include <nfs/nfs.h> 557c478bd9Sstevel@tonic-gate #include <nfs/rnode.h> 560a701b1eSRobert Gordon #include <rpc/rpc_rdma.h> 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /* 597c478bd9Sstevel@tonic-gate * These are the XDR routines used to serialize and deserialize 607c478bd9Sstevel@tonic-gate * the various structures passed as parameters across the network 617c478bd9Sstevel@tonic-gate * between NFS clients and servers. 627c478bd9Sstevel@tonic-gate */ 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* 657c478bd9Sstevel@tonic-gate * XDR null terminated ASCII strings 667c478bd9Sstevel@tonic-gate * xdr_string3 deals with "C strings" - arrays of bytes that are 677c478bd9Sstevel@tonic-gate * terminated by a NULL character. The parameter cpp references a 687c478bd9Sstevel@tonic-gate * pointer to storage; If the pointer is null, then the necessary 697c478bd9Sstevel@tonic-gate * storage is allocated. The last parameter is the max allowed length 707c478bd9Sstevel@tonic-gate * of the string as allowed by the system. The NFS Version 3 protocol 717c478bd9Sstevel@tonic-gate * does not place limits on strings, but the implementation needs to 727c478bd9Sstevel@tonic-gate * place a reasonable limit to avoid problems. 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate bool_t 757c478bd9Sstevel@tonic-gate xdr_string3(XDR *xdrs, char **cpp, uint_t maxsize) 767c478bd9Sstevel@tonic-gate { 777c478bd9Sstevel@tonic-gate char *sp; 787c478bd9Sstevel@tonic-gate uint_t size; 797c478bd9Sstevel@tonic-gate uint_t nodesize; 807c478bd9Sstevel@tonic-gate bool_t mem_alloced = FALSE; 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /* 837c478bd9Sstevel@tonic-gate * first deal with the length since xdr strings are counted-strings 847c478bd9Sstevel@tonic-gate */ 857c478bd9Sstevel@tonic-gate sp = *cpp; 867c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 877c478bd9Sstevel@tonic-gate case XDR_FREE: 887c478bd9Sstevel@tonic-gate if (sp == NULL || sp == nfs3nametoolong) 897c478bd9Sstevel@tonic-gate return (TRUE); /* already free */ 907c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate case XDR_ENCODE: 937c478bd9Sstevel@tonic-gate size = (uint_t)strlen(sp); 947c478bd9Sstevel@tonic-gate break; 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate case XDR_DECODE: 977c478bd9Sstevel@tonic-gate break; 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &size)) 1017c478bd9Sstevel@tonic-gate return (FALSE); 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* 1047c478bd9Sstevel@tonic-gate * now deal with the actual bytes 1057c478bd9Sstevel@tonic-gate */ 1067c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 1077c478bd9Sstevel@tonic-gate case XDR_DECODE: 1087c478bd9Sstevel@tonic-gate if (size >= maxsize) { 1097c478bd9Sstevel@tonic-gate *cpp = nfs3nametoolong; 1107c478bd9Sstevel@tonic-gate if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size)) 1117c478bd9Sstevel@tonic-gate return (FALSE); 1127c478bd9Sstevel@tonic-gate return (TRUE); 1137c478bd9Sstevel@tonic-gate } 1147c478bd9Sstevel@tonic-gate nodesize = size + 1; 1157c478bd9Sstevel@tonic-gate if (nodesize == 0) 1167c478bd9Sstevel@tonic-gate return (TRUE); 1177c478bd9Sstevel@tonic-gate if (sp == NULL) { 1187c478bd9Sstevel@tonic-gate sp = kmem_alloc(nodesize, KM_NOSLEEP); 1197c478bd9Sstevel@tonic-gate *cpp = sp; 1207c478bd9Sstevel@tonic-gate if (sp == NULL) 1217c478bd9Sstevel@tonic-gate return (FALSE); 1227c478bd9Sstevel@tonic-gate mem_alloced = TRUE; 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate sp[size] = 0; 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate if (xdr_opaque(xdrs, sp, size)) { 1277c478bd9Sstevel@tonic-gate if (strlen(sp) != size) { 1287c478bd9Sstevel@tonic-gate if (mem_alloced) 1297c478bd9Sstevel@tonic-gate kmem_free(sp, nodesize); 1307c478bd9Sstevel@tonic-gate *cpp = NULL; 1317c478bd9Sstevel@tonic-gate return (FALSE); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate } else { 1347c478bd9Sstevel@tonic-gate if (mem_alloced) 1357c478bd9Sstevel@tonic-gate kmem_free(sp, nodesize); 1367c478bd9Sstevel@tonic-gate *cpp = NULL; 1377c478bd9Sstevel@tonic-gate return (FALSE); 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate return (TRUE); 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate case XDR_ENCODE: 1427c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, sp, size)); 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate case XDR_FREE: 1457c478bd9Sstevel@tonic-gate nodesize = size + 1; 1467c478bd9Sstevel@tonic-gate kmem_free(sp, nodesize); 1477c478bd9Sstevel@tonic-gate *cpp = NULL; 1487c478bd9Sstevel@tonic-gate return (TRUE); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate return (FALSE); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate /* 15527242a7cSthurlow * XDR_INLINE decode a filehandle. 1567c478bd9Sstevel@tonic-gate */ 15727242a7cSthurlow bool_t 15827242a7cSthurlow xdr_inline_decode_nfs_fh3(uint32_t *ptr, nfs_fh3 *fhp, uint32_t fhsize) 1597c478bd9Sstevel@tonic-gate { 16027242a7cSthurlow uchar_t *bp = (uchar_t *)ptr; 16127242a7cSthurlow uchar_t *cp; 16227242a7cSthurlow uint32_t dsize; 16327242a7cSthurlow uintptr_t resid; 1647c478bd9Sstevel@tonic-gate 16527242a7cSthurlow /* 16627242a7cSthurlow * Check to see if what the client sent us is bigger or smaller 16727242a7cSthurlow * than what we can ever possibly send out. NFS_FHMAXDATA is 16827242a7cSthurlow * unfortunately badly named as it is no longer the max and is 16927242a7cSthurlow * really the min of what is sent over the wire. 17027242a7cSthurlow */ 17127242a7cSthurlow if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) + 17227242a7cSthurlow sizeof (ushort_t) + NFS_FHMAXDATA + 17327242a7cSthurlow sizeof (ushort_t) + NFS_FHMAXDATA)) { 17427242a7cSthurlow return (FALSE); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 17727242a7cSthurlow /* 17827242a7cSthurlow * All internal parts of a filehandle are in native byte order. 17927242a7cSthurlow * 18027242a7cSthurlow * Decode what should be fh3_fsid, it is aligned. 18127242a7cSthurlow */ 18227242a7cSthurlow fhp->fh3_fsid.val[0] = *(uint32_t *)bp; 18327242a7cSthurlow bp += BYTES_PER_XDR_UNIT; 18427242a7cSthurlow fhp->fh3_fsid.val[1] = *(uint32_t *)bp; 18527242a7cSthurlow bp += BYTES_PER_XDR_UNIT; 18627242a7cSthurlow 18727242a7cSthurlow /* 18827242a7cSthurlow * Decode what should be fh3_len. fh3_len is two bytes, so we're 18927242a7cSthurlow * unaligned now. 19027242a7cSthurlow */ 19127242a7cSthurlow cp = (uchar_t *)&fhp->fh3_len; 19227242a7cSthurlow *cp++ = *bp++; 19327242a7cSthurlow *cp++ = *bp++; 19427242a7cSthurlow fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t); 19527242a7cSthurlow 19627242a7cSthurlow /* 19727242a7cSthurlow * For backwards compatability, the fid length may be less than 19827242a7cSthurlow * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes. 19927242a7cSthurlow */ 20027242a7cSthurlow dsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len; 20127242a7cSthurlow 20227242a7cSthurlow /* 20327242a7cSthurlow * Make sure the client isn't sending us a bogus length for fh3x_data. 20427242a7cSthurlow */ 20527242a7cSthurlow if (fhsize < dsize) 20627242a7cSthurlow return (FALSE); 20727242a7cSthurlow bcopy(bp, fhp->fh3_data, dsize); 20827242a7cSthurlow bp += dsize; 20927242a7cSthurlow fhsize -= dsize; 21027242a7cSthurlow 21127242a7cSthurlow if (fhsize < sizeof (ushort_t)) 21227242a7cSthurlow return (FALSE); 21327242a7cSthurlow cp = (uchar_t *)&fhp->fh3_xlen; 21427242a7cSthurlow *cp++ = *bp++; 21527242a7cSthurlow *cp++ = *bp++; 21627242a7cSthurlow fhsize -= sizeof (ushort_t); 21727242a7cSthurlow 21827242a7cSthurlow dsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen; 21927242a7cSthurlow 22027242a7cSthurlow /* 22127242a7cSthurlow * Make sure the client isn't sending us a bogus length for fh3x_xdata. 22227242a7cSthurlow */ 22327242a7cSthurlow if (fhsize < dsize) 22427242a7cSthurlow return (FALSE); 22527242a7cSthurlow bcopy(bp, fhp->fh3_xdata, dsize); 22627242a7cSthurlow fhsize -= dsize; 22727242a7cSthurlow bp += dsize; 22827242a7cSthurlow 22927242a7cSthurlow /* 23027242a7cSthurlow * We realign things on purpose, so skip any padding 23127242a7cSthurlow */ 23227242a7cSthurlow resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT; 23327242a7cSthurlow if (resid != 0) { 23427242a7cSthurlow if (fhsize < (BYTES_PER_XDR_UNIT - resid)) 23527242a7cSthurlow return (FALSE); 23627242a7cSthurlow bp += BYTES_PER_XDR_UNIT - resid; 23727242a7cSthurlow fhsize -= BYTES_PER_XDR_UNIT - resid; 23827242a7cSthurlow } 23927242a7cSthurlow 24027242a7cSthurlow /* 24127242a7cSthurlow * Make sure client didn't send extra bytes 24227242a7cSthurlow */ 24327242a7cSthurlow if (fhsize != 0) 24427242a7cSthurlow return (FALSE); 24527242a7cSthurlow return (TRUE); 24627242a7cSthurlow } 24727242a7cSthurlow 24827242a7cSthurlow static bool_t 24927242a7cSthurlow xdr_decode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp) 25027242a7cSthurlow { 25127242a7cSthurlow uint32_t fhsize; /* filehandle size */ 25227242a7cSthurlow uint32_t bufsize; 25327242a7cSthurlow rpc_inline_t *ptr; 25427242a7cSthurlow uchar_t *bp; 25527242a7cSthurlow 25627242a7cSthurlow ASSERT(xdrs->x_op == XDR_DECODE); 25727242a7cSthurlow 25827242a7cSthurlow /* 25927242a7cSthurlow * Retrieve the filehandle length. 26027242a7cSthurlow */ 26127242a7cSthurlow if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize)) 26227242a7cSthurlow return (FALSE); 26327242a7cSthurlow 26427242a7cSthurlow bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data)); 26527242a7cSthurlow objp->fh3_length = 0; 26627242a7cSthurlow 26727242a7cSthurlow /* 26827242a7cSthurlow * Check to see if what the client sent us is bigger or smaller 26927242a7cSthurlow * than what we can ever possibly send out. NFS_FHMAXDATA is 27027242a7cSthurlow * unfortunately badly named as it is no longer the max and is 27127242a7cSthurlow * really the min of what is sent over the wire. 27227242a7cSthurlow */ 27327242a7cSthurlow if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) + 27427242a7cSthurlow sizeof (ushort_t) + NFS_FHMAXDATA + 27527242a7cSthurlow sizeof (ushort_t) + NFS_FHMAXDATA)) { 27627242a7cSthurlow if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize)) 27727242a7cSthurlow return (FALSE); 27827242a7cSthurlow return (TRUE); 27927242a7cSthurlow } 28027242a7cSthurlow 28127242a7cSthurlow /* 28227242a7cSthurlow * bring in fhsize plus any padding 28327242a7cSthurlow */ 28427242a7cSthurlow bufsize = RNDUP(fhsize); 28527242a7cSthurlow ptr = XDR_INLINE(xdrs, bufsize); 28627242a7cSthurlow bp = (uchar_t *)ptr; 28727242a7cSthurlow if (ptr == NULL) { 28827242a7cSthurlow bp = kmem_alloc(bufsize, KM_SLEEP); 28927242a7cSthurlow if (!xdr_opaque(xdrs, (char *)bp, bufsize)) { 29027242a7cSthurlow kmem_free(bp, bufsize); 29127242a7cSthurlow return (FALSE); 29227242a7cSthurlow } 29327242a7cSthurlow } 29427242a7cSthurlow 29527242a7cSthurlow objp->fh3_length = sizeof (fhandle3_t); 29627242a7cSthurlow 29727242a7cSthurlow if (xdr_inline_decode_nfs_fh3((uint32_t *)bp, objp, fhsize) == FALSE) { 29827242a7cSthurlow /* 29927242a7cSthurlow * If in the process of decoding we find the file handle 30027242a7cSthurlow * is not correctly formed, we need to continue decoding 30127242a7cSthurlow * and trigger an NFS layer error. Set the nfs_fh3_len to 30227242a7cSthurlow * zero so it gets caught as a bad length. 30327242a7cSthurlow */ 30427242a7cSthurlow bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data)); 30527242a7cSthurlow objp->fh3_length = 0; 30627242a7cSthurlow } 30727242a7cSthurlow 30827242a7cSthurlow if (ptr == NULL) 30927242a7cSthurlow kmem_free(bp, bufsize); 31027242a7cSthurlow return (TRUE); 31127242a7cSthurlow } 31227242a7cSthurlow 31327242a7cSthurlow /* 31427242a7cSthurlow * XDR_INLINE encode a filehandle. 31527242a7cSthurlow */ 31627242a7cSthurlow bool_t 31727242a7cSthurlow xdr_inline_encode_nfs_fh3(uint32_t **ptrp, uint32_t *ptr_redzone, 31827242a7cSthurlow nfs_fh3 *fhp) 31927242a7cSthurlow { 32027242a7cSthurlow uint32_t *ptr = *ptrp; 32127242a7cSthurlow uchar_t *cp; 32227242a7cSthurlow uint_t otw_len, fsize, xsize; /* otw, file, and export sizes */ 32327242a7cSthurlow uint32_t padword; 32427242a7cSthurlow 32527242a7cSthurlow fsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len; 32627242a7cSthurlow xsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen; 32727242a7cSthurlow 32827242a7cSthurlow /* 32927242a7cSthurlow * First get the initial and variable sized part of the filehandle. 33027242a7cSthurlow */ 33127242a7cSthurlow otw_len = sizeof (fhp->fh3_fsid) + 33227242a7cSthurlow sizeof (fhp->fh3_len) + fsize + 33327242a7cSthurlow sizeof (fhp->fh3_xlen) + xsize; 33427242a7cSthurlow 33527242a7cSthurlow /* 33627242a7cSthurlow * Round out to a full word. 33727242a7cSthurlow */ 33827242a7cSthurlow otw_len = RNDUP(otw_len); 33927242a7cSthurlow padword = (otw_len / BYTES_PER_XDR_UNIT); /* includes fhlen */ 34027242a7cSthurlow 34127242a7cSthurlow /* 34227242a7cSthurlow * Make sure we don't exceed our buffer. 34327242a7cSthurlow */ 34427242a7cSthurlow if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone) 34527242a7cSthurlow return (FALSE); 34627242a7cSthurlow 34727242a7cSthurlow /* 34827242a7cSthurlow * Zero out the pading. 34927242a7cSthurlow */ 35027242a7cSthurlow ptr[padword] = 0; 35127242a7cSthurlow 35227242a7cSthurlow IXDR_PUT_U_INT32(ptr, otw_len); 35327242a7cSthurlow 35427242a7cSthurlow /* 35527242a7cSthurlow * The rest of the filehandle is in native byteorder 35627242a7cSthurlow */ 35727242a7cSthurlow /* fh3_fsid */ 35827242a7cSthurlow *ptr++ = (uint32_t)fhp->fh3_fsid.val[0]; 35927242a7cSthurlow *ptr++ = (uint32_t)fhp->fh3_fsid.val[1]; 36027242a7cSthurlow 36127242a7cSthurlow /* 36227242a7cSthurlow * Since the next pieces are unaligned, we need to 36327242a7cSthurlow * do bytewise copies. 36427242a7cSthurlow */ 36527242a7cSthurlow cp = (uchar_t *)ptr; 36627242a7cSthurlow 36727242a7cSthurlow /* fh3_len + fh3_data */ 36827242a7cSthurlow bcopy(&fhp->fh3_len, cp, sizeof (fhp->fh3_len) + fsize); 36927242a7cSthurlow cp += sizeof (fhp->fh3_len) + fsize; 37027242a7cSthurlow 37127242a7cSthurlow /* fh3_xlen + fh3_xdata */ 37227242a7cSthurlow bcopy(&fhp->fh3_xlen, cp, sizeof (fhp->fh3_xlen) + xsize); 37327242a7cSthurlow cp += sizeof (fhp->fh3_xlen) + xsize; 37427242a7cSthurlow 37527242a7cSthurlow /* do necessary rounding/padding */ 37627242a7cSthurlow cp = (uchar_t *)RNDUP((uintptr_t)cp); 37727242a7cSthurlow ptr = (uint32_t *)cp; 37827242a7cSthurlow 37927242a7cSthurlow /* 38027242a7cSthurlow * With the above padding, we're word aligned again. 38127242a7cSthurlow */ 38227242a7cSthurlow ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0); 38327242a7cSthurlow 38427242a7cSthurlow *ptrp = ptr; 38527242a7cSthurlow 38627242a7cSthurlow return (TRUE); 38727242a7cSthurlow } 38827242a7cSthurlow 38927242a7cSthurlow static bool_t 39027242a7cSthurlow xdr_encode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp) 39127242a7cSthurlow { 39227242a7cSthurlow uint_t otw_len, fsize, xsize; /* otw, file, and export sizes */ 39327242a7cSthurlow bool_t ret; 39427242a7cSthurlow rpc_inline_t *ptr; 39527242a7cSthurlow rpc_inline_t *buf = NULL; 39627242a7cSthurlow uint32_t *ptr_redzone; 39727242a7cSthurlow 39827242a7cSthurlow ASSERT(xdrs->x_op == XDR_ENCODE); 39927242a7cSthurlow 40027242a7cSthurlow fsize = objp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_len; 40127242a7cSthurlow xsize = objp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_xlen; 40227242a7cSthurlow 40327242a7cSthurlow /* 40427242a7cSthurlow * First get the over the wire size, it is the 4 bytes 40527242a7cSthurlow * for the length, plus the combined size of the 40627242a7cSthurlow * file handle components. 40727242a7cSthurlow */ 40827242a7cSthurlow otw_len = BYTES_PER_XDR_UNIT + sizeof (objp->fh3_fsid) + 40927242a7cSthurlow sizeof (objp->fh3_len) + fsize + 41027242a7cSthurlow sizeof (objp->fh3_xlen) + xsize; 41127242a7cSthurlow /* 41227242a7cSthurlow * Round out to a full word. 41327242a7cSthurlow */ 41427242a7cSthurlow otw_len = RNDUP(otw_len); 41527242a7cSthurlow 41627242a7cSthurlow /* 41727242a7cSthurlow * Next try to inline the XDR stream, if that fails (rare) 41827242a7cSthurlow * allocate a buffer to encode the file handle and then 41927242a7cSthurlow * copy it using xdr_opaque and free the buffer. 42027242a7cSthurlow */ 42127242a7cSthurlow ptr = XDR_INLINE(xdrs, otw_len); 42227242a7cSthurlow if (ptr == NULL) 42327242a7cSthurlow ptr = buf = kmem_alloc(otw_len, KM_SLEEP); 42427242a7cSthurlow 42527242a7cSthurlow ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT)); 42627242a7cSthurlow ret = xdr_inline_encode_nfs_fh3((uint32_t **)&ptr, ptr_redzone, objp); 42727242a7cSthurlow 42827242a7cSthurlow if (buf != NULL) { 42927242a7cSthurlow if (ret == TRUE) 43027242a7cSthurlow ret = xdr_opaque(xdrs, (char *)buf, otw_len); 43127242a7cSthurlow kmem_free(buf, otw_len); 43227242a7cSthurlow } 43327242a7cSthurlow return (ret); 43427242a7cSthurlow } 43527242a7cSthurlow 43627242a7cSthurlow /* 43727242a7cSthurlow * XDR a NFSv3 filehandle the naive way. 43827242a7cSthurlow */ 4397c478bd9Sstevel@tonic-gate bool_t 4407c478bd9Sstevel@tonic-gate xdr_nfs_fh3(XDR *xdrs, nfs_fh3 *objp) 4417c478bd9Sstevel@tonic-gate { 4427c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 4437c478bd9Sstevel@tonic-gate return (TRUE); 4447c478bd9Sstevel@tonic-gate 4457c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->fh3_length)) 4467c478bd9Sstevel@tonic-gate return (FALSE); 4477c478bd9Sstevel@tonic-gate 4487c478bd9Sstevel@tonic-gate if (objp->fh3_length > NFS3_FHSIZE) 4497c478bd9Sstevel@tonic-gate return (FALSE); 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate return (xdr_opaque(xdrs, objp->fh3_u.data, objp->fh3_length)); 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate /* 45527242a7cSthurlow * XDR a NFSv3 filehandle with intelligence on the server. 45627242a7cSthurlow * Encoding goes from our in-memory structure to wire format. 45727242a7cSthurlow * Decoding goes from wire format to our in-memory structure. 4587c478bd9Sstevel@tonic-gate */ 4597c478bd9Sstevel@tonic-gate bool_t 46027242a7cSthurlow xdr_nfs_fh3_server(XDR *xdrs, nfs_fh3 *objp) 4617c478bd9Sstevel@tonic-gate { 46227242a7cSthurlow switch (xdrs->x_op) { 46327242a7cSthurlow case XDR_ENCODE: 4646a8ebdc3Sthurlow if (objp->fh3_flags & FH_WEBNFS) 4656a8ebdc3Sthurlow return (xdr_nfs_fh3(xdrs, objp)); 4666a8ebdc3Sthurlow else 46727242a7cSthurlow return (xdr_encode_nfs_fh3(xdrs, objp)); 46827242a7cSthurlow case XDR_DECODE: 46927242a7cSthurlow return (xdr_decode_nfs_fh3(xdrs, objp)); 47027242a7cSthurlow case XDR_FREE: 47127242a7cSthurlow if (objp->fh3_u.data != NULL) 47227242a7cSthurlow bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data)); 4737c478bd9Sstevel@tonic-gate return (TRUE); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate return (FALSE); 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate bool_t 4797c478bd9Sstevel@tonic-gate xdr_diropargs3(XDR *xdrs, diropargs3 *objp) 4807c478bd9Sstevel@tonic-gate { 48127242a7cSthurlow switch (xdrs->x_op) { 48227242a7cSthurlow case XDR_FREE: 48327242a7cSthurlow case XDR_ENCODE: 4847c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, objp->dirp)) 4857c478bd9Sstevel@tonic-gate return (FALSE); 48627242a7cSthurlow break; 48727242a7cSthurlow case XDR_DECODE: 48827242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->dir)) 48927242a7cSthurlow return (FALSE); 49027242a7cSthurlow break; 49127242a7cSthurlow } 4927c478bd9Sstevel@tonic-gate return (xdr_string3(xdrs, &objp->name, MAXNAMELEN)); 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate static bool_t 4967c478bd9Sstevel@tonic-gate xdr_fattr3(XDR *xdrs, fattr3 *na) 4977c478bd9Sstevel@tonic-gate { 4987c478bd9Sstevel@tonic-gate int32_t *ptr; 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 5017c478bd9Sstevel@tonic-gate return (TRUE); 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT); 5047c478bd9Sstevel@tonic-gate if (ptr != NULL) { 5057c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) { 5067c478bd9Sstevel@tonic-gate na->type = IXDR_GET_ENUM(ptr, enum ftype3); 5077c478bd9Sstevel@tonic-gate na->mode = IXDR_GET_U_INT32(ptr); 5087c478bd9Sstevel@tonic-gate na->nlink = IXDR_GET_U_INT32(ptr); 5097c478bd9Sstevel@tonic-gate na->uid = IXDR_GET_U_INT32(ptr); 5107c478bd9Sstevel@tonic-gate na->gid = IXDR_GET_U_INT32(ptr); 5117c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, na->size); 5127c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, na->used); 5137c478bd9Sstevel@tonic-gate na->rdev.specdata1 = IXDR_GET_U_INT32(ptr); 5147c478bd9Sstevel@tonic-gate na->rdev.specdata2 = IXDR_GET_U_INT32(ptr); 5157c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, na->fsid); 5167c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, na->fileid); 5177c478bd9Sstevel@tonic-gate na->atime.seconds = IXDR_GET_U_INT32(ptr); 5187c478bd9Sstevel@tonic-gate na->atime.nseconds = IXDR_GET_U_INT32(ptr); 5197c478bd9Sstevel@tonic-gate na->mtime.seconds = IXDR_GET_U_INT32(ptr); 5207c478bd9Sstevel@tonic-gate na->mtime.nseconds = IXDR_GET_U_INT32(ptr); 5217c478bd9Sstevel@tonic-gate na->ctime.seconds = IXDR_GET_U_INT32(ptr); 5227c478bd9Sstevel@tonic-gate na->ctime.nseconds = IXDR_GET_U_INT32(ptr); 5237c478bd9Sstevel@tonic-gate } else { 5247c478bd9Sstevel@tonic-gate IXDR_PUT_ENUM(ptr, na->type); 5257c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->mode); 5267c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->nlink); 5277c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->uid); 5287c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->gid); 5297c478bd9Sstevel@tonic-gate IXDR_PUT_U_HYPER(ptr, na->size); 5307c478bd9Sstevel@tonic-gate IXDR_PUT_U_HYPER(ptr, na->used); 5317c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->rdev.specdata1); 5327c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->rdev.specdata2); 5337c478bd9Sstevel@tonic-gate IXDR_PUT_U_HYPER(ptr, na->fsid); 5347c478bd9Sstevel@tonic-gate IXDR_PUT_U_HYPER(ptr, na->fileid); 5357c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->atime.seconds); 5367c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->atime.nseconds); 5377c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->mtime.seconds); 5387c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->mtime.nseconds); 5397c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->ctime.seconds); 5407c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, na->ctime.nseconds); 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate return (TRUE); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate if (!(xdr_enum(xdrs, (enum_t *)&na->type) && 5457c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->mode) && 5467c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->nlink) && 5477c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->uid) && 5487c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->gid) && 5497c478bd9Sstevel@tonic-gate xdr_u_longlong_t(xdrs, &na->size) && 5507c478bd9Sstevel@tonic-gate xdr_u_longlong_t(xdrs, &na->used) && 5517c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->rdev.specdata1) && 5527c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->rdev.specdata2) && 5537c478bd9Sstevel@tonic-gate xdr_u_longlong_t(xdrs, &na->fsid) && 5547c478bd9Sstevel@tonic-gate xdr_u_longlong_t(xdrs, &na->fileid) && 5557c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->atime.seconds) && 5567c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->atime.nseconds) && 5577c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->mtime.seconds) && 5587c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->mtime.nseconds) && 5597c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->ctime.seconds) && 5607c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &na->ctime.nseconds))) 5617c478bd9Sstevel@tonic-gate return (FALSE); 5627c478bd9Sstevel@tonic-gate return (TRUE); 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate /* 5667c478bd9Sstevel@tonic-gate * Fast decode of an fattr3 to a vattr 5677c478bd9Sstevel@tonic-gate * Only return FALSE on decode error, all other fattr to vattr translation 5687c478bd9Sstevel@tonic-gate * failures set status. 5697c478bd9Sstevel@tonic-gate * 5707c478bd9Sstevel@tonic-gate * Callers must catch the following errors: 5717c478bd9Sstevel@tonic-gate * EFBIG - file size will not fit in va_size 5727c478bd9Sstevel@tonic-gate * EOVERFLOW - time will not fit in va_*time 5737c478bd9Sstevel@tonic-gate */ 5747c478bd9Sstevel@tonic-gate static bool_t 5757c478bd9Sstevel@tonic-gate xdr_fattr3_to_vattr(XDR *xdrs, fattr3_res *objp) 5767c478bd9Sstevel@tonic-gate { 5777c478bd9Sstevel@tonic-gate int32_t *ptr; 5787c478bd9Sstevel@tonic-gate size3 used; 5797c478bd9Sstevel@tonic-gate specdata3 rdev; 5807c478bd9Sstevel@tonic-gate uint32_t ntime; 5817c478bd9Sstevel@tonic-gate vattr_t *vap = objp->vap; 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate /* 5847c478bd9Sstevel@tonic-gate * DECODE only 5857c478bd9Sstevel@tonic-gate */ 5867c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_DECODE); 5877c478bd9Sstevel@tonic-gate 5881e96f9d6SRich Brown /* On success, all attributes will be decoded */ 5891e96f9d6SRich Brown vap->va_mask = AT_ALL; 5901e96f9d6SRich Brown 5917c478bd9Sstevel@tonic-gate objp->status = 0; 5927c478bd9Sstevel@tonic-gate ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT); 5937c478bd9Sstevel@tonic-gate if (ptr != NULL) { 5947c478bd9Sstevel@tonic-gate /* 5957c478bd9Sstevel@tonic-gate * Common case 5967c478bd9Sstevel@tonic-gate */ 5977c478bd9Sstevel@tonic-gate vap->va_type = IXDR_GET_ENUM(ptr, enum vtype); 5982c2d21e9SRichard Lowe if ((ftype3)vap->va_type < NF3REG || 5992c2d21e9SRichard Lowe (ftype3)vap->va_type > NF3FIFO) 6007c478bd9Sstevel@tonic-gate vap->va_type = VBAD; 6017c478bd9Sstevel@tonic-gate else 6027c478bd9Sstevel@tonic-gate vap->va_type = nf3_to_vt[vap->va_type]; 6037c478bd9Sstevel@tonic-gate vap->va_mode = IXDR_GET_U_INT32(ptr); 6047c478bd9Sstevel@tonic-gate vap->va_nlink = IXDR_GET_U_INT32(ptr); 6057c478bd9Sstevel@tonic-gate vap->va_uid = (uid_t)IXDR_GET_U_INT32(ptr); 6067c478bd9Sstevel@tonic-gate if (vap->va_uid == NFS_UID_NOBODY) 6077c478bd9Sstevel@tonic-gate vap->va_uid = UID_NOBODY; 6087c478bd9Sstevel@tonic-gate vap->va_gid = (gid_t)IXDR_GET_U_INT32(ptr); 6097c478bd9Sstevel@tonic-gate if (vap->va_gid == NFS_GID_NOBODY) 6107c478bd9Sstevel@tonic-gate vap->va_gid = GID_NOBODY; 6117c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, vap->va_size); 6127c478bd9Sstevel@tonic-gate /* 6137c478bd9Sstevel@tonic-gate * If invalid size, stop decode, set status, and 6147c478bd9Sstevel@tonic-gate * return TRUE, x_handy will be correct, caller must ignore vap. 6157c478bd9Sstevel@tonic-gate */ 6167c478bd9Sstevel@tonic-gate if (!NFS3_SIZE_OK(vap->va_size)) { 6177c478bd9Sstevel@tonic-gate objp->status = EFBIG; 6187c478bd9Sstevel@tonic-gate return (TRUE); 6197c478bd9Sstevel@tonic-gate } 6207c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, used); 6217c478bd9Sstevel@tonic-gate rdev.specdata1 = IXDR_GET_U_INT32(ptr); 6227c478bd9Sstevel@tonic-gate rdev.specdata2 = IXDR_GET_U_INT32(ptr); 6237c478bd9Sstevel@tonic-gate /* fsid is ignored */ 6247c478bd9Sstevel@tonic-gate ptr += 2; 6257c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, vap->va_nodeid); 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate /* 6287c478bd9Sstevel@tonic-gate * nfs protocol defines times as unsigned so don't 6297c478bd9Sstevel@tonic-gate * extend sign, unless sysadmin set nfs_allow_preepoch_time. 6307c478bd9Sstevel@tonic-gate * The inline macros do the equivilant of NFS_TIME_T_CONVERT 6317c478bd9Sstevel@tonic-gate */ 6327c478bd9Sstevel@tonic-gate if (nfs_allow_preepoch_time) { 6337c478bd9Sstevel@tonic-gate vap->va_atime.tv_sec = IXDR_GET_INT32(ptr); 6347c478bd9Sstevel@tonic-gate vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr); 6357c478bd9Sstevel@tonic-gate vap->va_mtime.tv_sec = IXDR_GET_INT32(ptr); 6367c478bd9Sstevel@tonic-gate vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr); 6377c478bd9Sstevel@tonic-gate vap->va_ctime.tv_sec = IXDR_GET_INT32(ptr); 6387c478bd9Sstevel@tonic-gate vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr); 6397c478bd9Sstevel@tonic-gate } else { 6407c478bd9Sstevel@tonic-gate /* 6417c478bd9Sstevel@tonic-gate * Check if the time would overflow on 32-bit 6427c478bd9Sstevel@tonic-gate */ 6437c478bd9Sstevel@tonic-gate ntime = IXDR_GET_U_INT32(ptr); 6447c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 6457c478bd9Sstevel@tonic-gate if (NFS3_TIME_OVERFLOW(ntime)) { 6467c478bd9Sstevel@tonic-gate objp->status = EOVERFLOW; 6477c478bd9Sstevel@tonic-gate return (TRUE); 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate vap->va_atime.tv_sec = ntime; 6507c478bd9Sstevel@tonic-gate vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr); 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate ntime = IXDR_GET_U_INT32(ptr); 6537c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 6547c478bd9Sstevel@tonic-gate if (NFS3_TIME_OVERFLOW(ntime)) { 6557c478bd9Sstevel@tonic-gate objp->status = EOVERFLOW; 6567c478bd9Sstevel@tonic-gate return (TRUE); 6577c478bd9Sstevel@tonic-gate } 6587c478bd9Sstevel@tonic-gate vap->va_mtime.tv_sec = ntime; 6597c478bd9Sstevel@tonic-gate vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr); 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate ntime = IXDR_GET_U_INT32(ptr); 6627c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 6637c478bd9Sstevel@tonic-gate if (NFS3_TIME_OVERFLOW(ntime)) { 6647c478bd9Sstevel@tonic-gate objp->status = EOVERFLOW; 6657c478bd9Sstevel@tonic-gate return (TRUE); 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate vap->va_ctime.tv_sec = ntime; 6687c478bd9Sstevel@tonic-gate vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate } else { 6727c478bd9Sstevel@tonic-gate uint64 fsid; 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate /* 6757c478bd9Sstevel@tonic-gate * Slow path 6767c478bd9Sstevel@tonic-gate */ 6777c478bd9Sstevel@tonic-gate if (!(xdr_enum(xdrs, (enum_t *)&vap->va_type) && 6787c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &vap->va_mode) && 6797c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &vap->va_nlink) && 6807c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, (uint_t *)&vap->va_uid) && 6817c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, (uint_t *)&vap->va_gid) && 6827c478bd9Sstevel@tonic-gate xdr_u_longlong_t(xdrs, &vap->va_size) && 6837c478bd9Sstevel@tonic-gate xdr_u_longlong_t(xdrs, &used) && 6847c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &rdev.specdata1) && 6857c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &rdev.specdata2) && 6867c478bd9Sstevel@tonic-gate xdr_u_longlong_t(xdrs, &fsid) && /* ignored */ 6877c478bd9Sstevel@tonic-gate xdr_u_longlong_t(xdrs, &vap->va_nodeid))) 6887c478bd9Sstevel@tonic-gate return (FALSE); 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate if (nfs_allow_preepoch_time) { 6917c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 6927c478bd9Sstevel@tonic-gate return (FALSE); 6937c478bd9Sstevel@tonic-gate vap->va_atime.tv_sec = (int32_t)ntime; 6947c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 6957c478bd9Sstevel@tonic-gate return (FALSE); 6967c478bd9Sstevel@tonic-gate vap->va_atime.tv_nsec = ntime; 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 6997c478bd9Sstevel@tonic-gate return (FALSE); 7007c478bd9Sstevel@tonic-gate vap->va_mtime.tv_sec = (int32_t)ntime; 7017c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 7027c478bd9Sstevel@tonic-gate return (FALSE); 7037c478bd9Sstevel@tonic-gate vap->va_mtime.tv_nsec = ntime; 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 7067c478bd9Sstevel@tonic-gate return (FALSE); 7077c478bd9Sstevel@tonic-gate vap->va_ctime.tv_sec = (int32_t)ntime; 7087c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 7097c478bd9Sstevel@tonic-gate return (FALSE); 7107c478bd9Sstevel@tonic-gate vap->va_ctime.tv_nsec = ntime; 7117c478bd9Sstevel@tonic-gate } else { 7127c478bd9Sstevel@tonic-gate /* 7137c478bd9Sstevel@tonic-gate * Check if the time would overflow on 32-bit 7147c478bd9Sstevel@tonic-gate * Set status and keep decoding stream. 7157c478bd9Sstevel@tonic-gate */ 7167c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 7177c478bd9Sstevel@tonic-gate return (FALSE); 7187c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 7197c478bd9Sstevel@tonic-gate if (NFS3_TIME_OVERFLOW(ntime)) { 7207c478bd9Sstevel@tonic-gate objp->status = EOVERFLOW; 7217c478bd9Sstevel@tonic-gate } 7227c478bd9Sstevel@tonic-gate vap->va_atime.tv_sec = ntime; 7237c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 7247c478bd9Sstevel@tonic-gate return (FALSE); 7257c478bd9Sstevel@tonic-gate vap->va_atime.tv_nsec = ntime; 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 7287c478bd9Sstevel@tonic-gate return (FALSE); 7297c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 7307c478bd9Sstevel@tonic-gate if (NFS3_TIME_OVERFLOW(ntime)) { 7317c478bd9Sstevel@tonic-gate objp->status = EOVERFLOW; 7327c478bd9Sstevel@tonic-gate } 7337c478bd9Sstevel@tonic-gate vap->va_mtime.tv_sec = ntime; 7347c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 7357c478bd9Sstevel@tonic-gate return (FALSE); 7367c478bd9Sstevel@tonic-gate vap->va_mtime.tv_nsec = ntime; 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 7397c478bd9Sstevel@tonic-gate return (FALSE); 7407c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 7417c478bd9Sstevel@tonic-gate if (NFS3_TIME_OVERFLOW(ntime)) { 7427c478bd9Sstevel@tonic-gate objp->status = EOVERFLOW; 7437c478bd9Sstevel@tonic-gate } 7447c478bd9Sstevel@tonic-gate vap->va_ctime.tv_sec = ntime; 7457c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &ntime)) 7467c478bd9Sstevel@tonic-gate return (FALSE); 7477c478bd9Sstevel@tonic-gate vap->va_ctime.tv_nsec = ntime; 7487c478bd9Sstevel@tonic-gate } 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate /* 7517c478bd9Sstevel@tonic-gate * Fixup as needed 7527c478bd9Sstevel@tonic-gate */ 7532c2d21e9SRichard Lowe if ((ftype3)vap->va_type < NF3REG || 7542c2d21e9SRichard Lowe (ftype3)vap->va_type > NF3FIFO) 7557c478bd9Sstevel@tonic-gate vap->va_type = VBAD; 7567c478bd9Sstevel@tonic-gate else 7577c478bd9Sstevel@tonic-gate vap->va_type = nf3_to_vt[vap->va_type]; 7587c478bd9Sstevel@tonic-gate if (vap->va_uid == NFS_UID_NOBODY) 7597c478bd9Sstevel@tonic-gate vap->va_uid = UID_NOBODY; 7607c478bd9Sstevel@tonic-gate if (vap->va_gid == NFS_GID_NOBODY) 7617c478bd9Sstevel@tonic-gate vap->va_gid = GID_NOBODY; 7627c478bd9Sstevel@tonic-gate /* 7637c478bd9Sstevel@tonic-gate * If invalid size, set status, and 7647c478bd9Sstevel@tonic-gate * return TRUE, caller must ignore vap. 7657c478bd9Sstevel@tonic-gate */ 7667c478bd9Sstevel@tonic-gate if (!NFS3_SIZE_OK(vap->va_size)) { 7677c478bd9Sstevel@tonic-gate objp->status = EFBIG; 7687c478bd9Sstevel@tonic-gate return (TRUE); 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate } 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate /* 7737c478bd9Sstevel@tonic-gate * Fill in derived fields 7747c478bd9Sstevel@tonic-gate */ 7757c478bd9Sstevel@tonic-gate vap->va_fsid = objp->vp->v_vfsp->vfs_dev; 7767c478bd9Sstevel@tonic-gate vap->va_seq = 0; 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate /* 7797c478bd9Sstevel@tonic-gate * Common case values 7807c478bd9Sstevel@tonic-gate */ 7817c478bd9Sstevel@tonic-gate vap->va_rdev = 0; 7827c478bd9Sstevel@tonic-gate vap->va_blksize = MAXBSIZE; 7837c478bd9Sstevel@tonic-gate vap->va_nblocks = 0; 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate switch (vap->va_type) { 7867c478bd9Sstevel@tonic-gate case VREG: 7877c478bd9Sstevel@tonic-gate case VDIR: 7887c478bd9Sstevel@tonic-gate case VLNK: 7897c478bd9Sstevel@tonic-gate vap->va_nblocks = (u_longlong_t) 7907c478bd9Sstevel@tonic-gate ((used + (size3)DEV_BSIZE - (size3)1) / 7917c478bd9Sstevel@tonic-gate (size3)DEV_BSIZE); 7927c478bd9Sstevel@tonic-gate break; 7937c478bd9Sstevel@tonic-gate case VBLK: 7947c478bd9Sstevel@tonic-gate vap->va_blksize = DEV_BSIZE; 7957c478bd9Sstevel@tonic-gate /* FALLTHRU */ 7967c478bd9Sstevel@tonic-gate case VCHR: 7977c478bd9Sstevel@tonic-gate vap->va_rdev = makedevice(rdev.specdata1, rdev.specdata2); 7987c478bd9Sstevel@tonic-gate break; 7997c478bd9Sstevel@tonic-gate case VSOCK: 8007c478bd9Sstevel@tonic-gate case VFIFO: 8017c478bd9Sstevel@tonic-gate default: 8027c478bd9Sstevel@tonic-gate break; 8037c478bd9Sstevel@tonic-gate } 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate return (TRUE); 8067c478bd9Sstevel@tonic-gate } 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate static bool_t 8097c478bd9Sstevel@tonic-gate xdr_post_op_vattr(XDR *xdrs, post_op_vattr *objp) 8107c478bd9Sstevel@tonic-gate { 8117c478bd9Sstevel@tonic-gate /* 8127c478bd9Sstevel@tonic-gate * DECODE only 8137c478bd9Sstevel@tonic-gate */ 8147c478bd9Sstevel@tonic-gate ASSERT(xdrs->x_op == XDR_DECODE); 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->attributes)) 8177c478bd9Sstevel@tonic-gate return (FALSE); 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate if (objp->attributes == FALSE) 8207c478bd9Sstevel@tonic-gate return (TRUE); 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate if (objp->attributes != TRUE) 8237c478bd9Sstevel@tonic-gate return (FALSE); 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate if (!xdr_fattr3_to_vattr(xdrs, &objp->fres)) 8267c478bd9Sstevel@tonic-gate return (FALSE); 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate /* 8297c478bd9Sstevel@tonic-gate * The file size may cause an EFBIG or the time values 8307c478bd9Sstevel@tonic-gate * may cause EOVERFLOW, if so simply drop the attributes. 8317c478bd9Sstevel@tonic-gate */ 8327c478bd9Sstevel@tonic-gate if (objp->fres.status != NFS3_OK) 8337c478bd9Sstevel@tonic-gate objp->attributes = FALSE; 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gate return (TRUE); 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate bool_t 8397c478bd9Sstevel@tonic-gate xdr_post_op_attr(XDR *xdrs, post_op_attr *objp) 8407c478bd9Sstevel@tonic-gate { 8417c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->attributes)) 8427c478bd9Sstevel@tonic-gate return (FALSE); 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate if (objp->attributes == FALSE) 8457c478bd9Sstevel@tonic-gate return (TRUE); 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate if (objp->attributes != TRUE) 8487c478bd9Sstevel@tonic-gate return (FALSE); 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate if (!xdr_fattr3(xdrs, &objp->attr)) 8517c478bd9Sstevel@tonic-gate return (FALSE); 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate /* 8547c478bd9Sstevel@tonic-gate * Check that we don't get a file we can't handle through 8557c478bd9Sstevel@tonic-gate * existing interfaces (especially stat64()). 8567c478bd9Sstevel@tonic-gate * Decode only check since on encode the data has 8577c478bd9Sstevel@tonic-gate * been dealt with in the above call to xdr_fattr3(). 8587c478bd9Sstevel@tonic-gate */ 8597c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) { 8607c478bd9Sstevel@tonic-gate /* Set attrs to false if invalid size or time */ 8617c478bd9Sstevel@tonic-gate if (!NFS3_SIZE_OK(objp->attr.size)) { 8627c478bd9Sstevel@tonic-gate objp->attributes = FALSE; 8637c478bd9Sstevel@tonic-gate return (TRUE); 8647c478bd9Sstevel@tonic-gate } 8657c478bd9Sstevel@tonic-gate #ifndef _LP64 8667c478bd9Sstevel@tonic-gate if (!NFS3_FATTR_TIME_OK(&objp->attr)) 8677c478bd9Sstevel@tonic-gate objp->attributes = FALSE; 8687c478bd9Sstevel@tonic-gate #endif 8697c478bd9Sstevel@tonic-gate } 8707c478bd9Sstevel@tonic-gate return (TRUE); 8717c478bd9Sstevel@tonic-gate } 8727c478bd9Sstevel@tonic-gate 8737c478bd9Sstevel@tonic-gate static bool_t 8747c478bd9Sstevel@tonic-gate xdr_wcc_data(XDR *xdrs, wcc_data *objp) 8757c478bd9Sstevel@tonic-gate { 8767c478bd9Sstevel@tonic-gate int32_t *ptr; 8777c478bd9Sstevel@tonic-gate wcc_attr *attrp; 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 8807c478bd9Sstevel@tonic-gate return (TRUE); 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) { 8837c478bd9Sstevel@tonic-gate /* pre_op_attr */ 8847c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->before.attributes)) 8857c478bd9Sstevel@tonic-gate return (FALSE); 8867c478bd9Sstevel@tonic-gate 8877c478bd9Sstevel@tonic-gate switch (objp->before.attributes) { 8887c478bd9Sstevel@tonic-gate case TRUE: 8897c478bd9Sstevel@tonic-gate attrp = &objp->before.attr; 8907c478bd9Sstevel@tonic-gate ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT); 8917c478bd9Sstevel@tonic-gate if (ptr != NULL) { 8927c478bd9Sstevel@tonic-gate IXDR_GET_U_HYPER(ptr, attrp->size); 8937c478bd9Sstevel@tonic-gate attrp->mtime.seconds = IXDR_GET_U_INT32(ptr); 8947c478bd9Sstevel@tonic-gate attrp->mtime.nseconds = IXDR_GET_U_INT32(ptr); 8957c478bd9Sstevel@tonic-gate attrp->ctime.seconds = IXDR_GET_U_INT32(ptr); 8967c478bd9Sstevel@tonic-gate attrp->ctime.nseconds = IXDR_GET_U_INT32(ptr); 8977c478bd9Sstevel@tonic-gate } else { 8987c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &attrp->size)) 8997c478bd9Sstevel@tonic-gate return (FALSE); 9007c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &attrp->mtime.seconds)) 9017c478bd9Sstevel@tonic-gate return (FALSE); 9027c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &attrp->mtime.nseconds)) 9037c478bd9Sstevel@tonic-gate return (FALSE); 9047c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &attrp->ctime.seconds)) 9057c478bd9Sstevel@tonic-gate return (FALSE); 9067c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &attrp->ctime.nseconds)) 9077c478bd9Sstevel@tonic-gate return (FALSE); 9087c478bd9Sstevel@tonic-gate } 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate #ifndef _LP64 9117c478bd9Sstevel@tonic-gate /* 9127c478bd9Sstevel@tonic-gate * check time overflow. 9137c478bd9Sstevel@tonic-gate */ 9147c478bd9Sstevel@tonic-gate if (!NFS3_TIME_OK(attrp->mtime.seconds) || 9157c478bd9Sstevel@tonic-gate !NFS3_TIME_OK(attrp->ctime.seconds)) 9167c478bd9Sstevel@tonic-gate objp->before.attributes = FALSE; 9177c478bd9Sstevel@tonic-gate #endif 9187c478bd9Sstevel@tonic-gate break; 9197c478bd9Sstevel@tonic-gate case FALSE: 9207c478bd9Sstevel@tonic-gate break; 9217c478bd9Sstevel@tonic-gate default: 9227c478bd9Sstevel@tonic-gate return (FALSE); 9237c478bd9Sstevel@tonic-gate } 9247c478bd9Sstevel@tonic-gate } 9257c478bd9Sstevel@tonic-gate 9267c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 9277c478bd9Sstevel@tonic-gate /* pre_op_attr */ 9287c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->before.attributes)) 9297c478bd9Sstevel@tonic-gate return (FALSE); 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate switch (objp->before.attributes) { 9327c478bd9Sstevel@tonic-gate case TRUE: 9337c478bd9Sstevel@tonic-gate attrp = &objp->before.attr; 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT); 9367c478bd9Sstevel@tonic-gate if (ptr != NULL) { 9377c478bd9Sstevel@tonic-gate IXDR_PUT_U_HYPER(ptr, attrp->size); 9387c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, attrp->mtime.seconds); 9397c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, attrp->mtime.nseconds); 9407c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, attrp->ctime.seconds); 9417c478bd9Sstevel@tonic-gate IXDR_PUT_U_INT32(ptr, attrp->ctime.nseconds); 9427c478bd9Sstevel@tonic-gate } else { 9437c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &attrp->size)) 9447c478bd9Sstevel@tonic-gate return (FALSE); 9457c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &attrp->mtime.seconds)) 9467c478bd9Sstevel@tonic-gate return (FALSE); 9477c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &attrp->mtime.nseconds)) 9487c478bd9Sstevel@tonic-gate return (FALSE); 9497c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &attrp->ctime.seconds)) 9507c478bd9Sstevel@tonic-gate return (FALSE); 9517c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &attrp->ctime.nseconds)) 9527c478bd9Sstevel@tonic-gate return (FALSE); 9537c478bd9Sstevel@tonic-gate } 9547c478bd9Sstevel@tonic-gate break; 9557c478bd9Sstevel@tonic-gate case FALSE: 9567c478bd9Sstevel@tonic-gate break; 9577c478bd9Sstevel@tonic-gate default: 9587c478bd9Sstevel@tonic-gate return (FALSE); 9597c478bd9Sstevel@tonic-gate } 9607c478bd9Sstevel@tonic-gate } 9617c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &objp->after)); 9627c478bd9Sstevel@tonic-gate } 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate bool_t 9657c478bd9Sstevel@tonic-gate xdr_post_op_fh3(XDR *xdrs, post_op_fh3 *objp) 9667c478bd9Sstevel@tonic-gate { 9677c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->handle_follows)) 9687c478bd9Sstevel@tonic-gate return (FALSE); 9697c478bd9Sstevel@tonic-gate switch (objp->handle_follows) { 9707c478bd9Sstevel@tonic-gate case TRUE: 97127242a7cSthurlow switch (xdrs->x_op) { 97227242a7cSthurlow case XDR_ENCODE: 97327242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->handle)) 97427242a7cSthurlow return (FALSE); 97527242a7cSthurlow break; 97627242a7cSthurlow case XDR_FREE: 97727242a7cSthurlow case XDR_DECODE: 97827242a7cSthurlow if (!xdr_nfs_fh3(xdrs, &objp->handle)) 97927242a7cSthurlow return (FALSE); 98027242a7cSthurlow break; 98127242a7cSthurlow } 98227242a7cSthurlow return (TRUE); 9837c478bd9Sstevel@tonic-gate case FALSE: 9847c478bd9Sstevel@tonic-gate return (TRUE); 9857c478bd9Sstevel@tonic-gate default: 9867c478bd9Sstevel@tonic-gate return (FALSE); 9877c478bd9Sstevel@tonic-gate } 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate static bool_t 9917c478bd9Sstevel@tonic-gate xdr_sattr3(XDR *xdrs, sattr3 *objp) 9927c478bd9Sstevel@tonic-gate { 9937c478bd9Sstevel@tonic-gate /* set_mode3 */ 9947c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->mode.set_it)) 9957c478bd9Sstevel@tonic-gate return (FALSE); 9967c478bd9Sstevel@tonic-gate if (objp->mode.set_it) 9977c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->mode.mode)) 9987c478bd9Sstevel@tonic-gate return (FALSE); 9997c478bd9Sstevel@tonic-gate /* set_uid3 */ 10007c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->uid.set_it)) 10017c478bd9Sstevel@tonic-gate return (FALSE); 10027c478bd9Sstevel@tonic-gate if (objp->uid.set_it) 10037c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->uid.uid)) 10047c478bd9Sstevel@tonic-gate return (FALSE); 10057c478bd9Sstevel@tonic-gate /* set_gid3 */ 10067c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->gid.set_it)) 10077c478bd9Sstevel@tonic-gate return (FALSE); 10087c478bd9Sstevel@tonic-gate if (objp->gid.set_it) 10097c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->gid.gid)) 10107c478bd9Sstevel@tonic-gate return (FALSE); 10117c478bd9Sstevel@tonic-gate 10127c478bd9Sstevel@tonic-gate /* set_size3 */ 10137c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->size.set_it)) 10147c478bd9Sstevel@tonic-gate return (FALSE); 10157c478bd9Sstevel@tonic-gate if (objp->size.set_it) 10167c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->size.size)) 10177c478bd9Sstevel@tonic-gate return (FALSE); 10187c478bd9Sstevel@tonic-gate 10197c478bd9Sstevel@tonic-gate /* set_atime */ 10207c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->atime.set_it)) 10217c478bd9Sstevel@tonic-gate return (FALSE); 10227c478bd9Sstevel@tonic-gate if (objp->atime.set_it == SET_TO_CLIENT_TIME) { 10237c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->atime.atime.seconds)) 10247c478bd9Sstevel@tonic-gate return (FALSE); 10257c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->atime.atime.nseconds)) 10267c478bd9Sstevel@tonic-gate return (FALSE); 10277c478bd9Sstevel@tonic-gate } 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate /* set_mtime */ 10307c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->mtime.set_it)) 10317c478bd9Sstevel@tonic-gate return (FALSE); 10327c478bd9Sstevel@tonic-gate if (objp->mtime.set_it == SET_TO_CLIENT_TIME) { 10337c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->mtime.mtime.seconds)) 10347c478bd9Sstevel@tonic-gate return (FALSE); 10357c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->mtime.mtime.nseconds)) 10367c478bd9Sstevel@tonic-gate return (FALSE); 10377c478bd9Sstevel@tonic-gate } 10387c478bd9Sstevel@tonic-gate 10397c478bd9Sstevel@tonic-gate return (TRUE); 10407c478bd9Sstevel@tonic-gate } 10417c478bd9Sstevel@tonic-gate 10427c478bd9Sstevel@tonic-gate bool_t 10437c478bd9Sstevel@tonic-gate xdr_GETATTR3res(XDR *xdrs, GETATTR3res *objp) 10447c478bd9Sstevel@tonic-gate { 10457c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 10467c478bd9Sstevel@tonic-gate return (FALSE); 10477c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 10487c478bd9Sstevel@tonic-gate return (TRUE); 10497c478bd9Sstevel@tonic-gate /* xdr_GETATTR3resok */ 10507c478bd9Sstevel@tonic-gate return (xdr_fattr3(xdrs, &objp->resok.obj_attributes)); 10517c478bd9Sstevel@tonic-gate } 10527c478bd9Sstevel@tonic-gate 10537c478bd9Sstevel@tonic-gate bool_t 10547c478bd9Sstevel@tonic-gate xdr_GETATTR3vres(XDR *xdrs, GETATTR3vres *objp) 10557c478bd9Sstevel@tonic-gate { 10567c478bd9Sstevel@tonic-gate /* 10577c478bd9Sstevel@tonic-gate * DECODE or FREE only 10587c478bd9Sstevel@tonic-gate */ 10597c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 10607c478bd9Sstevel@tonic-gate return (TRUE); 10617c478bd9Sstevel@tonic-gate 10627c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_DECODE) 10637c478bd9Sstevel@tonic-gate return (FALSE); 10647c478bd9Sstevel@tonic-gate 10657c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 10667c478bd9Sstevel@tonic-gate return (FALSE); 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 10697c478bd9Sstevel@tonic-gate return (TRUE); 10707c478bd9Sstevel@tonic-gate 10717c478bd9Sstevel@tonic-gate return (xdr_fattr3_to_vattr(xdrs, &objp->fres)); 10727c478bd9Sstevel@tonic-gate } 10737c478bd9Sstevel@tonic-gate 10747c478bd9Sstevel@tonic-gate 10757c478bd9Sstevel@tonic-gate bool_t 10767c478bd9Sstevel@tonic-gate xdr_SETATTR3args(XDR *xdrs, SETATTR3args *objp) 10777c478bd9Sstevel@tonic-gate { 107827242a7cSthurlow switch (xdrs->x_op) { 107927242a7cSthurlow case XDR_FREE: 108027242a7cSthurlow case XDR_ENCODE: 10817c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &objp->object)) 10827c478bd9Sstevel@tonic-gate return (FALSE); 108327242a7cSthurlow break; 108427242a7cSthurlow case XDR_DECODE: 108527242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->object)) 108627242a7cSthurlow return (FALSE); 108727242a7cSthurlow break; 108827242a7cSthurlow } 10897c478bd9Sstevel@tonic-gate if (!xdr_sattr3(xdrs, &objp->new_attributes)) 10907c478bd9Sstevel@tonic-gate return (FALSE); 10917c478bd9Sstevel@tonic-gate 10927c478bd9Sstevel@tonic-gate /* sattrguard3 */ 10937c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->guard.check)) 10947c478bd9Sstevel@tonic-gate return (FALSE); 10957c478bd9Sstevel@tonic-gate switch (objp->guard.check) { 10967c478bd9Sstevel@tonic-gate case TRUE: 10977c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->guard.obj_ctime.seconds)) 10987c478bd9Sstevel@tonic-gate return (FALSE); 10997c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->guard.obj_ctime.nseconds)); 11007c478bd9Sstevel@tonic-gate case FALSE: 11017c478bd9Sstevel@tonic-gate return (TRUE); 11027c478bd9Sstevel@tonic-gate default: 11037c478bd9Sstevel@tonic-gate return (FALSE); 11047c478bd9Sstevel@tonic-gate } 11057c478bd9Sstevel@tonic-gate } 11067c478bd9Sstevel@tonic-gate 11077c478bd9Sstevel@tonic-gate bool_t 11087c478bd9Sstevel@tonic-gate xdr_SETATTR3res(XDR *xdrs, SETATTR3res *objp) 11097c478bd9Sstevel@tonic-gate { 11107c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 11117c478bd9Sstevel@tonic-gate return (FALSE); 11127c478bd9Sstevel@tonic-gate switch (objp->status) { 11137c478bd9Sstevel@tonic-gate case NFS3_OK: 11147c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resok.obj_wcc)); 11157c478bd9Sstevel@tonic-gate default: 11167c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resfail.obj_wcc)); 11177c478bd9Sstevel@tonic-gate } 11187c478bd9Sstevel@tonic-gate } 11197c478bd9Sstevel@tonic-gate 11207c478bd9Sstevel@tonic-gate bool_t 11217c478bd9Sstevel@tonic-gate xdr_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp) 11227c478bd9Sstevel@tonic-gate { 11237c478bd9Sstevel@tonic-gate LOOKUP3resok *resokp; 11247c478bd9Sstevel@tonic-gate 11257c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 11267c478bd9Sstevel@tonic-gate return (FALSE); 11277c478bd9Sstevel@tonic-gate 11287c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 11297c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes)); 11307c478bd9Sstevel@tonic-gate 11317c478bd9Sstevel@tonic-gate /* xdr_LOOKUP3resok */ 11327c478bd9Sstevel@tonic-gate resokp = &objp->resok; 113327242a7cSthurlow switch (xdrs->x_op) { 113427242a7cSthurlow case XDR_ENCODE: 113527242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &resokp->object)) 113627242a7cSthurlow return (FALSE); 113727242a7cSthurlow break; 113827242a7cSthurlow case XDR_FREE: 113927242a7cSthurlow case XDR_DECODE: 11407c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &resokp->object)) 11417c478bd9Sstevel@tonic-gate return (FALSE); 114227242a7cSthurlow break; 114327242a7cSthurlow } 11447c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes)) 11457c478bd9Sstevel@tonic-gate return (FALSE); 11467c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &resokp->dir_attributes)); 11477c478bd9Sstevel@tonic-gate } 11487c478bd9Sstevel@tonic-gate 11497c478bd9Sstevel@tonic-gate bool_t 11507c478bd9Sstevel@tonic-gate xdr_LOOKUP3vres(XDR *xdrs, LOOKUP3vres *objp) 11517c478bd9Sstevel@tonic-gate { 11527c478bd9Sstevel@tonic-gate /* 11537c478bd9Sstevel@tonic-gate * DECODE or FREE only 11547c478bd9Sstevel@tonic-gate */ 11557c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 11567c478bd9Sstevel@tonic-gate return (TRUE); 11577c478bd9Sstevel@tonic-gate 11587c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_DECODE) 11597c478bd9Sstevel@tonic-gate return (FALSE); 11607c478bd9Sstevel@tonic-gate 11617c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 11627c478bd9Sstevel@tonic-gate return (FALSE); 11637c478bd9Sstevel@tonic-gate 11647c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 11657c478bd9Sstevel@tonic-gate return (xdr_post_op_vattr(xdrs, &objp->dir_attributes)); 11667c478bd9Sstevel@tonic-gate 11677c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &objp->object)) 11687c478bd9Sstevel@tonic-gate return (FALSE); 11697c478bd9Sstevel@tonic-gate if (!xdr_post_op_vattr(xdrs, &objp->obj_attributes)) 11707c478bd9Sstevel@tonic-gate return (FALSE); 11717c478bd9Sstevel@tonic-gate return (xdr_post_op_vattr(xdrs, &objp->dir_attributes)); 11727c478bd9Sstevel@tonic-gate } 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate bool_t 11757c478bd9Sstevel@tonic-gate xdr_ACCESS3args(XDR *xdrs, ACCESS3args *objp) 11767c478bd9Sstevel@tonic-gate { 117727242a7cSthurlow switch (xdrs->x_op) { 117827242a7cSthurlow case XDR_FREE: 117927242a7cSthurlow case XDR_ENCODE: 11807c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &objp->object)) 11817c478bd9Sstevel@tonic-gate return (FALSE); 118227242a7cSthurlow break; 118327242a7cSthurlow case XDR_DECODE: 118427242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->object)) 118527242a7cSthurlow return (FALSE); 118627242a7cSthurlow break; 118727242a7cSthurlow } 11887c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->access)); 11897c478bd9Sstevel@tonic-gate } 11907c478bd9Sstevel@tonic-gate 11917c478bd9Sstevel@tonic-gate 11927c478bd9Sstevel@tonic-gate bool_t 11937c478bd9Sstevel@tonic-gate xdr_ACCESS3res(XDR *xdrs, ACCESS3res *objp) 11947c478bd9Sstevel@tonic-gate { 11957c478bd9Sstevel@tonic-gate ACCESS3resok *resokp; 11967c478bd9Sstevel@tonic-gate 11977c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 11987c478bd9Sstevel@tonic-gate return (FALSE); 11997c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 12007c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes)); 12017c478bd9Sstevel@tonic-gate 12027c478bd9Sstevel@tonic-gate /* xdr_ACCESS3resok */ 12037c478bd9Sstevel@tonic-gate resokp = &objp->resok; 12047c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes)) 12057c478bd9Sstevel@tonic-gate return (FALSE); 12067c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &resokp->access)); 12077c478bd9Sstevel@tonic-gate } 12087c478bd9Sstevel@tonic-gate 12097c478bd9Sstevel@tonic-gate bool_t 12100a701b1eSRobert Gordon xdr_READLINK3args(XDR *xdrs, READLINK3args *objp) 12110a701b1eSRobert Gordon { 12120a701b1eSRobert Gordon rdma_chunkinfo_t rci; 12130a701b1eSRobert Gordon struct xdr_ops *xops = xdrrdma_xops(); 12140a701b1eSRobert Gordon 12150a701b1eSRobert Gordon if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) && 12160a701b1eSRobert Gordon xdrs->x_op == XDR_ENCODE) { 12170a701b1eSRobert Gordon rci.rci_type = RCI_REPLY_CHUNK; 12180a701b1eSRobert Gordon rci.rci_len = MAXPATHLEN; 12190a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci); 12200a701b1eSRobert Gordon } 12210a701b1eSRobert Gordon if (!xdr_nfs_fh3(xdrs, (nfs_fh3 *)objp)) 12220a701b1eSRobert Gordon return (FALSE); 12230a701b1eSRobert Gordon return (TRUE); 12240a701b1eSRobert Gordon } 12250a701b1eSRobert Gordon 12260a701b1eSRobert Gordon bool_t 12277c478bd9Sstevel@tonic-gate xdr_READLINK3res(XDR *xdrs, READLINK3res *objp) 12287c478bd9Sstevel@tonic-gate { 12297c478bd9Sstevel@tonic-gate 12307c478bd9Sstevel@tonic-gate READLINK3resok *resokp; 12317c478bd9Sstevel@tonic-gate 12327c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 12337c478bd9Sstevel@tonic-gate return (FALSE); 12347c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 12357c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, 12367c478bd9Sstevel@tonic-gate &objp->resfail.symlink_attributes)); 12377c478bd9Sstevel@tonic-gate 12387c478bd9Sstevel@tonic-gate /* xdr_READLINK3resok */ 12397c478bd9Sstevel@tonic-gate resokp = &objp->resok; 12407c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->symlink_attributes)) 12417c478bd9Sstevel@tonic-gate return (FALSE); 12427c478bd9Sstevel@tonic-gate return (xdr_string3(xdrs, &resokp->data, MAXPATHLEN)); 12437c478bd9Sstevel@tonic-gate } 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate bool_t 12467c478bd9Sstevel@tonic-gate xdr_READ3args(XDR *xdrs, READ3args *objp) 12477c478bd9Sstevel@tonic-gate { 12480a701b1eSRobert Gordon rdma_chunkinfo_t rci; 12490a701b1eSRobert Gordon rdma_wlist_conn_info_t rwci; 12500a701b1eSRobert Gordon struct xdr_ops *xops = xdrrdma_xops(); 12510a701b1eSRobert Gordon 125227242a7cSthurlow switch (xdrs->x_op) { 125327242a7cSthurlow case XDR_FREE: 125427242a7cSthurlow case XDR_ENCODE: 12557c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &objp->file)) 12567c478bd9Sstevel@tonic-gate return (FALSE); 125727242a7cSthurlow break; 125827242a7cSthurlow case XDR_DECODE: 125927242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->file)) 126027242a7cSthurlow return (FALSE); 126127242a7cSthurlow break; 126227242a7cSthurlow } 12637c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->offset)) 12647c478bd9Sstevel@tonic-gate return (FALSE); 12650a701b1eSRobert Gordon if (!xdr_u_int(xdrs, &objp->count)) 12660a701b1eSRobert Gordon return (FALSE); 12670a701b1eSRobert Gordon 12680a701b1eSRobert Gordon DTRACE_PROBE1(xdr__i__read3_buf_len, int, objp->count); 12690a701b1eSRobert Gordon 12700a701b1eSRobert Gordon objp->wlist = NULL; 12710a701b1eSRobert Gordon 12720a701b1eSRobert Gordon /* if xdrrdma_sizeof in progress, then store the size */ 12730a701b1eSRobert Gordon if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) { 12740a701b1eSRobert Gordon rci.rci_type = RCI_WRITE_ADDR_CHUNK; 12750a701b1eSRobert Gordon rci.rci_len = objp->count; 12760a701b1eSRobert Gordon (void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci); 12770a701b1eSRobert Gordon } 12780a701b1eSRobert Gordon 12790a701b1eSRobert Gordon if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE) 12800a701b1eSRobert Gordon return (TRUE); 12810a701b1eSRobert Gordon 12820a701b1eSRobert Gordon if (xdrs->x_op == XDR_ENCODE) { 12830a701b1eSRobert Gordon 12840a701b1eSRobert Gordon if (objp->res_uiop != NULL) { 12850a701b1eSRobert Gordon rci.rci_type = RCI_WRITE_UIO_CHUNK; 12860a701b1eSRobert Gordon rci.rci_a.rci_uiop = objp->res_uiop; 12870a701b1eSRobert Gordon rci.rci_len = objp->count; 12880a701b1eSRobert Gordon rci.rci_clpp = &objp->wlist; 12890a701b1eSRobert Gordon } else { 12900a701b1eSRobert Gordon rci.rci_type = RCI_WRITE_ADDR_CHUNK; 12910a701b1eSRobert Gordon rci.rci_a.rci_addr = objp->res_data_val_alt; 12920a701b1eSRobert Gordon rci.rci_len = objp->count; 12930a701b1eSRobert Gordon rci.rci_clpp = &objp->wlist; 12940a701b1eSRobert Gordon } 12950a701b1eSRobert Gordon 12960a701b1eSRobert Gordon return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci)); 12970a701b1eSRobert Gordon } 12980a701b1eSRobert Gordon 12990a701b1eSRobert Gordon /* XDR_DECODE case */ 13000a701b1eSRobert Gordon (void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci); 13010a701b1eSRobert Gordon objp->wlist = rwci.rwci_wlist; 13020a701b1eSRobert Gordon objp->conn = rwci.rwci_conn; 13030a701b1eSRobert Gordon 13040a701b1eSRobert Gordon return (TRUE); 13057c478bd9Sstevel@tonic-gate } 13067c478bd9Sstevel@tonic-gate 13077c478bd9Sstevel@tonic-gate bool_t 13087c478bd9Sstevel@tonic-gate xdr_READ3res(XDR *xdrs, READ3res *objp) 13097c478bd9Sstevel@tonic-gate { 13107c478bd9Sstevel@tonic-gate READ3resok *resokp; 13117c478bd9Sstevel@tonic-gate bool_t ret; 13127c478bd9Sstevel@tonic-gate mblk_t *mp; 13137c478bd9Sstevel@tonic-gate 13147c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 13157c478bd9Sstevel@tonic-gate return (FALSE); 13167c478bd9Sstevel@tonic-gate 13177c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 13187c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &objp->resfail.file_attributes)); 13197c478bd9Sstevel@tonic-gate 13207c478bd9Sstevel@tonic-gate resokp = &objp->resok; 13217c478bd9Sstevel@tonic-gate 13227c478bd9Sstevel@tonic-gate if (xdr_post_op_attr(xdrs, &resokp->file_attributes) == FALSE || 13237c478bd9Sstevel@tonic-gate xdr_u_int(xdrs, &resokp->count) == FALSE || 13247c478bd9Sstevel@tonic-gate xdr_bool(xdrs, &resokp->eof) == FALSE) { 13257c478bd9Sstevel@tonic-gate return (FALSE); 13267c478bd9Sstevel@tonic-gate } 13277c478bd9Sstevel@tonic-gate 13287c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 13297c478bd9Sstevel@tonic-gate 13307c478bd9Sstevel@tonic-gate mp = resokp->data.mp; 1331*e36d7b11SSebastien Roy if (mp != NULL) { 1332*e36d7b11SSebastien Roy if (xdrs->x_ops == &xdrmblk_ops) { 1333*e36d7b11SSebastien Roy if (xdrmblk_putmblk(xdrs, mp, resokp->count)) { 13347c478bd9Sstevel@tonic-gate resokp->data.mp = NULL; 13357c478bd9Sstevel@tonic-gate return (TRUE); 1336*e36d7b11SSebastien Roy } else { 1337*e36d7b11SSebastien Roy return (FALSE); 13387c478bd9Sstevel@tonic-gate } 1339*e36d7b11SSebastien Roy } else if (mp->b_cont != NULL) { 1340*e36d7b11SSebastien Roy /* 1341*e36d7b11SSebastien Roy * We have read results in an mblk chain, but 1342*e36d7b11SSebastien Roy * the encoding operations don't handle mblks 1343*e36d7b11SSebastien Roy * (they'll operate on data.data_val rather 1344*e36d7b11SSebastien Roy * than data.mp). Because data_val can only 1345*e36d7b11SSebastien Roy * point at a single data buffer, we need to 1346*e36d7b11SSebastien Roy * pullup the read results into a single data 1347*e36d7b11SSebastien Roy * block and reset data_val to point to it. 1348*e36d7b11SSebastien Roy * 1349*e36d7b11SSebastien Roy * This happens with RPC GSS where the wrapping 1350*e36d7b11SSebastien Roy * function does XDR serialization into a 1351*e36d7b11SSebastien Roy * temporary buffer prior to applying GSS. 1352*e36d7b11SSebastien Roy * Because we're not in a performance sensitive 1353*e36d7b11SSebastien Roy * path, the pullupmsg() here shouldn't hurt us 1354*e36d7b11SSebastien Roy * too badly. 1355*e36d7b11SSebastien Roy */ 1356*e36d7b11SSebastien Roy if (pullupmsg(mp, -1) == 0) 1357*e36d7b11SSebastien Roy return (FALSE); 1358*e36d7b11SSebastien Roy resokp->data.data_val = (caddr_t)mp->b_rptr; 1359*e36d7b11SSebastien Roy } 1360*e36d7b11SSebastien Roy } else { 13610a701b1eSRobert Gordon if (xdr_u_int(xdrs, &resokp->count) == FALSE) { 13620a701b1eSRobert Gordon return (FALSE); 13630a701b1eSRobert Gordon } 13640a701b1eSRobert Gordon /* 13650a701b1eSRobert Gordon * If read data sent by wlist (RDMA_WRITE), don't do 13660a701b1eSRobert Gordon * xdr_bytes() below. RDMA_WRITE transfers the data. 13670a701b1eSRobert Gordon * Note: this is encode-only because the client code 13680a701b1eSRobert Gordon * uses xdr_READ3vres/xdr_READ3uiores to decode results. 13690a701b1eSRobert Gordon */ 13700a701b1eSRobert Gordon if (resokp->wlist) { 13710a701b1eSRobert Gordon if (resokp->count != 0) { 13720a701b1eSRobert Gordon return (xdrrdma_send_read_data( 1373f837ee4aSSiddheshwar Mahesh xdrs, resokp->count, 1374f837ee4aSSiddheshwar Mahesh resokp->wlist)); 13750a701b1eSRobert Gordon } 13760a701b1eSRobert Gordon return (TRUE); 13770a701b1eSRobert Gordon } 13787c478bd9Sstevel@tonic-gate } 13797c478bd9Sstevel@tonic-gate /* 13807c478bd9Sstevel@tonic-gate * Fall thru for the xdr_bytes() 13817c478bd9Sstevel@tonic-gate * 13827c478bd9Sstevel@tonic-gate * note: the mblk will be freed in 13837c478bd9Sstevel@tonic-gate * rfs3_read_free. 13847c478bd9Sstevel@tonic-gate */ 13857c478bd9Sstevel@tonic-gate } 13867c478bd9Sstevel@tonic-gate 13870a701b1eSRobert Gordon /* no RDMA_WRITE transfer -- send data inline */ 13880a701b1eSRobert Gordon 13897c478bd9Sstevel@tonic-gate ret = xdr_bytes(xdrs, (char **)&resokp->data.data_val, 13907c478bd9Sstevel@tonic-gate &resokp->data.data_len, nfs3tsize()); 13917c478bd9Sstevel@tonic-gate 13927c478bd9Sstevel@tonic-gate return (ret); 13937c478bd9Sstevel@tonic-gate } 13947c478bd9Sstevel@tonic-gate 13957c478bd9Sstevel@tonic-gate bool_t 13967c478bd9Sstevel@tonic-gate xdr_READ3vres(XDR *xdrs, READ3vres *objp) 13977c478bd9Sstevel@tonic-gate { 13980a701b1eSRobert Gordon count3 ocount; 13997c478bd9Sstevel@tonic-gate /* 14007c478bd9Sstevel@tonic-gate * DECODE or FREE only 14017c478bd9Sstevel@tonic-gate */ 14027c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 14037c478bd9Sstevel@tonic-gate return (TRUE); 14047c478bd9Sstevel@tonic-gate 14057c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_DECODE) 14067c478bd9Sstevel@tonic-gate return (FALSE); 14077c478bd9Sstevel@tonic-gate 14087c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 14097c478bd9Sstevel@tonic-gate return (FALSE); 14107c478bd9Sstevel@tonic-gate 14117c478bd9Sstevel@tonic-gate if (!xdr_post_op_vattr(xdrs, &objp->pov)) 14127c478bd9Sstevel@tonic-gate return (FALSE); 14137c478bd9Sstevel@tonic-gate 14147c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 14157c478bd9Sstevel@tonic-gate return (TRUE); 14167c478bd9Sstevel@tonic-gate 14177c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->count)) 14187c478bd9Sstevel@tonic-gate return (FALSE); 14197c478bd9Sstevel@tonic-gate 14207c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->eof)) 14217c478bd9Sstevel@tonic-gate return (FALSE); 14227c478bd9Sstevel@tonic-gate 14230a701b1eSRobert Gordon /* 14240a701b1eSRobert Gordon * If read data received via RDMA_WRITE, don't do xdr_bytes(). 14250a701b1eSRobert Gordon * RDMA_WRITE already moved the data so decode length of RDMA_WRITE. 14260a701b1eSRobert Gordon */ 14270a701b1eSRobert Gordon if (xdrs->x_ops == &xdrrdma_ops) { 14280a701b1eSRobert Gordon struct clist *cl; 14290a701b1eSRobert Gordon 14300a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl); 14310a701b1eSRobert Gordon 14320a701b1eSRobert Gordon if (cl) { 14330a701b1eSRobert Gordon if (!xdr_u_int(xdrs, &ocount)) { 14340a701b1eSRobert Gordon return (FALSE); 14350a701b1eSRobert Gordon } 14360a701b1eSRobert Gordon if (ocount != objp->count) { 14370a701b1eSRobert Gordon DTRACE_PROBE2(xdr__e__read3vres_fail, 14380a701b1eSRobert Gordon int, ocount, int, objp->count); 1439f837ee4aSSiddheshwar Mahesh objp->wlist = NULL; 14400a701b1eSRobert Gordon return (FALSE); 14410a701b1eSRobert Gordon } 14420a701b1eSRobert Gordon 1443f837ee4aSSiddheshwar Mahesh objp->wlist_len = clist_len(cl); 1444f837ee4aSSiddheshwar Mahesh objp->data.data_len = ocount; 1445f837ee4aSSiddheshwar Mahesh 1446f837ee4aSSiddheshwar Mahesh if (objp->wlist_len != 1447f837ee4aSSiddheshwar Mahesh roundup(objp->data.data_len, BYTES_PER_XDR_UNIT)) { 1448f837ee4aSSiddheshwar Mahesh DTRACE_PROBE2( 1449f837ee4aSSiddheshwar Mahesh xdr__e__read3vres_fail, 1450f837ee4aSSiddheshwar Mahesh int, ocount, 1451f837ee4aSSiddheshwar Mahesh int, objp->data.data_len); 1452f837ee4aSSiddheshwar Mahesh objp->wlist = NULL; 1453f837ee4aSSiddheshwar Mahesh return (FALSE); 1454f837ee4aSSiddheshwar Mahesh } 14550a701b1eSRobert Gordon return (TRUE); 14560a701b1eSRobert Gordon } 14570a701b1eSRobert Gordon } 14580a701b1eSRobert Gordon 14597c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->data.data_val, 14607c478bd9Sstevel@tonic-gate &objp->data.data_len, nfs3tsize())); 14617c478bd9Sstevel@tonic-gate } 14627c478bd9Sstevel@tonic-gate 14637c478bd9Sstevel@tonic-gate bool_t 14647c478bd9Sstevel@tonic-gate xdr_READ3uiores(XDR *xdrs, READ3uiores *objp) 14657c478bd9Sstevel@tonic-gate { 14660a701b1eSRobert Gordon count3 ocount; 14677c478bd9Sstevel@tonic-gate bool_t attributes; 14687c478bd9Sstevel@tonic-gate mblk_t *mp; 14697c478bd9Sstevel@tonic-gate size_t n; 14707c478bd9Sstevel@tonic-gate int error; 14717c478bd9Sstevel@tonic-gate int size = (int)objp->size; 14727c478bd9Sstevel@tonic-gate struct uio *uiop = objp->uiop; 14737c478bd9Sstevel@tonic-gate int32_t fattr3_len = NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT; 14747c478bd9Sstevel@tonic-gate int32_t *ptr; 14757c478bd9Sstevel@tonic-gate 14767c478bd9Sstevel@tonic-gate /* 14777c478bd9Sstevel@tonic-gate * DECODE or FREE only 14787c478bd9Sstevel@tonic-gate */ 14797c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 14807c478bd9Sstevel@tonic-gate return (TRUE); 14817c478bd9Sstevel@tonic-gate 14827c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_DECODE) 14837c478bd9Sstevel@tonic-gate return (FALSE); 14847c478bd9Sstevel@tonic-gate 14857c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status)) 14867c478bd9Sstevel@tonic-gate return (FALSE); 14877c478bd9Sstevel@tonic-gate 14887c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&attributes)) 14897c478bd9Sstevel@tonic-gate return (FALSE); 14907c478bd9Sstevel@tonic-gate 14917c478bd9Sstevel@tonic-gate /* 14927c478bd9Sstevel@tonic-gate * For directio we just skip over attributes if present 14937c478bd9Sstevel@tonic-gate */ 14947c478bd9Sstevel@tonic-gate switch (attributes) { 14957c478bd9Sstevel@tonic-gate case TRUE: 14967c478bd9Sstevel@tonic-gate if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fattr3_len)) 14977c478bd9Sstevel@tonic-gate return (FALSE); 14987c478bd9Sstevel@tonic-gate break; 14997c478bd9Sstevel@tonic-gate case FALSE: 15007c478bd9Sstevel@tonic-gate break; 15017c478bd9Sstevel@tonic-gate default: 15027c478bd9Sstevel@tonic-gate return (FALSE); 15037c478bd9Sstevel@tonic-gate } 15047c478bd9Sstevel@tonic-gate 15057c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 15067c478bd9Sstevel@tonic-gate return (TRUE); 15077c478bd9Sstevel@tonic-gate 15087c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&objp->count)) 15097c478bd9Sstevel@tonic-gate return (FALSE); 15107c478bd9Sstevel@tonic-gate 15117c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof)) 15127c478bd9Sstevel@tonic-gate return (FALSE); 15137c478bd9Sstevel@tonic-gate 15147c478bd9Sstevel@tonic-gate if (xdrs->x_ops == &xdrmblk_ops) { 15157c478bd9Sstevel@tonic-gate if (!xdrmblk_getmblk(xdrs, &mp, &objp->size)) 15167c478bd9Sstevel@tonic-gate return (FALSE); 15177c478bd9Sstevel@tonic-gate 15187c478bd9Sstevel@tonic-gate if (objp->size == 0) 15197c478bd9Sstevel@tonic-gate return (TRUE); 15207c478bd9Sstevel@tonic-gate 15217c478bd9Sstevel@tonic-gate if (objp->size > size) 15227c478bd9Sstevel@tonic-gate return (FALSE); 15237c478bd9Sstevel@tonic-gate 15247c478bd9Sstevel@tonic-gate size = (int)objp->size; 15257c478bd9Sstevel@tonic-gate do { 15267c478bd9Sstevel@tonic-gate n = MIN(size, mp->b_wptr - mp->b_rptr); 15277c478bd9Sstevel@tonic-gate if ((n = MIN(uiop->uio_resid, n)) != 0) { 15287c478bd9Sstevel@tonic-gate 15297c478bd9Sstevel@tonic-gate error = uiomove((char *)mp->b_rptr, n, UIO_READ, 15307c478bd9Sstevel@tonic-gate uiop); 15317c478bd9Sstevel@tonic-gate if (error) 15327c478bd9Sstevel@tonic-gate return (FALSE); 15337c478bd9Sstevel@tonic-gate mp->b_rptr += n; 15347c478bd9Sstevel@tonic-gate size -= n; 15357c478bd9Sstevel@tonic-gate } 15367c478bd9Sstevel@tonic-gate 15377c478bd9Sstevel@tonic-gate while (mp && (mp->b_rptr >= mp->b_wptr)) 15387c478bd9Sstevel@tonic-gate mp = mp->b_cont; 15397c478bd9Sstevel@tonic-gate } while (mp && size > 0 && uiop->uio_resid > 0); 15407c478bd9Sstevel@tonic-gate 15417c478bd9Sstevel@tonic-gate return (TRUE); 15427c478bd9Sstevel@tonic-gate } 15437c478bd9Sstevel@tonic-gate 15440a701b1eSRobert Gordon if (xdrs->x_ops == &xdrrdma_ops) { 15450a701b1eSRobert Gordon struct clist *cl; 15460a701b1eSRobert Gordon 15470a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl); 15480a701b1eSRobert Gordon 15490a701b1eSRobert Gordon objp->wlist = cl; 15500a701b1eSRobert Gordon 15510a701b1eSRobert Gordon if (objp->wlist) { 15520a701b1eSRobert Gordon if (!xdr_u_int(xdrs, &ocount)) { 15530a701b1eSRobert Gordon objp->wlist = NULL; 15540a701b1eSRobert Gordon return (FALSE); 15550a701b1eSRobert Gordon } 15560a701b1eSRobert Gordon 15570a701b1eSRobert Gordon if (ocount != objp->count) { 15580a701b1eSRobert Gordon DTRACE_PROBE2(xdr__e__read3uiores_fail, 15590a701b1eSRobert Gordon int, ocount, int, objp->count); 15600a701b1eSRobert Gordon objp->wlist = NULL; 15610a701b1eSRobert Gordon return (FALSE); 15620a701b1eSRobert Gordon } 15630a701b1eSRobert Gordon 1564f837ee4aSSiddheshwar Mahesh objp->wlist_len = clist_len(cl); 15650a701b1eSRobert Gordon 15660a701b1eSRobert Gordon uiop->uio_resid -= objp->count; 15670a701b1eSRobert Gordon uiop->uio_iov->iov_len -= objp->count; 15680a701b1eSRobert Gordon uiop->uio_iov->iov_base += objp->count; 15690a701b1eSRobert Gordon uiop->uio_loffset += objp->count; 15700a701b1eSRobert Gordon 15717c478bd9Sstevel@tonic-gate /* 15720a701b1eSRobert Gordon * XXX: Assume 1 iov, needs to be changed. 15730a701b1eSRobert Gordon */ 1574f837ee4aSSiddheshwar Mahesh objp->size = objp->count; 15750a701b1eSRobert Gordon 15760a701b1eSRobert Gordon return (TRUE); 15770a701b1eSRobert Gordon } 15780a701b1eSRobert Gordon } 15790a701b1eSRobert Gordon 15800a701b1eSRobert Gordon /* 15810a701b1eSRobert Gordon * This isn't an xdrmblk stream nor RDMA. 15820a701b1eSRobert Gordon * Handle the likely case that it can be 15830a701b1eSRobert Gordon * inlined (ex. xdrmem). 15847c478bd9Sstevel@tonic-gate */ 15857c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&objp->size)) 15867c478bd9Sstevel@tonic-gate return (FALSE); 15877c478bd9Sstevel@tonic-gate 15887c478bd9Sstevel@tonic-gate if (objp->size == 0) 15897c478bd9Sstevel@tonic-gate return (TRUE); 15907c478bd9Sstevel@tonic-gate 15917c478bd9Sstevel@tonic-gate if (objp->size > size) 15927c478bd9Sstevel@tonic-gate return (FALSE); 15937c478bd9Sstevel@tonic-gate 15947c478bd9Sstevel@tonic-gate size = (int)objp->size; 15957c478bd9Sstevel@tonic-gate if ((ptr = XDR_INLINE(xdrs, size)) != NULL) 15967c478bd9Sstevel@tonic-gate return (uiomove(ptr, size, UIO_READ, uiop) ? FALSE : TRUE); 15977c478bd9Sstevel@tonic-gate 15987c478bd9Sstevel@tonic-gate /* 15997c478bd9Sstevel@tonic-gate * Handle some other (unlikely) stream type that will need a copy. 16007c478bd9Sstevel@tonic-gate */ 16017c478bd9Sstevel@tonic-gate if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL) 16027c478bd9Sstevel@tonic-gate return (FALSE); 16037c478bd9Sstevel@tonic-gate 16047c478bd9Sstevel@tonic-gate if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) { 16057c478bd9Sstevel@tonic-gate kmem_free(ptr, size); 16067c478bd9Sstevel@tonic-gate return (FALSE); 16077c478bd9Sstevel@tonic-gate } 16087c478bd9Sstevel@tonic-gate error = uiomove(ptr, size, UIO_READ, uiop); 16097c478bd9Sstevel@tonic-gate kmem_free(ptr, size); 16107c478bd9Sstevel@tonic-gate 16117c478bd9Sstevel@tonic-gate return (error ? FALSE : TRUE); 16127c478bd9Sstevel@tonic-gate } 16137c478bd9Sstevel@tonic-gate 16147c478bd9Sstevel@tonic-gate bool_t 16157c478bd9Sstevel@tonic-gate xdr_WRITE3args(XDR *xdrs, WRITE3args *objp) 16167c478bd9Sstevel@tonic-gate { 161727242a7cSthurlow switch (xdrs->x_op) { 161827242a7cSthurlow case XDR_FREE: 161927242a7cSthurlow case XDR_ENCODE: 16207c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &objp->file)) 16217c478bd9Sstevel@tonic-gate return (FALSE); 162227242a7cSthurlow break; 162327242a7cSthurlow case XDR_DECODE: 162427242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->file)) 162527242a7cSthurlow return (FALSE); 162627242a7cSthurlow break; 162727242a7cSthurlow } 16287c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->offset)) 16297c478bd9Sstevel@tonic-gate return (FALSE); 16307c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->count)) 16317c478bd9Sstevel@tonic-gate return (FALSE); 16327c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->stable)) 16337c478bd9Sstevel@tonic-gate return (FALSE); 16347c478bd9Sstevel@tonic-gate 16357c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) { 16367c478bd9Sstevel@tonic-gate if (xdrs->x_ops == &xdrmblk_ops) { 16377c478bd9Sstevel@tonic-gate if (xdrmblk_getmblk(xdrs, &objp->mblk, 16387c478bd9Sstevel@tonic-gate &objp->data.data_len) == TRUE) { 16397c478bd9Sstevel@tonic-gate objp->data.data_val = NULL; 16407c478bd9Sstevel@tonic-gate return (TRUE); 16417c478bd9Sstevel@tonic-gate } 16427c478bd9Sstevel@tonic-gate } 16437c478bd9Sstevel@tonic-gate objp->mblk = NULL; 16440a701b1eSRobert Gordon 16450a701b1eSRobert Gordon if (xdrs->x_ops == &xdrrdmablk_ops) { 16460a701b1eSRobert Gordon if (xdrrdma_getrdmablk(xdrs, &objp->rlist, 16470a701b1eSRobert Gordon &objp->data.data_len, 16480a701b1eSRobert Gordon &objp->conn, nfs3tsize()) == TRUE) { 16490a701b1eSRobert Gordon objp->data.data_val = NULL; 16500a701b1eSRobert Gordon if (xdrrdma_read_from_client( 1651f837ee4aSSiddheshwar Mahesh objp->rlist, 16520a701b1eSRobert Gordon &objp->conn, 16530a701b1eSRobert Gordon objp->count) == FALSE) { 16540a701b1eSRobert Gordon return (FALSE); 16550a701b1eSRobert Gordon } 16560a701b1eSRobert Gordon return (TRUE); 16570a701b1eSRobert Gordon } 16580a701b1eSRobert Gordon } 16590a701b1eSRobert Gordon objp->rlist = NULL; 16600a701b1eSRobert Gordon 16617c478bd9Sstevel@tonic-gate /* Else fall thru for the xdr_bytes(). */ 16627c478bd9Sstevel@tonic-gate } 16637c478bd9Sstevel@tonic-gate 16640a701b1eSRobert Gordon if (xdrs->x_op == XDR_FREE) { 16650a701b1eSRobert Gordon if (objp->rlist != NULL) { 16660a701b1eSRobert Gordon (void) xdrrdma_free_clist(objp->conn, objp->rlist); 16670a701b1eSRobert Gordon objp->rlist = NULL; 16680a701b1eSRobert Gordon objp->data.data_val = NULL; 16690a701b1eSRobert Gordon return (TRUE); 16700a701b1eSRobert Gordon } 16710a701b1eSRobert Gordon } 16720a701b1eSRobert Gordon 16730a701b1eSRobert Gordon DTRACE_PROBE1(xdr__i__write3_buf_len, 16740a701b1eSRobert Gordon int, objp->data.data_len); 16750a701b1eSRobert Gordon 16767c478bd9Sstevel@tonic-gate return (xdr_bytes(xdrs, (char **)&objp->data.data_val, 16777c478bd9Sstevel@tonic-gate &objp->data.data_len, nfs3tsize())); 16787c478bd9Sstevel@tonic-gate } 16797c478bd9Sstevel@tonic-gate 16807c478bd9Sstevel@tonic-gate bool_t 16817c478bd9Sstevel@tonic-gate xdr_WRITE3res(XDR *xdrs, WRITE3res *objp) 16827c478bd9Sstevel@tonic-gate { 16837c478bd9Sstevel@tonic-gate WRITE3resok *resokp; 16847c478bd9Sstevel@tonic-gate 16857c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 16867c478bd9Sstevel@tonic-gate return (FALSE); 16877c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) /* xdr_WRITE3resfail */ 16887c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc)); 16897c478bd9Sstevel@tonic-gate 16907c478bd9Sstevel@tonic-gate /* xdr_WRITE3resok */ 16917c478bd9Sstevel@tonic-gate resokp = &objp->resok; 16927c478bd9Sstevel@tonic-gate if (!xdr_wcc_data(xdrs, &resokp->file_wcc)) 16937c478bd9Sstevel@tonic-gate return (FALSE); 16947c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->count)) 16957c478bd9Sstevel@tonic-gate return (FALSE); 16967c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&resokp->committed)) 16977c478bd9Sstevel@tonic-gate return (FALSE); 16987c478bd9Sstevel@tonic-gate /* 16997c478bd9Sstevel@tonic-gate * writeverf3 is really an opaque 8 byte 17007c478bd9Sstevel@tonic-gate * quantity, but we will treat it as a 17017c478bd9Sstevel@tonic-gate * hyper for efficiency, the cost of 17027c478bd9Sstevel@tonic-gate * a byteswap here saves bcopys elsewhere 17037c478bd9Sstevel@tonic-gate */ 17047c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, &resokp->verf)); 17057c478bd9Sstevel@tonic-gate } 17067c478bd9Sstevel@tonic-gate 17077c478bd9Sstevel@tonic-gate bool_t 17087c478bd9Sstevel@tonic-gate xdr_CREATE3args(XDR *xdrs, CREATE3args *objp) 17097c478bd9Sstevel@tonic-gate { 17107c478bd9Sstevel@tonic-gate createhow3 *howp; 17117c478bd9Sstevel@tonic-gate 17127c478bd9Sstevel@tonic-gate if (!xdr_diropargs3(xdrs, &objp->where)) 17137c478bd9Sstevel@tonic-gate return (FALSE); 17147c478bd9Sstevel@tonic-gate 17157c478bd9Sstevel@tonic-gate /* xdr_createhow3 */ 17167c478bd9Sstevel@tonic-gate howp = &objp->how; 17177c478bd9Sstevel@tonic-gate 17187c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&howp->mode)) 17197c478bd9Sstevel@tonic-gate return (FALSE); 17207c478bd9Sstevel@tonic-gate switch (howp->mode) { 17217c478bd9Sstevel@tonic-gate case UNCHECKED: 17227c478bd9Sstevel@tonic-gate case GUARDED: 17237c478bd9Sstevel@tonic-gate return (xdr_sattr3(xdrs, &howp->createhow3_u.obj_attributes)); 17247c478bd9Sstevel@tonic-gate case EXCLUSIVE: 17257c478bd9Sstevel@tonic-gate /* 17267c478bd9Sstevel@tonic-gate * createverf3 is really an opaque 8 byte 17277c478bd9Sstevel@tonic-gate * quantity, but we will treat it as a 17287c478bd9Sstevel@tonic-gate * hyper for efficiency, the cost of 17297c478bd9Sstevel@tonic-gate * a byteswap here saves bcopys elsewhere 17307c478bd9Sstevel@tonic-gate */ 17317c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, &howp->createhow3_u.verf)); 17327c478bd9Sstevel@tonic-gate default: 17337c478bd9Sstevel@tonic-gate return (FALSE); 17347c478bd9Sstevel@tonic-gate } 17357c478bd9Sstevel@tonic-gate } 17367c478bd9Sstevel@tonic-gate 17377c478bd9Sstevel@tonic-gate bool_t 17387c478bd9Sstevel@tonic-gate xdr_CREATE3res(XDR *xdrs, CREATE3res *objp) 17397c478bd9Sstevel@tonic-gate { 17407c478bd9Sstevel@tonic-gate CREATE3resok *resokp; 17417c478bd9Sstevel@tonic-gate 17427c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 17437c478bd9Sstevel@tonic-gate return (FALSE); 17447c478bd9Sstevel@tonic-gate switch (objp->status) { 17457c478bd9Sstevel@tonic-gate case NFS3_OK: 17467c478bd9Sstevel@tonic-gate /* xdr_CREATE3resok */ 17477c478bd9Sstevel@tonic-gate resokp = &objp->resok; 17487c478bd9Sstevel@tonic-gate 17497c478bd9Sstevel@tonic-gate if (!xdr_post_op_fh3(xdrs, &resokp->obj)) 17507c478bd9Sstevel@tonic-gate return (FALSE); 17517c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes)) 17527c478bd9Sstevel@tonic-gate return (FALSE); 17537c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &resokp->dir_wcc)); 17547c478bd9Sstevel@tonic-gate default: 17557c478bd9Sstevel@tonic-gate /* xdr_CREATE3resfail */ 17567c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc)); 17577c478bd9Sstevel@tonic-gate } 17587c478bd9Sstevel@tonic-gate } 17597c478bd9Sstevel@tonic-gate 17607c478bd9Sstevel@tonic-gate bool_t 17617c478bd9Sstevel@tonic-gate xdr_MKDIR3args(XDR *xdrs, MKDIR3args *objp) 17627c478bd9Sstevel@tonic-gate { 17637c478bd9Sstevel@tonic-gate if (!xdr_diropargs3(xdrs, &objp->where)) 17647c478bd9Sstevel@tonic-gate return (FALSE); 17657c478bd9Sstevel@tonic-gate return (xdr_sattr3(xdrs, &objp->attributes)); 17667c478bd9Sstevel@tonic-gate } 17677c478bd9Sstevel@tonic-gate 17687c478bd9Sstevel@tonic-gate bool_t 17697c478bd9Sstevel@tonic-gate xdr_MKDIR3res(XDR *xdrs, MKDIR3res *objp) 17707c478bd9Sstevel@tonic-gate { 17717c478bd9Sstevel@tonic-gate MKDIR3resok *resokp; 17727c478bd9Sstevel@tonic-gate 17737c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 17747c478bd9Sstevel@tonic-gate return (FALSE); 17757c478bd9Sstevel@tonic-gate switch (objp->status) { 17767c478bd9Sstevel@tonic-gate case NFS3_OK: 17777c478bd9Sstevel@tonic-gate /* xdr_MKDIR3resok */ 17787c478bd9Sstevel@tonic-gate resokp = &objp->resok; 17797c478bd9Sstevel@tonic-gate 17807c478bd9Sstevel@tonic-gate if (!xdr_post_op_fh3(xdrs, &resokp->obj)) 17817c478bd9Sstevel@tonic-gate return (FALSE); 17827c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes)) 17837c478bd9Sstevel@tonic-gate return (FALSE); 17847c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &resokp->dir_wcc)); 17857c478bd9Sstevel@tonic-gate default: 17867c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc)); 17877c478bd9Sstevel@tonic-gate } 17887c478bd9Sstevel@tonic-gate } 17897c478bd9Sstevel@tonic-gate 17907c478bd9Sstevel@tonic-gate bool_t 17917c478bd9Sstevel@tonic-gate xdr_SYMLINK3args(XDR *xdrs, SYMLINK3args *objp) 17927c478bd9Sstevel@tonic-gate { 17937c478bd9Sstevel@tonic-gate if (!xdr_diropargs3(xdrs, &objp->where)) 17947c478bd9Sstevel@tonic-gate return (FALSE); 17957c478bd9Sstevel@tonic-gate if (!xdr_sattr3(xdrs, &objp->symlink.symlink_attributes)) 17967c478bd9Sstevel@tonic-gate return (FALSE); 17977c478bd9Sstevel@tonic-gate return (xdr_string3(xdrs, &objp->symlink.symlink_data, MAXPATHLEN)); 17987c478bd9Sstevel@tonic-gate } 17997c478bd9Sstevel@tonic-gate 18007c478bd9Sstevel@tonic-gate bool_t 18017c478bd9Sstevel@tonic-gate xdr_SYMLINK3res(XDR *xdrs, SYMLINK3res *objp) 18027c478bd9Sstevel@tonic-gate { 18037c478bd9Sstevel@tonic-gate SYMLINK3resok *resokp; 18047c478bd9Sstevel@tonic-gate 18057c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 18067c478bd9Sstevel@tonic-gate return (FALSE); 18077c478bd9Sstevel@tonic-gate switch (objp->status) { 18087c478bd9Sstevel@tonic-gate case NFS3_OK: 18097c478bd9Sstevel@tonic-gate resokp = &objp->resok; 18107c478bd9Sstevel@tonic-gate /* xdr_SYMLINK3resok */ 18117c478bd9Sstevel@tonic-gate if (!xdr_post_op_fh3(xdrs, &resokp->obj)) 18127c478bd9Sstevel@tonic-gate return (FALSE); 18137c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes)) 18147c478bd9Sstevel@tonic-gate return (FALSE); 18157c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &resokp->dir_wcc)); 18167c478bd9Sstevel@tonic-gate default: 18177c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc)); 18187c478bd9Sstevel@tonic-gate } 18197c478bd9Sstevel@tonic-gate } 18207c478bd9Sstevel@tonic-gate 18217c478bd9Sstevel@tonic-gate bool_t 18227c478bd9Sstevel@tonic-gate xdr_MKNOD3args(XDR *xdrs, MKNOD3args *objp) 18237c478bd9Sstevel@tonic-gate { 18247c478bd9Sstevel@tonic-gate mknoddata3 *whatp; 18257c478bd9Sstevel@tonic-gate devicedata3 *nod_objp; 18267c478bd9Sstevel@tonic-gate 18277c478bd9Sstevel@tonic-gate if (!xdr_diropargs3(xdrs, &objp->where)) 18287c478bd9Sstevel@tonic-gate return (FALSE); 18297c478bd9Sstevel@tonic-gate 18307c478bd9Sstevel@tonic-gate whatp = &objp->what; 18317c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&whatp->type)) 18327c478bd9Sstevel@tonic-gate return (FALSE); 18337c478bd9Sstevel@tonic-gate switch (whatp->type) { 18347c478bd9Sstevel@tonic-gate case NF3CHR: 18357c478bd9Sstevel@tonic-gate case NF3BLK: 18367c478bd9Sstevel@tonic-gate /* xdr_devicedata3 */ 18377c478bd9Sstevel@tonic-gate nod_objp = &whatp->mknoddata3_u.device; 18387c478bd9Sstevel@tonic-gate if (!xdr_sattr3(xdrs, &nod_objp->dev_attributes)) 18397c478bd9Sstevel@tonic-gate return (FALSE); 18407c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &nod_objp->spec.specdata1)) 18417c478bd9Sstevel@tonic-gate return (FALSE); 18427c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &nod_objp->spec.specdata2)); 18437c478bd9Sstevel@tonic-gate case NF3SOCK: 18447c478bd9Sstevel@tonic-gate case NF3FIFO: 18457c478bd9Sstevel@tonic-gate return (xdr_sattr3(xdrs, &whatp->mknoddata3_u.pipe_attributes)); 18467c478bd9Sstevel@tonic-gate default: 18477c478bd9Sstevel@tonic-gate break; 18487c478bd9Sstevel@tonic-gate } 18497c478bd9Sstevel@tonic-gate return (TRUE); 18507c478bd9Sstevel@tonic-gate } 18517c478bd9Sstevel@tonic-gate 18527c478bd9Sstevel@tonic-gate bool_t 18537c478bd9Sstevel@tonic-gate xdr_MKNOD3res(XDR *xdrs, MKNOD3res *objp) 18547c478bd9Sstevel@tonic-gate { 18557c478bd9Sstevel@tonic-gate MKNOD3resok *resokp; 18567c478bd9Sstevel@tonic-gate 18577c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 18587c478bd9Sstevel@tonic-gate return (FALSE); 18597c478bd9Sstevel@tonic-gate switch (objp->status) { 18607c478bd9Sstevel@tonic-gate case NFS3_OK: 18617c478bd9Sstevel@tonic-gate /* xdr_MKNOD3resok */ 18627c478bd9Sstevel@tonic-gate resokp = &objp->resok; 18637c478bd9Sstevel@tonic-gate if (!xdr_post_op_fh3(xdrs, &resokp->obj)) 18647c478bd9Sstevel@tonic-gate return (FALSE); 18657c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes)) 18667c478bd9Sstevel@tonic-gate return (FALSE); 18677c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &resokp->dir_wcc)); 18687c478bd9Sstevel@tonic-gate default: 18697c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc)); 18707c478bd9Sstevel@tonic-gate } 18717c478bd9Sstevel@tonic-gate } 18727c478bd9Sstevel@tonic-gate 18737c478bd9Sstevel@tonic-gate bool_t 18747c478bd9Sstevel@tonic-gate xdr_REMOVE3res(XDR *xdrs, REMOVE3res *objp) 18757c478bd9Sstevel@tonic-gate { 18767c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 18777c478bd9Sstevel@tonic-gate return (FALSE); 18787c478bd9Sstevel@tonic-gate switch (objp->status) { 18797c478bd9Sstevel@tonic-gate case NFS3_OK: 18807c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc)); 18817c478bd9Sstevel@tonic-gate default: 18827c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc)); 18837c478bd9Sstevel@tonic-gate } 18847c478bd9Sstevel@tonic-gate } 18857c478bd9Sstevel@tonic-gate 18867c478bd9Sstevel@tonic-gate bool_t 18877c478bd9Sstevel@tonic-gate xdr_RMDIR3res(XDR *xdrs, RMDIR3res *objp) 18887c478bd9Sstevel@tonic-gate { 18897c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 18907c478bd9Sstevel@tonic-gate return (FALSE); 18917c478bd9Sstevel@tonic-gate switch (objp->status) { 18927c478bd9Sstevel@tonic-gate case NFS3_OK: 18937c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc)); 18947c478bd9Sstevel@tonic-gate default: 18957c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc)); 18967c478bd9Sstevel@tonic-gate } 18977c478bd9Sstevel@tonic-gate } 18987c478bd9Sstevel@tonic-gate 18997c478bd9Sstevel@tonic-gate bool_t 19007c478bd9Sstevel@tonic-gate xdr_RENAME3args(XDR *xdrs, RENAME3args *objp) 19017c478bd9Sstevel@tonic-gate { 19027c478bd9Sstevel@tonic-gate if (!xdr_diropargs3(xdrs, &objp->from)) 19037c478bd9Sstevel@tonic-gate return (FALSE); 19047c478bd9Sstevel@tonic-gate return (xdr_diropargs3(xdrs, &objp->to)); 19057c478bd9Sstevel@tonic-gate } 19067c478bd9Sstevel@tonic-gate 19077c478bd9Sstevel@tonic-gate bool_t 19087c478bd9Sstevel@tonic-gate xdr_RENAME3res(XDR *xdrs, RENAME3res *objp) 19097c478bd9Sstevel@tonic-gate { 19107c478bd9Sstevel@tonic-gate RENAME3resok *resokp; 19117c478bd9Sstevel@tonic-gate RENAME3resfail *resfailp; 19127c478bd9Sstevel@tonic-gate 19137c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 19147c478bd9Sstevel@tonic-gate return (FALSE); 19157c478bd9Sstevel@tonic-gate switch (objp->status) { 19167c478bd9Sstevel@tonic-gate case NFS3_OK: 19177c478bd9Sstevel@tonic-gate /* xdr_RENAME3resok */ 19187c478bd9Sstevel@tonic-gate resokp = &objp->resok; 19197c478bd9Sstevel@tonic-gate 19207c478bd9Sstevel@tonic-gate if (!xdr_wcc_data(xdrs, &resokp->fromdir_wcc)) 19217c478bd9Sstevel@tonic-gate return (FALSE); 19227c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &resokp->todir_wcc)); 19237c478bd9Sstevel@tonic-gate default: 19247c478bd9Sstevel@tonic-gate /* xdr_RENAME3resfail */ 19257c478bd9Sstevel@tonic-gate resfailp = &objp->resfail; 19267c478bd9Sstevel@tonic-gate if (!xdr_wcc_data(xdrs, &resfailp->fromdir_wcc)) 19277c478bd9Sstevel@tonic-gate return (FALSE); 19287c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &resfailp->todir_wcc)); 19297c478bd9Sstevel@tonic-gate } 19307c478bd9Sstevel@tonic-gate } 19317c478bd9Sstevel@tonic-gate 19327c478bd9Sstevel@tonic-gate bool_t 19337c478bd9Sstevel@tonic-gate xdr_LINK3args(XDR *xdrs, LINK3args *objp) 19347c478bd9Sstevel@tonic-gate { 193527242a7cSthurlow switch (xdrs->x_op) { 193627242a7cSthurlow case XDR_FREE: 193727242a7cSthurlow case XDR_ENCODE: 19387c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &objp->file)) 19397c478bd9Sstevel@tonic-gate return (FALSE); 194027242a7cSthurlow break; 194127242a7cSthurlow case XDR_DECODE: 194227242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->file)) 194327242a7cSthurlow return (FALSE); 194427242a7cSthurlow break; 194527242a7cSthurlow } 19467c478bd9Sstevel@tonic-gate return (xdr_diropargs3(xdrs, &objp->link)); 19477c478bd9Sstevel@tonic-gate } 19487c478bd9Sstevel@tonic-gate 19497c478bd9Sstevel@tonic-gate bool_t 19507c478bd9Sstevel@tonic-gate xdr_LINK3res(XDR *xdrs, LINK3res *objp) 19517c478bd9Sstevel@tonic-gate { 19527c478bd9Sstevel@tonic-gate LINK3resok *resokp; 19537c478bd9Sstevel@tonic-gate LINK3resfail *resfailp; 19547c478bd9Sstevel@tonic-gate 19557c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 19567c478bd9Sstevel@tonic-gate return (FALSE); 19577c478bd9Sstevel@tonic-gate switch (objp->status) { 19587c478bd9Sstevel@tonic-gate case NFS3_OK: 19597c478bd9Sstevel@tonic-gate /* xdr_LINK3resok */ 19607c478bd9Sstevel@tonic-gate resokp = &objp->resok; 19617c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->file_attributes)) 19627c478bd9Sstevel@tonic-gate return (FALSE); 19637c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &resokp->linkdir_wcc)); 19647c478bd9Sstevel@tonic-gate default: 19657c478bd9Sstevel@tonic-gate /* xdr_LINK3resfail */ 19667c478bd9Sstevel@tonic-gate resfailp = &objp->resfail; 19677c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resfailp->file_attributes)) 19687c478bd9Sstevel@tonic-gate return (FALSE); 19697c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &resfailp->linkdir_wcc)); 19707c478bd9Sstevel@tonic-gate } 19717c478bd9Sstevel@tonic-gate } 19727c478bd9Sstevel@tonic-gate 19737c478bd9Sstevel@tonic-gate bool_t 19747c478bd9Sstevel@tonic-gate xdr_READDIR3args(XDR *xdrs, READDIR3args *objp) 19757c478bd9Sstevel@tonic-gate { 19760a701b1eSRobert Gordon rdma_chunkinfo_t rci; 19770a701b1eSRobert Gordon struct xdr_ops *xops = xdrrdma_xops(); 19780a701b1eSRobert Gordon 19797c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 19807c478bd9Sstevel@tonic-gate return (TRUE); 19817c478bd9Sstevel@tonic-gate 198227242a7cSthurlow switch (xdrs->x_op) { 198327242a7cSthurlow case XDR_FREE: 198427242a7cSthurlow case XDR_ENCODE: 19857c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &objp->dir)) 19867c478bd9Sstevel@tonic-gate return (FALSE); 198727242a7cSthurlow break; 198827242a7cSthurlow case XDR_DECODE: 198927242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->dir)) 199027242a7cSthurlow return (FALSE); 199127242a7cSthurlow break; 199227242a7cSthurlow } 19930a701b1eSRobert Gordon if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) && 19940a701b1eSRobert Gordon xdrs->x_op == XDR_ENCODE) { 19950a701b1eSRobert Gordon rci.rci_type = RCI_REPLY_CHUNK; 19960a701b1eSRobert Gordon rci.rci_len = objp->count; 19970a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci); 19980a701b1eSRobert Gordon } 19990a701b1eSRobert Gordon 20007c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->cookie)) 20017c478bd9Sstevel@tonic-gate return (FALSE); 20027c478bd9Sstevel@tonic-gate /* 20037c478bd9Sstevel@tonic-gate * cookieverf is really an opaque 8 byte 20047c478bd9Sstevel@tonic-gate * quantity, but we will treat it as a 20057c478bd9Sstevel@tonic-gate * hyper for efficiency, the cost of 20067c478bd9Sstevel@tonic-gate * a byteswap here saves bcopys elsewhere 20077c478bd9Sstevel@tonic-gate */ 20087c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->cookieverf)) 20097c478bd9Sstevel@tonic-gate return (FALSE); 20107c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->count)); 20117c478bd9Sstevel@tonic-gate } 20127c478bd9Sstevel@tonic-gate 20137c478bd9Sstevel@tonic-gate #ifdef nextdp 20147c478bd9Sstevel@tonic-gate #undef nextdp 20157c478bd9Sstevel@tonic-gate #endif 20167c478bd9Sstevel@tonic-gate #define nextdp(dp) ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen)) 20177c478bd9Sstevel@tonic-gate #ifdef roundup 20187c478bd9Sstevel@tonic-gate #undef roundup 20197c478bd9Sstevel@tonic-gate #endif 20207c478bd9Sstevel@tonic-gate #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) 20217c478bd9Sstevel@tonic-gate 20227c478bd9Sstevel@tonic-gate /* 20237c478bd9Sstevel@tonic-gate * ENCODE ONLY 20247c478bd9Sstevel@tonic-gate */ 20257c478bd9Sstevel@tonic-gate static bool_t 20267c478bd9Sstevel@tonic-gate xdr_putdirlist(XDR *xdrs, READDIR3resok *objp) 20277c478bd9Sstevel@tonic-gate { 20287c478bd9Sstevel@tonic-gate struct dirent64 *dp; 20297c478bd9Sstevel@tonic-gate char *name; 20307c478bd9Sstevel@tonic-gate int size; 20317c478bd9Sstevel@tonic-gate int bufsize; 20327c478bd9Sstevel@tonic-gate uint_t namlen; 20337c478bd9Sstevel@tonic-gate bool_t true = TRUE; 20347c478bd9Sstevel@tonic-gate bool_t false = FALSE; 20357c478bd9Sstevel@tonic-gate int entrysz; 20367c478bd9Sstevel@tonic-gate int tofit; 20377c478bd9Sstevel@tonic-gate fileid3 fileid; 20387c478bd9Sstevel@tonic-gate cookie3 cookie; 20397c478bd9Sstevel@tonic-gate 20407c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_ENCODE) 20417c478bd9Sstevel@tonic-gate return (FALSE); 20427c478bd9Sstevel@tonic-gate 20437c478bd9Sstevel@tonic-gate /* 20447c478bd9Sstevel@tonic-gate * bufsize is used to keep track of the size of the response. 20457c478bd9Sstevel@tonic-gate * It is primed with: 20467c478bd9Sstevel@tonic-gate * 1 for the status + 20477c478bd9Sstevel@tonic-gate * 1 for the dir_attributes.attributes boolean + 20487c478bd9Sstevel@tonic-gate * 2 for the cookie verifier 20497c478bd9Sstevel@tonic-gate * all times BYTES_PER_XDR_UNIT to convert from XDR units 20507c478bd9Sstevel@tonic-gate * to bytes. If there are directory attributes to be 20517c478bd9Sstevel@tonic-gate * returned, then: 20527c478bd9Sstevel@tonic-gate * NFS3_SIZEOF_FATTR3 for the dir_attributes.attr fattr3 20537c478bd9Sstevel@tonic-gate * time BYTES_PER_XDR_UNIT is added to account for them. 20547c478bd9Sstevel@tonic-gate */ 20557c478bd9Sstevel@tonic-gate bufsize = (1 + 1 + 2) * BYTES_PER_XDR_UNIT; 20567c478bd9Sstevel@tonic-gate if (objp->dir_attributes.attributes) 20577c478bd9Sstevel@tonic-gate bufsize += NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT; 20587c478bd9Sstevel@tonic-gate for (size = objp->size, dp = (struct dirent64 *)objp->reply.entries; 20597c478bd9Sstevel@tonic-gate size > 0; 20607c478bd9Sstevel@tonic-gate size -= dp->d_reclen, dp = nextdp(dp)) { 20617c478bd9Sstevel@tonic-gate if (dp->d_reclen == 0) 20627c478bd9Sstevel@tonic-gate return (FALSE); 20637c478bd9Sstevel@tonic-gate if (dp->d_ino == 0) 20647c478bd9Sstevel@tonic-gate continue; 20657c478bd9Sstevel@tonic-gate name = dp->d_name; 20667c478bd9Sstevel@tonic-gate namlen = (uint_t)strlen(dp->d_name); 20677c478bd9Sstevel@tonic-gate /* 20687c478bd9Sstevel@tonic-gate * An entry is composed of: 20697c478bd9Sstevel@tonic-gate * 1 for the true/false list indicator + 20707c478bd9Sstevel@tonic-gate * 2 for the fileid + 20717c478bd9Sstevel@tonic-gate * 1 for the length of the name + 20727c478bd9Sstevel@tonic-gate * 2 for the cookie + 20737c478bd9Sstevel@tonic-gate * all times BYTES_PER_XDR_UNIT to convert from 20747c478bd9Sstevel@tonic-gate * XDR units to bytes, plus the length of the name 20757c478bd9Sstevel@tonic-gate * rounded up to the nearest BYTES_PER_XDR_UNIT. 20767c478bd9Sstevel@tonic-gate */ 20777c478bd9Sstevel@tonic-gate entrysz = (1 + 2 + 1 + 2) * BYTES_PER_XDR_UNIT + 20787c478bd9Sstevel@tonic-gate roundup(namlen, BYTES_PER_XDR_UNIT); 20797c478bd9Sstevel@tonic-gate /* 20807c478bd9Sstevel@tonic-gate * We need to check to see if the number of bytes left 20817c478bd9Sstevel@tonic-gate * to go into the buffer will actually fit into the 20827c478bd9Sstevel@tonic-gate * buffer. This is calculated as the size of this 20837c478bd9Sstevel@tonic-gate * entry plus: 20847c478bd9Sstevel@tonic-gate * 1 for the true/false list indicator + 20857c478bd9Sstevel@tonic-gate * 1 for the eof indicator 20867c478bd9Sstevel@tonic-gate * times BYTES_PER_XDR_UNIT to convert from from 20877c478bd9Sstevel@tonic-gate * XDR units to bytes. 20887c478bd9Sstevel@tonic-gate */ 20897c478bd9Sstevel@tonic-gate tofit = entrysz + (1 + 1) * BYTES_PER_XDR_UNIT; 20907c478bd9Sstevel@tonic-gate if (bufsize + tofit > objp->count) { 20917c478bd9Sstevel@tonic-gate objp->reply.eof = FALSE; 20927c478bd9Sstevel@tonic-gate break; 20937c478bd9Sstevel@tonic-gate } 20947c478bd9Sstevel@tonic-gate fileid = (fileid3)(dp->d_ino); 20957c478bd9Sstevel@tonic-gate cookie = (cookie3)(dp->d_off); 20967c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &true) || 20977c478bd9Sstevel@tonic-gate !xdr_u_longlong_t(xdrs, &fileid) || 20987c478bd9Sstevel@tonic-gate !xdr_bytes(xdrs, &name, &namlen, ~0) || 20997c478bd9Sstevel@tonic-gate !xdr_u_longlong_t(xdrs, &cookie)) { 21007c478bd9Sstevel@tonic-gate return (FALSE); 21017c478bd9Sstevel@tonic-gate } 21027c478bd9Sstevel@tonic-gate bufsize += entrysz; 21037c478bd9Sstevel@tonic-gate } 21047c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &false)) 21057c478bd9Sstevel@tonic-gate return (FALSE); 21067c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->reply.eof)) 21077c478bd9Sstevel@tonic-gate return (FALSE); 21087c478bd9Sstevel@tonic-gate return (TRUE); 21097c478bd9Sstevel@tonic-gate } 21107c478bd9Sstevel@tonic-gate 21117c478bd9Sstevel@tonic-gate bool_t 21127c478bd9Sstevel@tonic-gate xdr_READDIR3res(XDR *xdrs, READDIR3res *objp) 21137c478bd9Sstevel@tonic-gate { 21147c478bd9Sstevel@tonic-gate READDIR3resok *resokp; 21157c478bd9Sstevel@tonic-gate 21167c478bd9Sstevel@tonic-gate /* 21177c478bd9Sstevel@tonic-gate * ENCODE or FREE only 21187c478bd9Sstevel@tonic-gate */ 21197c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) 21207c478bd9Sstevel@tonic-gate return (FALSE); 21217c478bd9Sstevel@tonic-gate 21227c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 21237c478bd9Sstevel@tonic-gate return (FALSE); 21247c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 21257c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes)); 21267c478bd9Sstevel@tonic-gate 21277c478bd9Sstevel@tonic-gate /* xdr_READDIR3resok */ 21287c478bd9Sstevel@tonic-gate resokp = &objp->resok; 21297c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes)) 21307c478bd9Sstevel@tonic-gate return (FALSE); 21317c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_ENCODE) 21327c478bd9Sstevel@tonic-gate return (TRUE); 21337c478bd9Sstevel@tonic-gate /* 21347c478bd9Sstevel@tonic-gate * cookieverf is really an opaque 8 byte 21357c478bd9Sstevel@tonic-gate * quantity, but we will treat it as a 21367c478bd9Sstevel@tonic-gate * hyper for efficiency, the cost of 21377c478bd9Sstevel@tonic-gate * a byteswap here saves bcopys elsewhere 21387c478bd9Sstevel@tonic-gate */ 21397c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf)) 21407c478bd9Sstevel@tonic-gate return (FALSE); 21417c478bd9Sstevel@tonic-gate return (xdr_putdirlist(xdrs, resokp)); 21427c478bd9Sstevel@tonic-gate } 21437c478bd9Sstevel@tonic-gate 21447c478bd9Sstevel@tonic-gate bool_t 21457c478bd9Sstevel@tonic-gate xdr_READDIR3vres(XDR *xdrs, READDIR3vres *objp) 21467c478bd9Sstevel@tonic-gate { 21477c478bd9Sstevel@tonic-gate dirent64_t *dp; 21487c478bd9Sstevel@tonic-gate uint_t entries_size; 21497c478bd9Sstevel@tonic-gate int outcount = 0; 21507c478bd9Sstevel@tonic-gate 21517c478bd9Sstevel@tonic-gate /* 21527c478bd9Sstevel@tonic-gate * DECODE or FREE only 21537c478bd9Sstevel@tonic-gate */ 21547c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 21557c478bd9Sstevel@tonic-gate return (TRUE); 21567c478bd9Sstevel@tonic-gate 21577c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_DECODE) 21587c478bd9Sstevel@tonic-gate return (FALSE); 21597c478bd9Sstevel@tonic-gate 21607c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 21617c478bd9Sstevel@tonic-gate return (FALSE); 21627c478bd9Sstevel@tonic-gate 21637c478bd9Sstevel@tonic-gate if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes)) 21647c478bd9Sstevel@tonic-gate return (FALSE); 21657c478bd9Sstevel@tonic-gate 21667c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 21677c478bd9Sstevel@tonic-gate return (TRUE); 21687c478bd9Sstevel@tonic-gate 21697c478bd9Sstevel@tonic-gate /* 21707c478bd9Sstevel@tonic-gate * cookieverf is really an opaque 8 byte 21717c478bd9Sstevel@tonic-gate * quantity, but we will treat it as a 21727c478bd9Sstevel@tonic-gate * hyper for efficiency, the cost of 21737c478bd9Sstevel@tonic-gate * a byteswap here saves bcopys elsewhere 21747c478bd9Sstevel@tonic-gate */ 21757c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->cookieverf)) 21767c478bd9Sstevel@tonic-gate return (FALSE); 21777c478bd9Sstevel@tonic-gate 21787c478bd9Sstevel@tonic-gate entries_size = objp->entries_size; 21797c478bd9Sstevel@tonic-gate dp = objp->entries; 21807c478bd9Sstevel@tonic-gate 21817c478bd9Sstevel@tonic-gate for (;;) { 21827c478bd9Sstevel@tonic-gate uint_t this_reclen; 21837c478bd9Sstevel@tonic-gate bool_t valid; 21847c478bd9Sstevel@tonic-gate uint_t namlen; 21857c478bd9Sstevel@tonic-gate ino64_t fileid; 21867c478bd9Sstevel@tonic-gate 21877c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&valid)) 21887c478bd9Sstevel@tonic-gate return (FALSE); 21897c478bd9Sstevel@tonic-gate if (!valid) { 21907c478bd9Sstevel@tonic-gate /* 21917c478bd9Sstevel@tonic-gate * We have run out of entries, decode eof. 21927c478bd9Sstevel@tonic-gate */ 21937c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof)) 21947c478bd9Sstevel@tonic-gate return (FALSE); 21957c478bd9Sstevel@tonic-gate 21967c478bd9Sstevel@tonic-gate break; 21977c478bd9Sstevel@tonic-gate } 21987c478bd9Sstevel@tonic-gate 21997c478bd9Sstevel@tonic-gate /* 22007c478bd9Sstevel@tonic-gate * fileid3 fileid 22017c478bd9Sstevel@tonic-gate */ 22027c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid)) 22037c478bd9Sstevel@tonic-gate return (FALSE); 22047c478bd9Sstevel@tonic-gate 22057c478bd9Sstevel@tonic-gate /* 22067c478bd9Sstevel@tonic-gate * filename3 name 22077c478bd9Sstevel@tonic-gate */ 22087c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&namlen)) 22097c478bd9Sstevel@tonic-gate return (FALSE); 22107c478bd9Sstevel@tonic-gate this_reclen = DIRENT64_RECLEN(namlen); 22117c478bd9Sstevel@tonic-gate 22127c478bd9Sstevel@tonic-gate /* 22137c478bd9Sstevel@tonic-gate * If this will overflow buffer, stop decoding 22147c478bd9Sstevel@tonic-gate */ 22157c478bd9Sstevel@tonic-gate if ((outcount + this_reclen) > entries_size) { 22167c478bd9Sstevel@tonic-gate objp->eof = FALSE; 22177c478bd9Sstevel@tonic-gate break; 22187c478bd9Sstevel@tonic-gate } 22197c478bd9Sstevel@tonic-gate dp->d_reclen = this_reclen; 22207c478bd9Sstevel@tonic-gate dp->d_ino = fileid; 22217c478bd9Sstevel@tonic-gate 22227c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, dp->d_name, namlen)) 22237c478bd9Sstevel@tonic-gate return (FALSE); 22247c478bd9Sstevel@tonic-gate bzero(&dp->d_name[namlen], 22257c478bd9Sstevel@tonic-gate DIRENT64_NAMELEN(this_reclen) - namlen); 22267c478bd9Sstevel@tonic-gate 22277c478bd9Sstevel@tonic-gate /* 22287c478bd9Sstevel@tonic-gate * cookie3 cookie 22297c478bd9Sstevel@tonic-gate */ 22307c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off)) 22317c478bd9Sstevel@tonic-gate return (FALSE); 22327c478bd9Sstevel@tonic-gate objp->loff = dp->d_off; 22337c478bd9Sstevel@tonic-gate 22347c478bd9Sstevel@tonic-gate outcount += this_reclen; 22357c478bd9Sstevel@tonic-gate dp = (dirent64_t *)((intptr_t)dp + this_reclen); 22367c478bd9Sstevel@tonic-gate } 22377c478bd9Sstevel@tonic-gate 22387c478bd9Sstevel@tonic-gate objp->size = outcount; 22397c478bd9Sstevel@tonic-gate return (TRUE); 22407c478bd9Sstevel@tonic-gate } 22417c478bd9Sstevel@tonic-gate 22427c478bd9Sstevel@tonic-gate bool_t 22437c478bd9Sstevel@tonic-gate xdr_READDIRPLUS3args(XDR *xdrs, READDIRPLUS3args *objp) 22447c478bd9Sstevel@tonic-gate { 22450a701b1eSRobert Gordon rdma_chunkinfo_t rci; 22460a701b1eSRobert Gordon struct xdr_ops *xops = xdrrdma_xops(); 22470a701b1eSRobert Gordon 22487c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 22497c478bd9Sstevel@tonic-gate return (TRUE); 22507c478bd9Sstevel@tonic-gate 225127242a7cSthurlow switch (xdrs->x_op) { 225227242a7cSthurlow case XDR_FREE: 225327242a7cSthurlow case XDR_ENCODE: 22547c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &objp->dir)) 22557c478bd9Sstevel@tonic-gate return (FALSE); 225627242a7cSthurlow break; 225727242a7cSthurlow case XDR_DECODE: 225827242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->dir)) 225927242a7cSthurlow return (FALSE); 226027242a7cSthurlow break; 226127242a7cSthurlow } 22620a701b1eSRobert Gordon if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) && 22630a701b1eSRobert Gordon xdrs->x_op == XDR_ENCODE) { 22640a701b1eSRobert Gordon rci.rci_type = RCI_REPLY_CHUNK; 22650a701b1eSRobert Gordon rci.rci_len = objp->maxcount; 22660a701b1eSRobert Gordon XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci); 22670a701b1eSRobert Gordon } 22680a701b1eSRobert Gordon 22697c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->cookie)) 22707c478bd9Sstevel@tonic-gate return (FALSE); 22717c478bd9Sstevel@tonic-gate /* 22727c478bd9Sstevel@tonic-gate * cookieverf is really an opaque 8 byte 22737c478bd9Sstevel@tonic-gate * quantity, but we will treat it as a 22747c478bd9Sstevel@tonic-gate * hyper for efficiency, the cost of 22757c478bd9Sstevel@tonic-gate * a byteswap here saves bcopys elsewhere 22767c478bd9Sstevel@tonic-gate */ 22777c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->cookieverf)) 22787c478bd9Sstevel@tonic-gate return (FALSE); 22797c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->dircount)) 22807c478bd9Sstevel@tonic-gate return (FALSE); 22817c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->maxcount)); 22827c478bd9Sstevel@tonic-gate } 22837c478bd9Sstevel@tonic-gate 22847c478bd9Sstevel@tonic-gate /* 22857c478bd9Sstevel@tonic-gate * ENCODE ONLY 22867c478bd9Sstevel@tonic-gate */ 22877c478bd9Sstevel@tonic-gate static bool_t 22887c478bd9Sstevel@tonic-gate xdr_putdirpluslist(XDR *xdrs, READDIRPLUS3resok *objp) 22897c478bd9Sstevel@tonic-gate { 22907c478bd9Sstevel@tonic-gate struct dirent64 *dp; 22917c478bd9Sstevel@tonic-gate char *name; 22927c478bd9Sstevel@tonic-gate int nents; 22937c478bd9Sstevel@tonic-gate bool_t true = TRUE; 22947c478bd9Sstevel@tonic-gate bool_t false = FALSE; 22957c478bd9Sstevel@tonic-gate fileid3 fileid; 22967c478bd9Sstevel@tonic-gate cookie3 cookie; 22977c478bd9Sstevel@tonic-gate entryplus3_info *infop; 22987c478bd9Sstevel@tonic-gate 22997c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_ENCODE) 23007c478bd9Sstevel@tonic-gate return (FALSE); 23017c478bd9Sstevel@tonic-gate 23027c478bd9Sstevel@tonic-gate dp = (struct dirent64 *)objp->reply.entries; 23037c478bd9Sstevel@tonic-gate nents = objp->size; 23047c478bd9Sstevel@tonic-gate infop = objp->infop; 23057c478bd9Sstevel@tonic-gate 23067c478bd9Sstevel@tonic-gate while (nents > 0) { 23077c478bd9Sstevel@tonic-gate if (dp->d_reclen == 0) 23087c478bd9Sstevel@tonic-gate return (FALSE); 23097c478bd9Sstevel@tonic-gate if (dp->d_ino != 0) { 23107c478bd9Sstevel@tonic-gate name = dp->d_name; 23117c478bd9Sstevel@tonic-gate fileid = (fileid3)(dp->d_ino); 23127c478bd9Sstevel@tonic-gate cookie = (cookie3)(dp->d_off); 23137c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &true) || 23147c478bd9Sstevel@tonic-gate !xdr_u_longlong_t(xdrs, &fileid) || 23157c478bd9Sstevel@tonic-gate !xdr_bytes(xdrs, &name, &infop->namelen, ~0) || 23167c478bd9Sstevel@tonic-gate !xdr_u_longlong_t(xdrs, &cookie) || 23177c478bd9Sstevel@tonic-gate !xdr_post_op_attr(xdrs, &infop->attr) || 23187c478bd9Sstevel@tonic-gate !xdr_post_op_fh3(xdrs, &infop->fh)) { 23197c478bd9Sstevel@tonic-gate return (FALSE); 23207c478bd9Sstevel@tonic-gate } 23217c478bd9Sstevel@tonic-gate } 23227c478bd9Sstevel@tonic-gate dp = nextdp(dp); 23237c478bd9Sstevel@tonic-gate infop++; 23247c478bd9Sstevel@tonic-gate nents--; 23257c478bd9Sstevel@tonic-gate } 23267c478bd9Sstevel@tonic-gate 23277c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &false)) 23287c478bd9Sstevel@tonic-gate return (FALSE); 23297c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &objp->reply.eof)) 23307c478bd9Sstevel@tonic-gate return (FALSE); 23317c478bd9Sstevel@tonic-gate return (TRUE); 23327c478bd9Sstevel@tonic-gate } 23337c478bd9Sstevel@tonic-gate 23347c478bd9Sstevel@tonic-gate bool_t 23357c478bd9Sstevel@tonic-gate xdr_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp) 23367c478bd9Sstevel@tonic-gate { 23377c478bd9Sstevel@tonic-gate READDIRPLUS3resok *resokp; 23387c478bd9Sstevel@tonic-gate 23397c478bd9Sstevel@tonic-gate /* 23407c478bd9Sstevel@tonic-gate * ENCODE or FREE only 23417c478bd9Sstevel@tonic-gate */ 23427c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) 23437c478bd9Sstevel@tonic-gate return (FALSE); 23447c478bd9Sstevel@tonic-gate 23457c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 23467c478bd9Sstevel@tonic-gate return (FALSE); 23477c478bd9Sstevel@tonic-gate switch (objp->status) { 23487c478bd9Sstevel@tonic-gate case NFS3_OK: 23497c478bd9Sstevel@tonic-gate /* xdr_READDIRPLUS3resok */ 23507c478bd9Sstevel@tonic-gate resokp = &objp->resok; 23517c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes)) 23527c478bd9Sstevel@tonic-gate return (FALSE); 23537c478bd9Sstevel@tonic-gate /* 23547c478bd9Sstevel@tonic-gate * cookieverf is really an opaque 8 byte 23557c478bd9Sstevel@tonic-gate * quantity, but we will treat it as a 23567c478bd9Sstevel@tonic-gate * hyper for efficiency, the cost of 23577c478bd9Sstevel@tonic-gate * a byteswap here saves bcopys elsewhere 23587c478bd9Sstevel@tonic-gate */ 23597c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf)) 23607c478bd9Sstevel@tonic-gate return (FALSE); 23617c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 23627c478bd9Sstevel@tonic-gate if (!xdr_putdirpluslist(xdrs, resokp)) 23637c478bd9Sstevel@tonic-gate return (FALSE); 23647c478bd9Sstevel@tonic-gate } 23657c478bd9Sstevel@tonic-gate break; 23667c478bd9Sstevel@tonic-gate default: 23677c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes)); 23687c478bd9Sstevel@tonic-gate } 23697c478bd9Sstevel@tonic-gate return (TRUE); 23707c478bd9Sstevel@tonic-gate } 23717c478bd9Sstevel@tonic-gate 23727c478bd9Sstevel@tonic-gate /* 23737c478bd9Sstevel@tonic-gate * Decode readdirplus directly into a dirent64_t and do the DNLC caching. 23747c478bd9Sstevel@tonic-gate */ 23757c478bd9Sstevel@tonic-gate bool_t 23767c478bd9Sstevel@tonic-gate xdr_READDIRPLUS3vres(XDR *xdrs, READDIRPLUS3vres *objp) 23777c478bd9Sstevel@tonic-gate { 23787c478bd9Sstevel@tonic-gate dirent64_t *dp; 23797c478bd9Sstevel@tonic-gate vnode_t *dvp; 23807c478bd9Sstevel@tonic-gate uint_t entries_size; 23817c478bd9Sstevel@tonic-gate int outcount = 0; 23827c478bd9Sstevel@tonic-gate vnode_t *nvp; 23837c478bd9Sstevel@tonic-gate rnode_t *rp; 23847c478bd9Sstevel@tonic-gate post_op_vattr pov; 23857c478bd9Sstevel@tonic-gate vattr_t va; 23867c478bd9Sstevel@tonic-gate 23877c478bd9Sstevel@tonic-gate /* 23887c478bd9Sstevel@tonic-gate * DECODE or FREE only 23897c478bd9Sstevel@tonic-gate */ 23907c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 23917c478bd9Sstevel@tonic-gate return (TRUE); 23927c478bd9Sstevel@tonic-gate 23937c478bd9Sstevel@tonic-gate if (xdrs->x_op != XDR_DECODE) 23947c478bd9Sstevel@tonic-gate return (FALSE); 23957c478bd9Sstevel@tonic-gate 23967c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status)) 23977c478bd9Sstevel@tonic-gate return (FALSE); 23987c478bd9Sstevel@tonic-gate 23997c478bd9Sstevel@tonic-gate if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes)) 24007c478bd9Sstevel@tonic-gate return (FALSE); 24017c478bd9Sstevel@tonic-gate 24027c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 24037c478bd9Sstevel@tonic-gate return (TRUE); 24047c478bd9Sstevel@tonic-gate 24057c478bd9Sstevel@tonic-gate /* 24067c478bd9Sstevel@tonic-gate * cookieverf is really an opaque 8 byte 24077c478bd9Sstevel@tonic-gate * quantity, but we will treat it as a 24087c478bd9Sstevel@tonic-gate * hyper for efficiency, the cost of 24097c478bd9Sstevel@tonic-gate * a byteswap here saves bcopys elsewhere 24107c478bd9Sstevel@tonic-gate */ 24117c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->cookieverf)) 24127c478bd9Sstevel@tonic-gate return (FALSE); 24137c478bd9Sstevel@tonic-gate 24147c478bd9Sstevel@tonic-gate dvp = objp->dir_attributes.fres.vp; 24157c478bd9Sstevel@tonic-gate rp = VTOR(dvp); 24167c478bd9Sstevel@tonic-gate 24177c478bd9Sstevel@tonic-gate pov.fres.vap = &va; 24187c478bd9Sstevel@tonic-gate pov.fres.vp = dvp; 24197c478bd9Sstevel@tonic-gate 24207c478bd9Sstevel@tonic-gate entries_size = objp->entries_size; 24217c478bd9Sstevel@tonic-gate dp = objp->entries; 24227c478bd9Sstevel@tonic-gate 24237c478bd9Sstevel@tonic-gate for (;;) { 24247c478bd9Sstevel@tonic-gate uint_t this_reclen; 24257c478bd9Sstevel@tonic-gate bool_t valid; 24267c478bd9Sstevel@tonic-gate uint_t namlen; 24277c478bd9Sstevel@tonic-gate nfs_fh3 fh; 24287c478bd9Sstevel@tonic-gate int va_valid; 24297c478bd9Sstevel@tonic-gate int fh_valid; 24307c478bd9Sstevel@tonic-gate ino64_t fileid; 24317c478bd9Sstevel@tonic-gate 24327c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&valid)) 24337c478bd9Sstevel@tonic-gate return (FALSE); 24347c478bd9Sstevel@tonic-gate if (!valid) { 24357c478bd9Sstevel@tonic-gate /* 24367c478bd9Sstevel@tonic-gate * We have run out of entries, decode eof. 24377c478bd9Sstevel@tonic-gate */ 24387c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof)) 24397c478bd9Sstevel@tonic-gate return (FALSE); 24407c478bd9Sstevel@tonic-gate 24417c478bd9Sstevel@tonic-gate break; 24427c478bd9Sstevel@tonic-gate } 24437c478bd9Sstevel@tonic-gate 24447c478bd9Sstevel@tonic-gate /* 24457c478bd9Sstevel@tonic-gate * fileid3 fileid 24467c478bd9Sstevel@tonic-gate */ 24477c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid)) 24487c478bd9Sstevel@tonic-gate return (FALSE); 24497c478bd9Sstevel@tonic-gate 24507c478bd9Sstevel@tonic-gate /* 24517c478bd9Sstevel@tonic-gate * filename3 name 24527c478bd9Sstevel@tonic-gate */ 24537c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&namlen)) 24547c478bd9Sstevel@tonic-gate return (FALSE); 24557c478bd9Sstevel@tonic-gate this_reclen = DIRENT64_RECLEN(namlen); 24567c478bd9Sstevel@tonic-gate 24577c478bd9Sstevel@tonic-gate /* 24587c478bd9Sstevel@tonic-gate * If this will overflow buffer, stop decoding 24597c478bd9Sstevel@tonic-gate */ 24607c478bd9Sstevel@tonic-gate if ((outcount + this_reclen) > entries_size) { 24617c478bd9Sstevel@tonic-gate objp->eof = FALSE; 24627c478bd9Sstevel@tonic-gate break; 24637c478bd9Sstevel@tonic-gate } 24647c478bd9Sstevel@tonic-gate dp->d_reclen = this_reclen; 24657c478bd9Sstevel@tonic-gate dp->d_ino = fileid; 24667c478bd9Sstevel@tonic-gate 24677c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, dp->d_name, namlen)) 24687c478bd9Sstevel@tonic-gate return (FALSE); 24697c478bd9Sstevel@tonic-gate bzero(&dp->d_name[namlen], 24707c478bd9Sstevel@tonic-gate DIRENT64_NAMELEN(this_reclen) - namlen); 24717c478bd9Sstevel@tonic-gate 24727c478bd9Sstevel@tonic-gate /* 24737c478bd9Sstevel@tonic-gate * cookie3 cookie 24747c478bd9Sstevel@tonic-gate */ 24757c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off)) 24767c478bd9Sstevel@tonic-gate return (FALSE); 24777c478bd9Sstevel@tonic-gate objp->loff = dp->d_off; 24787c478bd9Sstevel@tonic-gate 24797c478bd9Sstevel@tonic-gate /* 24807c478bd9Sstevel@tonic-gate * post_op_attr name_attributes 24817c478bd9Sstevel@tonic-gate */ 24827c478bd9Sstevel@tonic-gate if (!xdr_post_op_vattr(xdrs, &pov)) 24837c478bd9Sstevel@tonic-gate return (FALSE); 24847c478bd9Sstevel@tonic-gate 24857c478bd9Sstevel@tonic-gate if (pov.attributes == TRUE && 24867c478bd9Sstevel@tonic-gate pov.fres.status == NFS3_OK) 24877c478bd9Sstevel@tonic-gate va_valid = TRUE; 24887c478bd9Sstevel@tonic-gate else 24897c478bd9Sstevel@tonic-gate va_valid = FALSE; 24907c478bd9Sstevel@tonic-gate 24917c478bd9Sstevel@tonic-gate /* 24927c478bd9Sstevel@tonic-gate * post_op_fh3 name_handle 24937c478bd9Sstevel@tonic-gate */ 24947c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int32_t *)&fh_valid)) 24957c478bd9Sstevel@tonic-gate return (FALSE); 24967c478bd9Sstevel@tonic-gate 24977c478bd9Sstevel@tonic-gate /* 24987c478bd9Sstevel@tonic-gate * By definition of the standard fh_valid can be 0 (FALSE) or 24997c478bd9Sstevel@tonic-gate * 1 (TRUE), but we have to account for it being anything else 25007c478bd9Sstevel@tonic-gate * in case some other system didn't follow the standard. Note 25017c478bd9Sstevel@tonic-gate * that this is why the else checks if the fh_valid variable 25027c478bd9Sstevel@tonic-gate * is != FALSE. 25037c478bd9Sstevel@tonic-gate */ 25047c478bd9Sstevel@tonic-gate if (fh_valid == TRUE) { 25057c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &fh)) 25067c478bd9Sstevel@tonic-gate return (FALSE); 25077c478bd9Sstevel@tonic-gate } else { 25087c478bd9Sstevel@tonic-gate if (fh_valid != FALSE) 25097c478bd9Sstevel@tonic-gate return (FALSE); 25107c478bd9Sstevel@tonic-gate } 25117c478bd9Sstevel@tonic-gate 25127c478bd9Sstevel@tonic-gate /* 25137c478bd9Sstevel@tonic-gate * If the name is "." or there are no attributes, 25147c478bd9Sstevel@tonic-gate * don't polute the DNLC with "." entries or files 25157c478bd9Sstevel@tonic-gate * we cannot determine the type for. 25167c478bd9Sstevel@tonic-gate */ 25177c478bd9Sstevel@tonic-gate if (!(namlen == 1 && dp->d_name[0] == '.') && 25187c478bd9Sstevel@tonic-gate va_valid && fh_valid) { 25197c478bd9Sstevel@tonic-gate 25207c478bd9Sstevel@tonic-gate /* 25217c478bd9Sstevel@tonic-gate * Do the DNLC caching 25227c478bd9Sstevel@tonic-gate */ 25237c478bd9Sstevel@tonic-gate nvp = makenfs3node_va(&fh, &va, dvp->v_vfsp, 25247c478bd9Sstevel@tonic-gate objp->time, objp->credentials, 25257c478bd9Sstevel@tonic-gate rp->r_path, dp->d_name); 25267c478bd9Sstevel@tonic-gate dnlc_update(dvp, dp->d_name, nvp); 25277c478bd9Sstevel@tonic-gate VN_RELE(nvp); 25287c478bd9Sstevel@tonic-gate } 25297c478bd9Sstevel@tonic-gate 25307c478bd9Sstevel@tonic-gate outcount += this_reclen; 25317c478bd9Sstevel@tonic-gate dp = (dirent64_t *)((intptr_t)dp + this_reclen); 25327c478bd9Sstevel@tonic-gate } 25337c478bd9Sstevel@tonic-gate 25347c478bd9Sstevel@tonic-gate objp->size = outcount; 25357c478bd9Sstevel@tonic-gate return (TRUE); 25367c478bd9Sstevel@tonic-gate } 25377c478bd9Sstevel@tonic-gate 25387c478bd9Sstevel@tonic-gate bool_t 25397c478bd9Sstevel@tonic-gate xdr_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp) 25407c478bd9Sstevel@tonic-gate { 25417c478bd9Sstevel@tonic-gate FSSTAT3resok *resokp; 25427c478bd9Sstevel@tonic-gate 25437c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 25447c478bd9Sstevel@tonic-gate return (FALSE); 25457c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 25467c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes)); 25477c478bd9Sstevel@tonic-gate 25487c478bd9Sstevel@tonic-gate /* xdr_FSSTAT3resok */ 25497c478bd9Sstevel@tonic-gate resokp = &objp->resok; 25507c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes)) 25517c478bd9Sstevel@tonic-gate return (FALSE); 25527c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &resokp->tbytes)) 25537c478bd9Sstevel@tonic-gate return (FALSE); 25547c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &resokp->fbytes)) 25557c478bd9Sstevel@tonic-gate return (FALSE); 25567c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &resokp->abytes)) 25577c478bd9Sstevel@tonic-gate return (FALSE); 25587c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &resokp->tfiles)) 25597c478bd9Sstevel@tonic-gate return (FALSE); 25607c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &resokp->ffiles)) 25617c478bd9Sstevel@tonic-gate return (FALSE); 25627c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &resokp->afiles)) 25637c478bd9Sstevel@tonic-gate return (FALSE); 25647c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &resokp->invarsec)); 25657c478bd9Sstevel@tonic-gate } 25667c478bd9Sstevel@tonic-gate 25677c478bd9Sstevel@tonic-gate bool_t 25687c478bd9Sstevel@tonic-gate xdr_FSINFO3res(XDR *xdrs, FSINFO3res *objp) 25697c478bd9Sstevel@tonic-gate { 25707c478bd9Sstevel@tonic-gate FSINFO3resok *resokp; 25717c478bd9Sstevel@tonic-gate 25727c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 25737c478bd9Sstevel@tonic-gate return (FALSE); 25747c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) /* xdr_FSSTAT3resfail */ 25757c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes)); 25767c478bd9Sstevel@tonic-gate 25777c478bd9Sstevel@tonic-gate /* xdr_FSINFO3resok */ 25787c478bd9Sstevel@tonic-gate resokp = &objp->resok; 25797c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes)) 25807c478bd9Sstevel@tonic-gate return (FALSE); 25817c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->rtmax)) 25827c478bd9Sstevel@tonic-gate return (FALSE); 25837c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->rtpref)) 25847c478bd9Sstevel@tonic-gate return (FALSE); 25857c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->rtmult)) 25867c478bd9Sstevel@tonic-gate return (FALSE); 25877c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->wtmax)) 25887c478bd9Sstevel@tonic-gate return (FALSE); 25897c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->wtpref)) 25907c478bd9Sstevel@tonic-gate return (FALSE); 25917c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->wtmult)) 25927c478bd9Sstevel@tonic-gate return (FALSE); 25937c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->dtpref)) 25947c478bd9Sstevel@tonic-gate return (FALSE); 25957c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &resokp->maxfilesize)) 25967c478bd9Sstevel@tonic-gate return (FALSE); 25977c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->time_delta.seconds)) 25987c478bd9Sstevel@tonic-gate return (FALSE); 25997c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->time_delta.nseconds)) 26007c478bd9Sstevel@tonic-gate return (FALSE); 26017c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &resokp->properties)); 26027c478bd9Sstevel@tonic-gate } 26037c478bd9Sstevel@tonic-gate 26047c478bd9Sstevel@tonic-gate bool_t 26057c478bd9Sstevel@tonic-gate xdr_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp) 26067c478bd9Sstevel@tonic-gate { 26077c478bd9Sstevel@tonic-gate PATHCONF3resok *resokp; 26087c478bd9Sstevel@tonic-gate 26097c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 26107c478bd9Sstevel@tonic-gate return (FALSE); 26117c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 26127c478bd9Sstevel@tonic-gate return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes)); 26137c478bd9Sstevel@tonic-gate 26147c478bd9Sstevel@tonic-gate /* xdr_PATHCONF3resok */ 26157c478bd9Sstevel@tonic-gate resokp = &objp->resok; 26167c478bd9Sstevel@tonic-gate if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes)) 26177c478bd9Sstevel@tonic-gate return (FALSE); 26187c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->info.link_max)) 26197c478bd9Sstevel@tonic-gate return (FALSE); 26207c478bd9Sstevel@tonic-gate if (!xdr_u_int(xdrs, &resokp->info.name_max)) 26217c478bd9Sstevel@tonic-gate return (FALSE); 26227c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &resokp->info.no_trunc)) 26237c478bd9Sstevel@tonic-gate return (FALSE); 26247c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &resokp->info.chown_restricted)) 26257c478bd9Sstevel@tonic-gate return (FALSE); 26267c478bd9Sstevel@tonic-gate if (!xdr_bool(xdrs, &resokp->info.case_insensitive)) 26277c478bd9Sstevel@tonic-gate return (FALSE); 26287c478bd9Sstevel@tonic-gate return (xdr_bool(xdrs, &resokp->info.case_preserving)); 26297c478bd9Sstevel@tonic-gate } 26307c478bd9Sstevel@tonic-gate 26317c478bd9Sstevel@tonic-gate bool_t 26327c478bd9Sstevel@tonic-gate xdr_COMMIT3args(XDR *xdrs, COMMIT3args *objp) 26337c478bd9Sstevel@tonic-gate { 26347c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 26357c478bd9Sstevel@tonic-gate return (TRUE); 26367c478bd9Sstevel@tonic-gate 263727242a7cSthurlow switch (xdrs->x_op) { 263827242a7cSthurlow case XDR_FREE: 263927242a7cSthurlow case XDR_ENCODE: 26407c478bd9Sstevel@tonic-gate if (!xdr_nfs_fh3(xdrs, &objp->file)) 26417c478bd9Sstevel@tonic-gate return (FALSE); 264227242a7cSthurlow break; 264327242a7cSthurlow case XDR_DECODE: 264427242a7cSthurlow if (!xdr_nfs_fh3_server(xdrs, &objp->file)) 264527242a7cSthurlow return (FALSE); 264627242a7cSthurlow break; 264727242a7cSthurlow } 26487c478bd9Sstevel@tonic-gate if (!xdr_u_longlong_t(xdrs, &objp->offset)) 26497c478bd9Sstevel@tonic-gate return (FALSE); 26507c478bd9Sstevel@tonic-gate return (xdr_u_int(xdrs, &objp->count)); 26517c478bd9Sstevel@tonic-gate } 26527c478bd9Sstevel@tonic-gate 26537c478bd9Sstevel@tonic-gate bool_t 26547c478bd9Sstevel@tonic-gate xdr_COMMIT3res(XDR *xdrs, COMMIT3res *objp) 26557c478bd9Sstevel@tonic-gate { 26567c478bd9Sstevel@tonic-gate COMMIT3resok *resokp; 26577c478bd9Sstevel@tonic-gate 26587c478bd9Sstevel@tonic-gate if (!xdr_enum(xdrs, (enum_t *)&objp->status)) 26597c478bd9Sstevel@tonic-gate return (FALSE); 26607c478bd9Sstevel@tonic-gate if (objp->status != NFS3_OK) 26617c478bd9Sstevel@tonic-gate return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc)); 26627c478bd9Sstevel@tonic-gate 26637c478bd9Sstevel@tonic-gate /* xdr_COMMIT3resok */ 26647c478bd9Sstevel@tonic-gate resokp = &objp->resok; 26657c478bd9Sstevel@tonic-gate if (!xdr_wcc_data(xdrs, &resokp->file_wcc)) 26667c478bd9Sstevel@tonic-gate return (FALSE); 26677c478bd9Sstevel@tonic-gate /* 26687c478bd9Sstevel@tonic-gate * writeverf3 is really an opaque 8 byte 26697c478bd9Sstevel@tonic-gate * quantity, but we will treat it as a 26707c478bd9Sstevel@tonic-gate * hyper for efficiency, the cost of 26717c478bd9Sstevel@tonic-gate * a byteswap here saves bcopys elsewhere 26727c478bd9Sstevel@tonic-gate */ 26737c478bd9Sstevel@tonic-gate return (xdr_u_longlong_t(xdrs, &resokp->verf)); 26747c478bd9Sstevel@tonic-gate } 2675