1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  27 /* All Rights Reserved */
  28 
  29 /*
  30  * Copyright (c) 2013 by Delphix. All rights reserved.
  31  */
  32 
  33 #include <sys/param.h>
  34 #include <sys/types.h>
  35 #include <sys/systm.h>
  36 #include <sys/user.h>
  37 #include <sys/vnode.h>
  38 #include <sys/file.h>
  39 #include <sys/dirent.h>
  40 #include <sys/vfs.h>
  41 #include <sys/stream.h>
  42 #include <sys/strsubr.h>
  43 #include <sys/debug.h>
  44 #include <sys/t_lock.h>
  45 #include <sys/cmn_err.h>
  46 #include <sys/dnlc.h>
  47 #include <sys/cred.h>
  48 #include <sys/time.h>
  49 #include <sys/sdt.h>
  50 
  51 #include <rpc/types.h>
  52 #include <rpc/xdr.h>
  53 
  54 #include <nfs/nfs.h>
  55 #include <nfs/rnode.h>
  56 #include <rpc/rpc_rdma.h>
  57 
  58 /*
  59  * These are the XDR routines used to serialize and deserialize
  60  * the various structures passed as parameters across the network
  61  * between NFS clients and servers.
  62  */
  63 
  64 /*
  65  * XDR null terminated ASCII strings
  66  * xdr_string3 deals with "C strings" - arrays of bytes that are
  67  * terminated by a NULL character.  The parameter cpp references a
  68  * pointer to storage; If the pointer is null, then the necessary
  69  * storage is allocated.  The last parameter is the max allowed length
  70  * of the string as allowed by the system.  The NFS Version 3 protocol
  71  * does not place limits on strings, but the implementation needs to
  72  * place a reasonable limit to avoid problems.
  73  */
  74 bool_t
  75 xdr_string3(XDR *xdrs, char **cpp, uint_t maxsize)
  76 {
  77         char *sp;
  78         uint_t size;
  79         uint_t nodesize;
  80         bool_t mem_alloced = FALSE;
  81 
  82         /*
  83          * first deal with the length since xdr strings are counted-strings
  84          */
  85         sp = *cpp;
  86         switch (xdrs->x_op) {
  87         case XDR_FREE:
  88                 if (sp == NULL || sp == nfs3nametoolong)
  89                         return (TRUE);  /* already free */
  90                 /* FALLTHROUGH */
  91 
  92         case XDR_ENCODE:
  93                 size = (uint_t)strlen(sp);
  94                 break;
  95 
  96         case XDR_DECODE:
  97                 break;
  98         }
  99 
 100         if (!xdr_u_int(xdrs, &size))
 101                 return (FALSE);
 102 
 103         /*
 104          * now deal with the actual bytes
 105          */
 106         switch (xdrs->x_op) {
 107         case XDR_DECODE:
 108                 if (size >= maxsize) {
 109                         *cpp = nfs3nametoolong;
 110                         if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size))
 111                                 return (FALSE);
 112                         return (TRUE);
 113                 }
 114                 nodesize = size + 1;
 115                 if (nodesize == 0)
 116                         return (TRUE);
 117                 if (sp == NULL) {
 118                         sp = kmem_alloc(nodesize, KM_NOSLEEP);
 119                         *cpp = sp;
 120                         if (sp == NULL)
 121                                 return (FALSE);
 122                         mem_alloced = TRUE;
 123                 }
 124                 sp[size] = 0;
 125 
 126                 if (xdr_opaque(xdrs, sp, size)) {
 127                         if (strlen(sp) != size) {
 128                                 if (mem_alloced)
 129                                         kmem_free(sp, nodesize);
 130                                 *cpp = NULL;
 131                                 return (FALSE);
 132                         }
 133                 } else {
 134                         if (mem_alloced)
 135                                 kmem_free(sp, nodesize);
 136                         *cpp = NULL;
 137                         return (FALSE);
 138                 }
 139                 return (TRUE);
 140 
 141         case XDR_ENCODE:
 142                 return (xdr_opaque(xdrs, sp, size));
 143 
 144         case XDR_FREE:
 145                 nodesize = size + 1;
 146                 kmem_free(sp, nodesize);
 147                 *cpp = NULL;
 148                 return (TRUE);
 149         }
 150 
 151         return (FALSE);
 152 }
 153 
 154 /*
 155  * XDR_INLINE decode a filehandle.
 156  */
 157 bool_t
 158 xdr_inline_decode_nfs_fh3(uint32_t *ptr, nfs_fh3 *fhp, uint32_t fhsize)
 159 {
 160         uchar_t *bp = (uchar_t *)ptr;
 161         uchar_t *cp;
 162         uint32_t dsize;
 163         uintptr_t resid;
 164 
 165         /*
 166          * Check to see if what the client sent us is bigger or smaller
 167          * than what we can ever possibly send out. NFS_FHMAXDATA is
 168          * unfortunately badly named as it is no longer the max and is
 169          * really the min of what is sent over the wire.
 170          */
 171         if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) +
 172             sizeof (ushort_t) + NFS_FHMAXDATA +
 173             sizeof (ushort_t) + NFS_FHMAXDATA)) {
 174                 return (FALSE);
 175         }
 176 
 177         /*
 178          * All internal parts of a filehandle are in native byte order.
 179          *
 180          * Decode what should be fh3_fsid, it is aligned.
 181          */
 182         fhp->fh3_fsid.val[0] = *(uint32_t *)bp;
 183         bp += BYTES_PER_XDR_UNIT;
 184         fhp->fh3_fsid.val[1] = *(uint32_t *)bp;
 185         bp += BYTES_PER_XDR_UNIT;
 186 
 187         /*
 188          * Decode what should be fh3_len.  fh3_len is two bytes, so we're
 189          * unaligned now.
 190          */
 191         cp = (uchar_t *)&fhp->fh3_len;
 192         *cp++ = *bp++;
 193         *cp++ = *bp++;
 194         fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
 195 
 196         /*
 197          * For backwards compatability, the fid length may be less than
 198          * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
 199          */
 200         dsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len;
 201 
 202         /*
 203          * Make sure the client isn't sending us a bogus length for fh3x_data.
 204          */
 205         if (fhsize < dsize)
 206                 return (FALSE);
 207         bcopy(bp, fhp->fh3_data, dsize);
 208         bp += dsize;
 209         fhsize -= dsize;
 210 
 211         if (fhsize < sizeof (ushort_t))
 212                 return (FALSE);
 213         cp = (uchar_t *)&fhp->fh3_xlen;
 214         *cp++ = *bp++;
 215         *cp++ = *bp++;
 216         fhsize -= sizeof (ushort_t);
 217 
 218         dsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen;
 219 
 220         /*
 221          * Make sure the client isn't sending us a bogus length for fh3x_xdata.
 222          */
 223         if (fhsize < dsize)
 224                 return (FALSE);
 225         bcopy(bp, fhp->fh3_xdata, dsize);
 226         fhsize -= dsize;
 227         bp += dsize;
 228 
 229         /*
 230          * We realign things on purpose, so skip any padding
 231          */
 232         resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
 233         if (resid != 0) {
 234                 if (fhsize < (BYTES_PER_XDR_UNIT - resid))
 235                         return (FALSE);
 236                 bp += BYTES_PER_XDR_UNIT - resid;
 237                 fhsize -= BYTES_PER_XDR_UNIT - resid;
 238         }
 239 
 240         /*
 241          * Make sure client didn't send extra bytes
 242          */
 243         if (fhsize != 0)
 244                 return (FALSE);
 245         return (TRUE);
 246 }
 247 
 248 static bool_t
 249 xdr_decode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
 250 {
 251         uint32_t fhsize;                /* filehandle size */
 252         uint32_t bufsize;
 253         rpc_inline_t *ptr;
 254         uchar_t *bp;
 255 
 256         ASSERT(xdrs->x_op == XDR_DECODE);
 257 
 258         /*
 259          * Retrieve the filehandle length.
 260          */
 261         if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
 262                 return (FALSE);
 263 
 264         bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
 265         objp->fh3_length = 0;
 266 
 267         /*
 268          * Check to see if what the client sent us is bigger or smaller
 269          * than what we can ever possibly send out. NFS_FHMAXDATA is
 270          * unfortunately badly named as it is no longer the max and is
 271          * really the min of what is sent over the wire.
 272          */
 273         if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) +
 274             sizeof (ushort_t) + NFS_FHMAXDATA +
 275             sizeof (ushort_t) + NFS_FHMAXDATA)) {
 276                 if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
 277                         return (FALSE);
 278                 return (TRUE);
 279         }
 280 
 281         /*
 282          * bring in fhsize plus any padding
 283          */
 284         bufsize = RNDUP(fhsize);
 285         ptr = XDR_INLINE(xdrs, bufsize);
 286         bp = (uchar_t *)ptr;
 287         if (ptr == NULL) {
 288                 bp = kmem_alloc(bufsize, KM_SLEEP);
 289                 if (!xdr_opaque(xdrs, (char *)bp, bufsize)) {
 290                         kmem_free(bp, bufsize);
 291                         return (FALSE);
 292                 }
 293         }
 294 
 295         objp->fh3_length = sizeof (fhandle3_t);
 296 
 297         if (xdr_inline_decode_nfs_fh3((uint32_t *)bp, objp, fhsize) == FALSE) {
 298                 /*
 299                  * If in the process of decoding we find the file handle
 300                  * is not correctly formed, we need to continue decoding
 301                  * and trigger an NFS layer error. Set the nfs_fh3_len to
 302                  * zero so it gets caught as a bad length.
 303                  */
 304                 bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
 305                 objp->fh3_length = 0;
 306         }
 307 
 308         if (ptr == NULL)
 309                 kmem_free(bp, bufsize);
 310         return (TRUE);
 311 }
 312 
 313 /*
 314  * XDR_INLINE encode a filehandle.
 315  */
 316 bool_t
 317 xdr_inline_encode_nfs_fh3(uint32_t **ptrp, uint32_t *ptr_redzone,
 318         nfs_fh3 *fhp)
 319 {
 320         uint32_t *ptr = *ptrp;
 321         uchar_t *cp;
 322         uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
 323         uint32_t padword;
 324 
 325         fsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len;
 326         xsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen;
 327 
 328         /*
 329          * First get the initial and variable sized part of the filehandle.
 330          */
 331         otw_len = sizeof (fhp->fh3_fsid) +
 332             sizeof (fhp->fh3_len) + fsize +
 333             sizeof (fhp->fh3_xlen) + xsize;
 334 
 335         /*
 336          * Round out to a full word.
 337          */
 338         otw_len = RNDUP(otw_len);
 339         padword = (otw_len / BYTES_PER_XDR_UNIT);       /* includes fhlen */
 340 
 341         /*
 342          * Make sure we don't exceed our buffer.
 343          */
 344         if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone)
 345                 return (FALSE);
 346 
 347         /*
 348          * Zero out the pading.
 349          */
 350         ptr[padword] = 0;
 351 
 352         IXDR_PUT_U_INT32(ptr, otw_len);
 353 
 354         /*
 355          * The rest of the filehandle is in native byteorder
 356          */
 357         /* fh3_fsid */
 358         *ptr++ = (uint32_t)fhp->fh3_fsid.val[0];
 359         *ptr++ = (uint32_t)fhp->fh3_fsid.val[1];
 360 
 361         /*
 362          * Since the next pieces are unaligned, we need to
 363          * do bytewise copies.
 364          */
 365         cp = (uchar_t *)ptr;
 366 
 367         /* fh3_len + fh3_data */
 368         bcopy(&fhp->fh3_len, cp, sizeof (fhp->fh3_len) + fsize);
 369         cp += sizeof (fhp->fh3_len) + fsize;
 370 
 371         /* fh3_xlen + fh3_xdata */
 372         bcopy(&fhp->fh3_xlen, cp, sizeof (fhp->fh3_xlen) + xsize);
 373         cp += sizeof (fhp->fh3_xlen) + xsize;
 374 
 375         /* do necessary rounding/padding */
 376         cp = (uchar_t *)RNDUP((uintptr_t)cp);
 377         ptr = (uint32_t *)cp;
 378 
 379         /*
 380          * With the above padding, we're word aligned again.
 381          */
 382         ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0);
 383 
 384         *ptrp = ptr;
 385 
 386         return (TRUE);
 387 }
 388 
 389 static bool_t
 390 xdr_encode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
 391 {
 392         uint_t otw_len, fsize, xsize;   /* otw, file, and export sizes */
 393         bool_t ret;
 394         rpc_inline_t *ptr;
 395         rpc_inline_t *buf = NULL;
 396         uint32_t *ptr_redzone;
 397 
 398         ASSERT(xdrs->x_op == XDR_ENCODE);
 399 
 400         fsize = objp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_len;
 401         xsize = objp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_xlen;
 402 
 403         /*
 404          * First get the over the wire size, it is the 4 bytes
 405          * for the length, plus the combined size of the
 406          * file handle components.
 407          */
 408         otw_len = BYTES_PER_XDR_UNIT + sizeof (objp->fh3_fsid) +
 409             sizeof (objp->fh3_len) + fsize +
 410             sizeof (objp->fh3_xlen) + xsize;
 411         /*
 412          * Round out to a full word.
 413          */
 414         otw_len = RNDUP(otw_len);
 415 
 416         /*
 417          * Next try to inline the XDR stream, if that fails (rare)
 418          * allocate a buffer to encode the file handle and then
 419          * copy it using xdr_opaque and free the buffer.
 420          */
 421         ptr = XDR_INLINE(xdrs, otw_len);
 422         if (ptr == NULL)
 423                 ptr = buf = kmem_alloc(otw_len, KM_SLEEP);
 424 
 425         ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT));
 426         ret = xdr_inline_encode_nfs_fh3((uint32_t **)&ptr, ptr_redzone, objp);
 427 
 428         if (buf != NULL) {
 429                 if (ret == TRUE)
 430                         ret = xdr_opaque(xdrs, (char *)buf, otw_len);
 431                 kmem_free(buf, otw_len);
 432         }
 433         return (ret);
 434 }
 435 
 436 /*
 437  * XDR a NFSv3 filehandle the naive way.
 438  */
 439 bool_t
 440 xdr_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
 441 {
 442         if (xdrs->x_op == XDR_FREE)
 443                 return (TRUE);
 444 
 445         if (!xdr_u_int(xdrs, &objp->fh3_length))
 446                 return (FALSE);
 447 
 448         if (objp->fh3_length > NFS3_FHSIZE)
 449                 return (FALSE);
 450 
 451         return (xdr_opaque(xdrs, objp->fh3_u.data, objp->fh3_length));
 452 }
 453 
 454 /*
 455  * XDR a NFSv3 filehandle with intelligence on the server.
 456  * Encoding goes from our in-memory structure to wire format.
 457  * Decoding goes from wire format to our in-memory structure.
 458  */
 459 bool_t
 460 xdr_nfs_fh3_server(XDR *xdrs, nfs_fh3 *objp)
 461 {
 462         switch (xdrs->x_op) {
 463         case XDR_ENCODE:
 464                 if (objp->fh3_flags & FH_WEBNFS)
 465                         return (xdr_nfs_fh3(xdrs, objp));
 466                 else
 467                         return (xdr_encode_nfs_fh3(xdrs, objp));
 468         case XDR_DECODE:
 469                 return (xdr_decode_nfs_fh3(xdrs, objp));
 470         case XDR_FREE:
 471                 if (objp->fh3_u.data != NULL)
 472                         bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
 473                 return (TRUE);
 474         }
 475         return (FALSE);
 476 }
 477 
 478 bool_t
 479 xdr_diropargs3(XDR *xdrs, diropargs3 *objp)
 480 {
 481         switch (xdrs->x_op) {
 482         case XDR_FREE:
 483         case XDR_ENCODE:
 484                 if (!xdr_nfs_fh3(xdrs, objp->dirp))
 485                         return (FALSE);
 486                 break;
 487         case XDR_DECODE:
 488                 if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
 489                         return (FALSE);
 490                 break;
 491         }
 492         return (xdr_string3(xdrs, &objp->name, MAXNAMELEN));
 493 }
 494 
 495 static bool_t
 496 xdr_fattr3(XDR *xdrs, fattr3 *na)
 497 {
 498         int32_t *ptr;
 499 
 500         if (xdrs->x_op == XDR_FREE)
 501                 return (TRUE);
 502 
 503         ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
 504         if (ptr != NULL) {
 505                 if (xdrs->x_op == XDR_DECODE) {
 506                         na->type = IXDR_GET_ENUM(ptr, enum ftype3);
 507                         na->mode = IXDR_GET_U_INT32(ptr);
 508                         na->nlink = IXDR_GET_U_INT32(ptr);
 509                         na->uid = IXDR_GET_U_INT32(ptr);
 510                         na->gid = IXDR_GET_U_INT32(ptr);
 511                         IXDR_GET_U_HYPER(ptr, na->size);
 512                         IXDR_GET_U_HYPER(ptr, na->used);
 513                         na->rdev.specdata1 = IXDR_GET_U_INT32(ptr);
 514                         na->rdev.specdata2 = IXDR_GET_U_INT32(ptr);
 515                         IXDR_GET_U_HYPER(ptr, na->fsid);
 516                         IXDR_GET_U_HYPER(ptr, na->fileid);
 517                         na->atime.seconds = IXDR_GET_U_INT32(ptr);
 518                         na->atime.nseconds = IXDR_GET_U_INT32(ptr);
 519                         na->mtime.seconds = IXDR_GET_U_INT32(ptr);
 520                         na->mtime.nseconds = IXDR_GET_U_INT32(ptr);
 521                         na->ctime.seconds = IXDR_GET_U_INT32(ptr);
 522                         na->ctime.nseconds = IXDR_GET_U_INT32(ptr);
 523                 } else {
 524                         IXDR_PUT_ENUM(ptr, na->type);
 525                         IXDR_PUT_U_INT32(ptr, na->mode);
 526                         IXDR_PUT_U_INT32(ptr, na->nlink);
 527                         IXDR_PUT_U_INT32(ptr, na->uid);
 528                         IXDR_PUT_U_INT32(ptr, na->gid);
 529                         IXDR_PUT_U_HYPER(ptr, na->size);
 530                         IXDR_PUT_U_HYPER(ptr, na->used);
 531                         IXDR_PUT_U_INT32(ptr, na->rdev.specdata1);
 532                         IXDR_PUT_U_INT32(ptr, na->rdev.specdata2);
 533                         IXDR_PUT_U_HYPER(ptr, na->fsid);
 534                         IXDR_PUT_U_HYPER(ptr, na->fileid);
 535                         IXDR_PUT_U_INT32(ptr, na->atime.seconds);
 536                         IXDR_PUT_U_INT32(ptr, na->atime.nseconds);
 537                         IXDR_PUT_U_INT32(ptr, na->mtime.seconds);
 538                         IXDR_PUT_U_INT32(ptr, na->mtime.nseconds);
 539                         IXDR_PUT_U_INT32(ptr, na->ctime.seconds);
 540                         IXDR_PUT_U_INT32(ptr, na->ctime.nseconds);
 541                 }
 542                 return (TRUE);
 543         }
 544         if (!(xdr_enum(xdrs, (enum_t *)&na->type) &&
 545             xdr_u_int(xdrs, &na->mode) &&
 546             xdr_u_int(xdrs, &na->nlink) &&
 547             xdr_u_int(xdrs, &na->uid) &&
 548             xdr_u_int(xdrs, &na->gid) &&
 549             xdr_u_longlong_t(xdrs, &na->size) &&
 550             xdr_u_longlong_t(xdrs, &na->used) &&
 551             xdr_u_int(xdrs, &na->rdev.specdata1) &&
 552             xdr_u_int(xdrs, &na->rdev.specdata2) &&
 553             xdr_u_longlong_t(xdrs, &na->fsid) &&
 554             xdr_u_longlong_t(xdrs, &na->fileid) &&
 555             xdr_u_int(xdrs, &na->atime.seconds) &&
 556             xdr_u_int(xdrs, &na->atime.nseconds) &&
 557             xdr_u_int(xdrs, &na->mtime.seconds) &&
 558             xdr_u_int(xdrs, &na->mtime.nseconds) &&
 559             xdr_u_int(xdrs, &na->ctime.seconds) &&
 560             xdr_u_int(xdrs, &na->ctime.nseconds)))
 561                         return (FALSE);
 562         return (TRUE);
 563 }
 564 
 565 /*
 566  * Fast decode of an fattr3 to a vattr
 567  * Only return FALSE on decode error, all other fattr to vattr translation
 568  * failures set status.
 569  *
 570  * Callers must catch the following errors:
 571  *      EFBIG - file size will not fit in va_size
 572  *      EOVERFLOW - time will not fit in va_*time
 573  */
 574 static bool_t
 575 xdr_fattr3_to_vattr(XDR *xdrs, fattr3_res *objp)
 576 {
 577         int32_t *ptr;
 578         size3 used;
 579         specdata3 rdev;
 580         uint32_t ntime;
 581         vattr_t *vap = objp->vap;
 582 
 583         /*
 584          * DECODE only
 585          */
 586         ASSERT(xdrs->x_op == XDR_DECODE);
 587 
 588         /* On success, all attributes will be decoded */
 589         vap->va_mask = AT_ALL;
 590 
 591         objp->status = 0;
 592         ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
 593         if (ptr != NULL) {
 594                 /*
 595                  * Common case
 596                  */
 597                 vap->va_type = IXDR_GET_ENUM(ptr, enum vtype);
 598                 if ((ftype3)vap->va_type < NF3REG ||
 599                     (ftype3)vap->va_type > NF3FIFO)
 600                         vap->va_type = VBAD;
 601                 else
 602                         vap->va_type = nf3_to_vt[vap->va_type];
 603                 vap->va_mode = IXDR_GET_U_INT32(ptr);
 604                 vap->va_nlink = IXDR_GET_U_INT32(ptr);
 605                 vap->va_uid = (uid_t)IXDR_GET_U_INT32(ptr);
 606                 if (vap->va_uid == NFS_UID_NOBODY)
 607                         vap->va_uid = UID_NOBODY;
 608                 vap->va_gid = (gid_t)IXDR_GET_U_INT32(ptr);
 609                 if (vap->va_gid == NFS_GID_NOBODY)
 610                         vap->va_gid = GID_NOBODY;
 611                 IXDR_GET_U_HYPER(ptr, vap->va_size);
 612                 /*
 613                  * If invalid size, stop decode, set status, and
 614                  * return TRUE, x_handy will be correct, caller must ignore vap.
 615                  */
 616                 if (!NFS3_SIZE_OK(vap->va_size)) {
 617                         objp->status = EFBIG;
 618                         return (TRUE);
 619                 }
 620                 IXDR_GET_U_HYPER(ptr, used);
 621                 rdev.specdata1 = IXDR_GET_U_INT32(ptr);
 622                 rdev.specdata2 = IXDR_GET_U_INT32(ptr);
 623                 /* fsid is ignored */
 624                 ptr += 2;
 625                 IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
 626 
 627                 /*
 628                  * nfs protocol defines times as unsigned so don't
 629                  * extend sign, unless sysadmin set nfs_allow_preepoch_time.
 630                  * The inline macros do the equivilant of NFS_TIME_T_CONVERT
 631                  */
 632                 if (nfs_allow_preepoch_time) {
 633                         vap->va_atime.tv_sec = IXDR_GET_INT32(ptr);
 634                         vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
 635                         vap->va_mtime.tv_sec = IXDR_GET_INT32(ptr);
 636                         vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
 637                         vap->va_ctime.tv_sec = IXDR_GET_INT32(ptr);
 638                         vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
 639                 } else {
 640                         /*
 641                          * Check if the time would overflow on 32-bit
 642                          */
 643                         ntime = IXDR_GET_U_INT32(ptr);
 644                         /*CONSTCOND*/
 645                         if (NFS3_TIME_OVERFLOW(ntime)) {
 646                                 objp->status = EOVERFLOW;
 647                                 return (TRUE);
 648                         }
 649                         vap->va_atime.tv_sec = ntime;
 650                         vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
 651 
 652                         ntime = IXDR_GET_U_INT32(ptr);
 653                         /*CONSTCOND*/
 654                         if (NFS3_TIME_OVERFLOW(ntime)) {
 655                                 objp->status = EOVERFLOW;
 656                                 return (TRUE);
 657                         }
 658                         vap->va_mtime.tv_sec = ntime;
 659                         vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
 660 
 661                         ntime = IXDR_GET_U_INT32(ptr);
 662                         /*CONSTCOND*/
 663                         if (NFS3_TIME_OVERFLOW(ntime)) {
 664                                 objp->status = EOVERFLOW;
 665                                 return (TRUE);
 666                         }
 667                         vap->va_ctime.tv_sec = ntime;
 668                         vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
 669                 }
 670 
 671         } else {
 672                 uint64 fsid;
 673 
 674                 /*
 675                  * Slow path
 676                  */
 677                 if (!(xdr_enum(xdrs, (enum_t *)&vap->va_type) &&
 678                     xdr_u_int(xdrs, &vap->va_mode) &&
 679                     xdr_u_int(xdrs, &vap->va_nlink) &&
 680                     xdr_u_int(xdrs, (uint_t *)&vap->va_uid) &&
 681                     xdr_u_int(xdrs, (uint_t *)&vap->va_gid) &&
 682                     xdr_u_longlong_t(xdrs, &vap->va_size) &&
 683                     xdr_u_longlong_t(xdrs, &used) &&
 684                     xdr_u_int(xdrs, &rdev.specdata1) &&
 685                     xdr_u_int(xdrs, &rdev.specdata2) &&
 686                     xdr_u_longlong_t(xdrs, &fsid) &&        /* ignored */
 687                     xdr_u_longlong_t(xdrs, &vap->va_nodeid)))
 688                                 return (FALSE);
 689 
 690                 if (nfs_allow_preepoch_time) {
 691                         if (!xdr_u_int(xdrs, &ntime))
 692                                 return (FALSE);
 693                         vap->va_atime.tv_sec = (int32_t)ntime;
 694                         if (!xdr_u_int(xdrs, &ntime))
 695                                 return (FALSE);
 696                         vap->va_atime.tv_nsec = ntime;
 697 
 698                         if (!xdr_u_int(xdrs, &ntime))
 699                                 return (FALSE);
 700                         vap->va_mtime.tv_sec = (int32_t)ntime;
 701                         if (!xdr_u_int(xdrs, &ntime))
 702                                 return (FALSE);
 703                         vap->va_mtime.tv_nsec = ntime;
 704 
 705                         if (!xdr_u_int(xdrs, &ntime))
 706                                 return (FALSE);
 707                         vap->va_ctime.tv_sec = (int32_t)ntime;
 708                         if (!xdr_u_int(xdrs, &ntime))
 709                                 return (FALSE);
 710                         vap->va_ctime.tv_nsec = ntime;
 711                 } else {
 712                         /*
 713                          * Check if the time would overflow on 32-bit
 714                          * Set status and keep decoding stream.
 715                          */
 716                         if (!xdr_u_int(xdrs, &ntime))
 717                                 return (FALSE);
 718                         /*CONSTCOND*/
 719                         if (NFS3_TIME_OVERFLOW(ntime)) {
 720                                 objp->status = EOVERFLOW;
 721                         }
 722                         vap->va_atime.tv_sec = ntime;
 723                         if (!xdr_u_int(xdrs, &ntime))
 724                                 return (FALSE);
 725                         vap->va_atime.tv_nsec = ntime;
 726 
 727                         if (!xdr_u_int(xdrs, &ntime))
 728                                 return (FALSE);
 729                         /*CONSTCOND*/
 730                         if (NFS3_TIME_OVERFLOW(ntime)) {
 731                                 objp->status = EOVERFLOW;
 732                         }
 733                         vap->va_mtime.tv_sec = ntime;
 734                         if (!xdr_u_int(xdrs, &ntime))
 735                                 return (FALSE);
 736                         vap->va_mtime.tv_nsec = ntime;
 737 
 738                         if (!xdr_u_int(xdrs, &ntime))
 739                                 return (FALSE);
 740                         /*CONSTCOND*/
 741                         if (NFS3_TIME_OVERFLOW(ntime)) {
 742                                 objp->status = EOVERFLOW;
 743                         }
 744                         vap->va_ctime.tv_sec = ntime;
 745                         if (!xdr_u_int(xdrs, &ntime))
 746                                 return (FALSE);
 747                         vap->va_ctime.tv_nsec = ntime;
 748                 }
 749 
 750                 /*
 751                  * Fixup as needed
 752                  */
 753                 if ((ftype3)vap->va_type < NF3REG ||
 754                     (ftype3)vap->va_type > NF3FIFO)
 755                         vap->va_type = VBAD;
 756                 else
 757                         vap->va_type = nf3_to_vt[vap->va_type];
 758                 if (vap->va_uid == NFS_UID_NOBODY)
 759                         vap->va_uid = UID_NOBODY;
 760                 if (vap->va_gid == NFS_GID_NOBODY)
 761                         vap->va_gid = GID_NOBODY;
 762                 /*
 763                  * If invalid size, set status, and
 764                  * return TRUE, caller must ignore vap.
 765                  */
 766                 if (!NFS3_SIZE_OK(vap->va_size)) {
 767                         objp->status = EFBIG;
 768                         return (TRUE);
 769                 }
 770         }
 771 
 772         /*
 773          * Fill in derived fields
 774          */
 775         vap->va_fsid = objp->vp->v_vfsp->vfs_dev;
 776         vap->va_seq = 0;
 777 
 778         /*
 779          * Common case values
 780          */
 781         vap->va_rdev = 0;
 782         vap->va_blksize = MAXBSIZE;
 783         vap->va_nblocks = 0;
 784 
 785         switch (vap->va_type) {
 786         case VREG:
 787         case VDIR:
 788         case VLNK:
 789                 vap->va_nblocks = (u_longlong_t)
 790                     ((used + (size3)DEV_BSIZE - (size3)1) /
 791                     (size3)DEV_BSIZE);
 792                 break;
 793         case VBLK:
 794                 vap->va_blksize = DEV_BSIZE;
 795                 /* FALLTHRU */
 796         case VCHR:
 797                 vap->va_rdev = makedevice(rdev.specdata1, rdev.specdata2);
 798                 break;
 799         case VSOCK:
 800         case VFIFO:
 801         default:
 802                 break;
 803         }
 804 
 805         return (TRUE);
 806 }
 807 
 808 static bool_t
 809 xdr_post_op_vattr(XDR *xdrs, post_op_vattr *objp)
 810 {
 811         /*
 812          * DECODE only
 813          */
 814         ASSERT(xdrs->x_op == XDR_DECODE);
 815 
 816         if (!xdr_bool(xdrs, &objp->attributes))
 817                 return (FALSE);
 818 
 819         if (objp->attributes == FALSE)
 820                 return (TRUE);
 821 
 822         if (objp->attributes != TRUE)
 823                 return (FALSE);
 824 
 825         if (!xdr_fattr3_to_vattr(xdrs, &objp->fres))
 826                 return (FALSE);
 827 
 828         /*
 829          * The file size may cause an EFBIG or the time values
 830          * may cause EOVERFLOW, if so simply drop the attributes.
 831          */
 832         if (objp->fres.status != NFS3_OK)
 833                 objp->attributes = FALSE;
 834 
 835         return (TRUE);
 836 }
 837 
 838 bool_t
 839 xdr_post_op_attr(XDR *xdrs, post_op_attr *objp)
 840 {
 841         if (!xdr_bool(xdrs, &objp->attributes))
 842                 return (FALSE);
 843 
 844         if (objp->attributes == FALSE)
 845                 return (TRUE);
 846 
 847         if (objp->attributes != TRUE)
 848                 return (FALSE);
 849 
 850         if (!xdr_fattr3(xdrs, &objp->attr))
 851                 return (FALSE);
 852 
 853         /*
 854          * Check that we don't get a file we can't handle through
 855          *      existing interfaces (especially stat64()).
 856          * Decode only check since on encode the data has
 857          * been dealt with in the above call to xdr_fattr3().
 858          */
 859         if (xdrs->x_op == XDR_DECODE) {
 860                 /* Set attrs to false if invalid size or time */
 861                 if (!NFS3_SIZE_OK(objp->attr.size)) {
 862                         objp->attributes = FALSE;
 863                         return (TRUE);
 864                 }
 865 #ifndef _LP64
 866                 if (!NFS3_FATTR_TIME_OK(&objp->attr))
 867                         objp->attributes = FALSE;
 868 #endif
 869         }
 870         return (TRUE);
 871 }
 872 
 873 static bool_t
 874 xdr_wcc_data(XDR *xdrs, wcc_data *objp)
 875 {
 876         int32_t *ptr;
 877         wcc_attr *attrp;
 878 
 879         if (xdrs->x_op == XDR_FREE)
 880                 return (TRUE);
 881 
 882         if (xdrs->x_op == XDR_DECODE) {
 883                 /* pre_op_attr */
 884                 if (!xdr_bool(xdrs, &objp->before.attributes))
 885                         return (FALSE);
 886 
 887                 switch (objp->before.attributes) {
 888                 case TRUE:
 889                         attrp = &objp->before.attr;
 890                         ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
 891                         if (ptr != NULL) {
 892                                 IXDR_GET_U_HYPER(ptr, attrp->size);
 893                                 attrp->mtime.seconds = IXDR_GET_U_INT32(ptr);
 894                                 attrp->mtime.nseconds = IXDR_GET_U_INT32(ptr);
 895                                 attrp->ctime.seconds = IXDR_GET_U_INT32(ptr);
 896                                 attrp->ctime.nseconds = IXDR_GET_U_INT32(ptr);
 897                         } else {
 898                                 if (!xdr_u_longlong_t(xdrs, &attrp->size))
 899                                         return (FALSE);
 900                                 if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
 901                                         return (FALSE);
 902                                 if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
 903                                         return (FALSE);
 904                                 if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
 905                                         return (FALSE);
 906                                 if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
 907                                         return (FALSE);
 908                         }
 909 
 910 #ifndef _LP64
 911                         /*
 912                          * check time overflow.
 913                          */
 914                         if (!NFS3_TIME_OK(attrp->mtime.seconds) ||
 915                             !NFS3_TIME_OK(attrp->ctime.seconds))
 916                                 objp->before.attributes = FALSE;
 917 #endif
 918                         break;
 919                 case FALSE:
 920                         break;
 921                 default:
 922                         return (FALSE);
 923                 }
 924         }
 925 
 926         if (xdrs->x_op == XDR_ENCODE) {
 927                 /* pre_op_attr */
 928                 if (!xdr_bool(xdrs, &objp->before.attributes))
 929                         return (FALSE);
 930 
 931                 switch (objp->before.attributes) {
 932                 case TRUE:
 933                         attrp = &objp->before.attr;
 934 
 935                         ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
 936                         if (ptr != NULL) {
 937                                 IXDR_PUT_U_HYPER(ptr, attrp->size);
 938                                 IXDR_PUT_U_INT32(ptr, attrp->mtime.seconds);
 939                                 IXDR_PUT_U_INT32(ptr, attrp->mtime.nseconds);
 940                                 IXDR_PUT_U_INT32(ptr, attrp->ctime.seconds);
 941                                 IXDR_PUT_U_INT32(ptr, attrp->ctime.nseconds);
 942                         } else {
 943                                 if (!xdr_u_longlong_t(xdrs, &attrp->size))
 944                                         return (FALSE);
 945                                 if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
 946                                         return (FALSE);
 947                                 if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
 948                                         return (FALSE);
 949                                 if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
 950                                         return (FALSE);
 951                                 if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
 952                                         return (FALSE);
 953                         }
 954                         break;
 955                 case FALSE:
 956                         break;
 957                 default:
 958                         return (FALSE);
 959                 }
 960         }
 961         return (xdr_post_op_attr(xdrs, &objp->after));
 962 }
 963 
 964 bool_t
 965 xdr_post_op_fh3(XDR *xdrs, post_op_fh3 *objp)
 966 {
 967         if (!xdr_bool(xdrs, &objp->handle_follows))
 968                 return (FALSE);
 969         switch (objp->handle_follows) {
 970         case TRUE:
 971                 switch (xdrs->x_op) {
 972                 case XDR_ENCODE:
 973                         if (!xdr_nfs_fh3_server(xdrs, &objp->handle))
 974                                 return (FALSE);
 975                         break;
 976                 case XDR_FREE:
 977                 case XDR_DECODE:
 978                         if (!xdr_nfs_fh3(xdrs, &objp->handle))
 979                                 return (FALSE);
 980                         break;
 981                 }
 982                 return (TRUE);
 983         case FALSE:
 984                 return (TRUE);
 985         default:
 986                 return (FALSE);
 987         }
 988 }
 989 
 990 static bool_t
 991 xdr_sattr3(XDR *xdrs, sattr3 *objp)
 992 {
 993         /* set_mode3 */
 994         if (!xdr_bool(xdrs, &objp->mode.set_it))
 995                 return (FALSE);
 996         if (objp->mode.set_it)
 997                 if (!xdr_u_int(xdrs, &objp->mode.mode))
 998                         return (FALSE);
 999         /* set_uid3 */
1000         if (!xdr_bool(xdrs, &objp->uid.set_it))
1001                 return (FALSE);
1002         if (objp->uid.set_it)
1003                 if (!xdr_u_int(xdrs, &objp->uid.uid))
1004                         return (FALSE);
1005         /* set_gid3 */
1006         if (!xdr_bool(xdrs, &objp->gid.set_it))
1007                 return (FALSE);
1008         if (objp->gid.set_it)
1009                 if (!xdr_u_int(xdrs, &objp->gid.gid))
1010                         return (FALSE);
1011 
1012         /* set_size3 */
1013         if (!xdr_bool(xdrs, &objp->size.set_it))
1014                 return (FALSE);
1015         if (objp->size.set_it)
1016                 if (!xdr_u_longlong_t(xdrs, &objp->size.size))
1017                         return (FALSE);
1018 
1019         /* set_atime */
1020         if (!xdr_enum(xdrs, (enum_t *)&objp->atime.set_it))
1021                 return (FALSE);
1022         if (objp->atime.set_it == SET_TO_CLIENT_TIME) {
1023                 if (!xdr_u_int(xdrs, &objp->atime.atime.seconds))
1024                         return (FALSE);
1025                 if (!xdr_u_int(xdrs, &objp->atime.atime.nseconds))
1026                         return (FALSE);
1027         }
1028 
1029         /* set_mtime */
1030         if (!xdr_enum(xdrs, (enum_t *)&objp->mtime.set_it))
1031                 return (FALSE);
1032         if (objp->mtime.set_it == SET_TO_CLIENT_TIME) {
1033                 if (!xdr_u_int(xdrs, &objp->mtime.mtime.seconds))
1034                         return (FALSE);
1035                 if (!xdr_u_int(xdrs, &objp->mtime.mtime.nseconds))
1036                         return (FALSE);
1037         }
1038 
1039         return (TRUE);
1040 }
1041 
1042 bool_t
1043 xdr_GETATTR3res(XDR *xdrs, GETATTR3res *objp)
1044 {
1045         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1046                 return (FALSE);
1047         if (objp->status != NFS3_OK)
1048                 return (TRUE);
1049         /* xdr_GETATTR3resok */
1050         return (xdr_fattr3(xdrs, &objp->resok.obj_attributes));
1051 }
1052 
1053 bool_t
1054 xdr_GETATTR3vres(XDR *xdrs, GETATTR3vres *objp)
1055 {
1056         /*
1057          * DECODE or FREE only
1058          */
1059         if (xdrs->x_op == XDR_FREE)
1060                 return (TRUE);
1061 
1062         if (xdrs->x_op != XDR_DECODE)
1063                 return (FALSE);
1064 
1065         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1066                 return (FALSE);
1067 
1068         if (objp->status != NFS3_OK)
1069                 return (TRUE);
1070 
1071         return (xdr_fattr3_to_vattr(xdrs, &objp->fres));
1072 }
1073 
1074 
1075 bool_t
1076 xdr_SETATTR3args(XDR *xdrs, SETATTR3args *objp)
1077 {
1078         switch (xdrs->x_op) {
1079         case XDR_FREE:
1080         case XDR_ENCODE:
1081                 if (!xdr_nfs_fh3(xdrs, &objp->object))
1082                         return (FALSE);
1083                 break;
1084         case XDR_DECODE:
1085                 if (!xdr_nfs_fh3_server(xdrs, &objp->object))
1086                         return (FALSE);
1087                 break;
1088         }
1089         if (!xdr_sattr3(xdrs, &objp->new_attributes))
1090                 return (FALSE);
1091 
1092         /* sattrguard3 */
1093         if (!xdr_bool(xdrs, &objp->guard.check))
1094                 return (FALSE);
1095         switch (objp->guard.check) {
1096         case TRUE:
1097                 if (!xdr_u_int(xdrs, &objp->guard.obj_ctime.seconds))
1098                         return (FALSE);
1099                 return (xdr_u_int(xdrs, &objp->guard.obj_ctime.nseconds));
1100         case FALSE:
1101                 return (TRUE);
1102         default:
1103                 return (FALSE);
1104         }
1105 }
1106 
1107 bool_t
1108 xdr_SETATTR3res(XDR *xdrs, SETATTR3res *objp)
1109 {
1110         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1111                 return (FALSE);
1112         switch (objp->status) {
1113         case NFS3_OK:
1114                 return (xdr_wcc_data(xdrs, &objp->resok.obj_wcc));
1115         default:
1116                 return (xdr_wcc_data(xdrs, &objp->resfail.obj_wcc));
1117         }
1118 }
1119 
1120 bool_t
1121 xdr_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp)
1122 {
1123         LOOKUP3resok *resokp;
1124 
1125         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1126                 return (FALSE);
1127 
1128         if (objp->status != NFS3_OK)
1129                 return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
1130 
1131         /* xdr_LOOKUP3resok */
1132         resokp = &objp->resok;
1133         switch (xdrs->x_op) {
1134         case XDR_ENCODE:
1135                 if (!xdr_nfs_fh3_server(xdrs, &resokp->object))
1136                         return (FALSE);
1137                 break;
1138         case XDR_FREE:
1139         case XDR_DECODE:
1140                 if (!xdr_nfs_fh3(xdrs, &resokp->object))
1141                         return (FALSE);
1142                 break;
1143         }
1144         if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1145                 return (FALSE);
1146         return (xdr_post_op_attr(xdrs, &resokp->dir_attributes));
1147 }
1148 
1149 bool_t
1150 xdr_LOOKUP3vres(XDR *xdrs, LOOKUP3vres *objp)
1151 {
1152         /*
1153          * DECODE or FREE only
1154          */
1155         if (xdrs->x_op == XDR_FREE)
1156                 return (TRUE);
1157 
1158         if (xdrs->x_op != XDR_DECODE)
1159                 return (FALSE);
1160 
1161         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1162                 return (FALSE);
1163 
1164         if (objp->status != NFS3_OK)
1165                 return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
1166 
1167         if (!xdr_nfs_fh3(xdrs, &objp->object))
1168                 return (FALSE);
1169         if (!xdr_post_op_vattr(xdrs, &objp->obj_attributes))
1170                 return (FALSE);
1171         return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
1172 }
1173 
1174 bool_t
1175 xdr_ACCESS3args(XDR *xdrs, ACCESS3args *objp)
1176 {
1177         switch (xdrs->x_op) {
1178         case XDR_FREE:
1179         case XDR_ENCODE:
1180                 if (!xdr_nfs_fh3(xdrs, &objp->object))
1181                         return (FALSE);
1182                 break;
1183         case XDR_DECODE:
1184                 if (!xdr_nfs_fh3_server(xdrs, &objp->object))
1185                         return (FALSE);
1186                 break;
1187         }
1188         return (xdr_u_int(xdrs, &objp->access));
1189 }
1190 
1191 
1192 bool_t
1193 xdr_ACCESS3res(XDR *xdrs, ACCESS3res *objp)
1194 {
1195         ACCESS3resok *resokp;
1196 
1197         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1198                 return (FALSE);
1199         if (objp->status != NFS3_OK)
1200                 return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
1201 
1202         /* xdr_ACCESS3resok */
1203         resokp = &objp->resok;
1204         if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1205                 return (FALSE);
1206         return (xdr_u_int(xdrs, &resokp->access));
1207 }
1208 
1209 bool_t
1210 xdr_READLINK3args(XDR *xdrs,  READLINK3args *objp)
1211 {
1212         rdma_chunkinfo_t rci;
1213         struct xdr_ops *xops = xdrrdma_xops();
1214 
1215         if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
1216             xdrs->x_op == XDR_ENCODE) {
1217                 rci.rci_type = RCI_REPLY_CHUNK;
1218                 rci.rci_len = MAXPATHLEN;
1219                 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1220         }
1221         if (!xdr_nfs_fh3(xdrs, (nfs_fh3 *)objp))
1222                 return (FALSE);
1223         return (TRUE);
1224 }
1225 
1226 bool_t
1227 xdr_READLINK3res(XDR *xdrs, READLINK3res *objp)
1228 {
1229 
1230         READLINK3resok *resokp;
1231 
1232         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1233                 return (FALSE);
1234         if (objp->status != NFS3_OK)
1235                 return (xdr_post_op_attr(xdrs,
1236                     &objp->resfail.symlink_attributes));
1237 
1238         /* xdr_READLINK3resok */
1239         resokp = &objp->resok;
1240         if (!xdr_post_op_attr(xdrs, &resokp->symlink_attributes))
1241                 return (FALSE);
1242         return (xdr_string3(xdrs, &resokp->data, MAXPATHLEN));
1243 }
1244 
1245 bool_t
1246 xdr_READ3args(XDR *xdrs, READ3args *objp)
1247 {
1248         rdma_chunkinfo_t rci;
1249         rdma_wlist_conn_info_t rwci;
1250         struct xdr_ops *xops = xdrrdma_xops();
1251 
1252         switch (xdrs->x_op) {
1253         case XDR_FREE:
1254         case XDR_ENCODE:
1255                 if (!xdr_nfs_fh3(xdrs, &objp->file))
1256                         return (FALSE);
1257                 break;
1258         case XDR_DECODE:
1259                 if (!xdr_nfs_fh3_server(xdrs, &objp->file))
1260                         return (FALSE);
1261                 break;
1262         }
1263         if (!xdr_u_longlong_t(xdrs, &objp->offset))
1264                 return (FALSE);
1265         if (!xdr_u_int(xdrs, &objp->count))
1266                 return (FALSE);
1267 
1268         DTRACE_PROBE1(xdr__i__read3_buf_len, int, objp->count);
1269 
1270         objp->wlist = NULL;
1271 
1272         /* if xdrrdma_sizeof in progress, then store the size */
1273         if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
1274                 rci.rci_type = RCI_WRITE_ADDR_CHUNK;
1275                 rci.rci_len = objp->count;
1276                 (void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1277         }
1278 
1279         if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
1280                 return (TRUE);
1281 
1282         if (xdrs->x_op == XDR_ENCODE) {
1283 
1284                 if (objp->res_uiop != NULL) {
1285                         rci.rci_type = RCI_WRITE_UIO_CHUNK;
1286                         rci.rci_a.rci_uiop = objp->res_uiop;
1287                         rci.rci_len = objp->count;
1288                         rci.rci_clpp = &objp->wlist;
1289                 } else {
1290                         rci.rci_type = RCI_WRITE_ADDR_CHUNK;
1291                         rci.rci_a.rci_addr = objp->res_data_val_alt;
1292                         rci.rci_len = objp->count;
1293                         rci.rci_clpp = &objp->wlist;
1294                 }
1295 
1296                 return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
1297         }
1298 
1299         /* XDR_DECODE case */
1300         (void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
1301         objp->wlist = rwci.rwci_wlist;
1302         objp->conn = rwci.rwci_conn;
1303 
1304         return (TRUE);
1305 }
1306 
1307 bool_t
1308 xdr_READ3res(XDR *xdrs, READ3res *objp)
1309 {
1310         READ3resok *resokp;
1311         bool_t ret;
1312         mblk_t *mp;
1313 
1314         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1315                 return (FALSE);
1316 
1317         if (objp->status != NFS3_OK)
1318                 return (xdr_post_op_attr(xdrs, &objp->resfail.file_attributes));
1319 
1320         resokp = &objp->resok;
1321 
1322         if (xdr_post_op_attr(xdrs, &resokp->file_attributes) == FALSE ||
1323             xdr_u_int(xdrs, &resokp->count) == FALSE ||
1324             xdr_bool(xdrs, &resokp->eof) == FALSE) {
1325                 return (FALSE);
1326         }
1327 
1328         if (xdrs->x_op == XDR_ENCODE) {
1329 
1330                 mp = resokp->data.mp;
1331                 if (mp != NULL) {
1332                         if (xdrs->x_ops == &xdrmblk_ops) {
1333                                 if (xdrmblk_putmblk(xdrs, mp, resokp->count)) {
1334                                         resokp->data.mp = NULL;
1335                                         return (TRUE);
1336                                 } else {
1337                                         return (FALSE);
1338                                 }
1339                         } else if (mp->b_cont != NULL) {
1340                                 /*
1341                                  * We have read results in an mblk chain, but
1342                                  * the encoding operations don't handle mblks
1343                                  * (they'll operate on data.data_val rather
1344                                  * than data.mp).  Because data_val can only
1345                                  * point at a single data buffer, we need to
1346                                  * pullup the read results into a single data
1347                                  * block and reset data_val to point to it.
1348                                  *
1349                                  * This happens with RPC GSS where the wrapping
1350                                  * function does XDR serialization into a
1351                                  * temporary buffer prior to applying GSS.
1352                                  * Because we're not in a performance sensitive
1353                                  * path, the pullupmsg() here shouldn't hurt us
1354                                  * too badly.
1355                                  */
1356                                 if (pullupmsg(mp, -1) == 0)
1357                                         return (FALSE);
1358                                 resokp->data.data_val = (caddr_t)mp->b_rptr;
1359                         }
1360                 } else {
1361                         if (xdr_u_int(xdrs, &resokp->count) == FALSE) {
1362                                 return (FALSE);
1363                         }
1364                         /*
1365                          * If read data sent by wlist (RDMA_WRITE), don't do
1366                          * xdr_bytes() below.   RDMA_WRITE transfers the data.
1367                          * Note: this is encode-only because the client code
1368                          * uses xdr_READ3vres/xdr_READ3uiores to decode results.
1369                          */
1370                         if (resokp->wlist) {
1371                                 if (resokp->count != 0) {
1372                                         return (xdrrdma_send_read_data(
1373                                             xdrs, resokp->count,
1374                                             resokp->wlist));
1375                                 }
1376                                 return (TRUE);
1377                         }
1378                 }
1379                 /*
1380                  * Fall thru for the xdr_bytes()
1381                  *
1382                  * note: the mblk will be freed in
1383                  * rfs3_read_free.
1384                  */
1385         }
1386 
1387         /* no RDMA_WRITE transfer -- send data inline */
1388 
1389         ret = xdr_bytes(xdrs, (char **)&resokp->data.data_val,
1390             &resokp->data.data_len, nfs3tsize());
1391 
1392         return (ret);
1393 }
1394 
1395 bool_t
1396 xdr_READ3vres(XDR *xdrs, READ3vres *objp)
1397 {
1398         count3 ocount;
1399         /*
1400          * DECODE or FREE only
1401          */
1402         if (xdrs->x_op == XDR_FREE)
1403                 return (TRUE);
1404 
1405         if (xdrs->x_op != XDR_DECODE)
1406                 return (FALSE);
1407 
1408         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1409                 return (FALSE);
1410 
1411         if (!xdr_post_op_vattr(xdrs, &objp->pov))
1412                 return (FALSE);
1413 
1414         if (objp->status != NFS3_OK)
1415                 return (TRUE);
1416 
1417         if (!xdr_u_int(xdrs, &objp->count))
1418                 return (FALSE);
1419 
1420         if (!xdr_bool(xdrs, &objp->eof))
1421                 return (FALSE);
1422 
1423         /*
1424          * If read data received via RDMA_WRITE, don't do xdr_bytes().
1425          * RDMA_WRITE already moved the data so decode length of RDMA_WRITE.
1426          */
1427         if (xdrs->x_ops == &xdrrdma_ops) {
1428                 struct clist *cl;
1429 
1430                 XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
1431 
1432                 if (cl) {
1433                         if (!xdr_u_int(xdrs, &ocount)) {
1434                                 return (FALSE);
1435                         }
1436                         if (ocount != objp->count) {
1437                                 DTRACE_PROBE2(xdr__e__read3vres_fail,
1438                                     int, ocount, int, objp->count);
1439                                 objp->wlist = NULL;
1440                                 return (FALSE);
1441                         }
1442 
1443                         objp->wlist_len = clist_len(cl);
1444                         objp->data.data_len = ocount;
1445 
1446                         if (objp->wlist_len !=
1447                             roundup(objp->data.data_len, BYTES_PER_XDR_UNIT)) {
1448                                 DTRACE_PROBE2(
1449                                     xdr__e__read3vres_fail,
1450                                     int, ocount,
1451                                     int, objp->data.data_len);
1452                                 objp->wlist = NULL;
1453                                 return (FALSE);
1454                         }
1455                         return (TRUE);
1456                 }
1457         }
1458 
1459         return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
1460             &objp->data.data_len, nfs3tsize()));
1461 }
1462 
1463 bool_t
1464 xdr_READ3uiores(XDR *xdrs, READ3uiores *objp)
1465 {
1466         count3 ocount;
1467         bool_t attributes;
1468         mblk_t *mp;
1469         size_t n;
1470         int error;
1471         int size = (int)objp->size;
1472         struct uio *uiop = objp->uiop;
1473         int32_t fattr3_len = NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
1474         int32_t *ptr;
1475 
1476         /*
1477          * DECODE or FREE only
1478          */
1479         if (xdrs->x_op == XDR_FREE)
1480                 return (TRUE);
1481 
1482         if (xdrs->x_op != XDR_DECODE)
1483                 return (FALSE);
1484 
1485         if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
1486                 return (FALSE);
1487 
1488         if (!XDR_GETINT32(xdrs, (int32_t *)&attributes))
1489                 return (FALSE);
1490 
1491         /*
1492          * For directio we just skip over attributes if present
1493          */
1494         switch (attributes) {
1495         case TRUE:
1496                 if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fattr3_len))
1497                         return (FALSE);
1498                 break;
1499         case FALSE:
1500                 break;
1501         default:
1502                 return (FALSE);
1503         }
1504 
1505         if (objp->status != NFS3_OK)
1506                 return (TRUE);
1507 
1508         if (!XDR_GETINT32(xdrs, (int32_t *)&objp->count))
1509                 return (FALSE);
1510 
1511         if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
1512                 return (FALSE);
1513 
1514         if (xdrs->x_ops == &xdrmblk_ops) {
1515                 if (!xdrmblk_getmblk(xdrs, &mp, &objp->size))
1516                         return (FALSE);
1517 
1518                 if (objp->size == 0)
1519                         return (TRUE);
1520 
1521                 if (objp->size > size)
1522                         return (FALSE);
1523 
1524                 size = (int)objp->size;
1525                 do {
1526                         n = MIN(size, mp->b_wptr - mp->b_rptr);
1527                         if ((n = MIN(uiop->uio_resid, n)) != 0) {
1528 
1529                                 error = uiomove((char *)mp->b_rptr, n, UIO_READ,
1530                                     uiop);
1531                                 if (error)
1532                                         return (FALSE);
1533                                 mp->b_rptr += n;
1534                                 size -= n;
1535                         }
1536 
1537                         while (mp && (mp->b_rptr >= mp->b_wptr))
1538                                 mp = mp->b_cont;
1539                 } while (mp && size > 0 && uiop->uio_resid > 0);
1540 
1541                 return (TRUE);
1542         }
1543 
1544         if (xdrs->x_ops == &xdrrdma_ops) {
1545                 struct clist *cl;
1546 
1547                 XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
1548 
1549                 objp->wlist = cl;
1550 
1551                 if (objp->wlist) {
1552                         if (!xdr_u_int(xdrs, &ocount)) {
1553                                 objp->wlist = NULL;
1554                                 return (FALSE);
1555                         }
1556 
1557                         if (ocount != objp->count) {
1558                                 DTRACE_PROBE2(xdr__e__read3uiores_fail,
1559                                     int, ocount, int, objp->count);
1560                                 objp->wlist = NULL;
1561                                 return (FALSE);
1562                         }
1563 
1564                         objp->wlist_len = clist_len(cl);
1565 
1566                         uiop->uio_resid -= objp->count;
1567                         uiop->uio_iov->iov_len -= objp->count;
1568                         uiop->uio_iov->iov_base += objp->count;
1569                         uiop->uio_loffset += objp->count;
1570 
1571                         /*
1572                          * XXX: Assume 1 iov, needs to be changed.
1573                          */
1574                         objp->size = objp->count;
1575 
1576                         return (TRUE);
1577                 }
1578         }
1579 
1580         /*
1581          * This isn't an xdrmblk stream nor RDMA.
1582          * Handle the likely case that it can be
1583          * inlined (ex. xdrmem).
1584          */
1585         if (!XDR_GETINT32(xdrs, (int32_t *)&objp->size))
1586                 return (FALSE);
1587 
1588         if (objp->size == 0)
1589                 return (TRUE);
1590 
1591         if (objp->size > size)
1592                 return (FALSE);
1593 
1594         size = (int)objp->size;
1595         if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
1596                 return (uiomove(ptr, size, UIO_READ, uiop) ? FALSE : TRUE);
1597 
1598         /*
1599          * Handle some other (unlikely) stream type that will need a copy.
1600          */
1601         if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
1602                 return (FALSE);
1603 
1604         if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
1605                 kmem_free(ptr, size);
1606                 return (FALSE);
1607         }
1608         error = uiomove(ptr, size, UIO_READ, uiop);
1609         kmem_free(ptr, size);
1610 
1611         return (error ? FALSE : TRUE);
1612 }
1613 
1614 bool_t
1615 xdr_WRITE3args(XDR *xdrs, WRITE3args *objp)
1616 {
1617         switch (xdrs->x_op) {
1618         case XDR_FREE:
1619         case XDR_ENCODE:
1620                 if (!xdr_nfs_fh3(xdrs, &objp->file))
1621                         return (FALSE);
1622                 break;
1623         case XDR_DECODE:
1624                 if (!xdr_nfs_fh3_server(xdrs, &objp->file))
1625                         return (FALSE);
1626                 break;
1627         }
1628         if (!xdr_u_longlong_t(xdrs, &objp->offset))
1629                 return (FALSE);
1630         if (!xdr_u_int(xdrs, &objp->count))
1631                 return (FALSE);
1632         if (!xdr_enum(xdrs, (enum_t *)&objp->stable))
1633                 return (FALSE);
1634 
1635         if (xdrs->x_op == XDR_DECODE) {
1636                 if (xdrs->x_ops == &xdrmblk_ops) {
1637                         if (xdrmblk_getmblk(xdrs, &objp->mblk,
1638                             &objp->data.data_len) == TRUE) {
1639                                 objp->data.data_val = NULL;
1640                                 return (TRUE);
1641                         }
1642                 }
1643                 objp->mblk = NULL;
1644 
1645                 if (xdrs->x_ops == &xdrrdmablk_ops) {
1646                         if (xdrrdma_getrdmablk(xdrs, &objp->rlist,
1647                             &objp->data.data_len,
1648                             &objp->conn, nfs3tsize()) == TRUE) {
1649                                 objp->data.data_val = NULL;
1650                                 if (xdrrdma_read_from_client(
1651                                     objp->rlist,
1652                                     &objp->conn,
1653                                     objp->count) == FALSE) {
1654                                         return (FALSE);
1655                                 }
1656                                 return (TRUE);
1657                         }
1658                 }
1659                 objp->rlist = NULL;
1660 
1661                 /* Else fall thru for the xdr_bytes(). */
1662         }
1663 
1664         if (xdrs->x_op == XDR_FREE) {
1665                 if (objp->rlist != NULL) {
1666                         (void) xdrrdma_free_clist(objp->conn, objp->rlist);
1667                         objp->rlist = NULL;
1668                         objp->data.data_val = NULL;
1669                         return (TRUE);
1670                 }
1671         }
1672 
1673         DTRACE_PROBE1(xdr__i__write3_buf_len,
1674             int, objp->data.data_len);
1675 
1676         return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
1677             &objp->data.data_len, nfs3tsize()));
1678 }
1679 
1680 bool_t
1681 xdr_WRITE3res(XDR *xdrs, WRITE3res *objp)
1682 {
1683         WRITE3resok *resokp;
1684 
1685         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1686                 return (FALSE);
1687         if (objp->status != NFS3_OK) /* xdr_WRITE3resfail */
1688                 return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
1689 
1690         /* xdr_WRITE3resok */
1691         resokp = &objp->resok;
1692         if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
1693                 return (FALSE);
1694         if (!xdr_u_int(xdrs, &resokp->count))
1695                 return (FALSE);
1696         if (!xdr_enum(xdrs, (enum_t *)&resokp->committed))
1697                 return (FALSE);
1698         /*
1699          * writeverf3 is really an opaque 8 byte
1700          * quantity, but we will treat it as a
1701          * hyper for efficiency, the cost of
1702          * a byteswap here saves bcopys elsewhere
1703          */
1704         return (xdr_u_longlong_t(xdrs, &resokp->verf));
1705 }
1706 
1707 bool_t
1708 xdr_CREATE3args(XDR *xdrs, CREATE3args *objp)
1709 {
1710         createhow3 *howp;
1711 
1712         if (!xdr_diropargs3(xdrs, &objp->where))
1713                 return (FALSE);
1714 
1715         /* xdr_createhow3 */
1716         howp = &objp->how;
1717 
1718         if (!xdr_enum(xdrs, (enum_t *)&howp->mode))
1719                 return (FALSE);
1720         switch (howp->mode) {
1721         case UNCHECKED:
1722         case GUARDED:
1723                 return (xdr_sattr3(xdrs, &howp->createhow3_u.obj_attributes));
1724         case EXCLUSIVE:
1725                 /*
1726                  * createverf3 is really an opaque 8 byte
1727                  * quantity, but we will treat it as a
1728                  * hyper for efficiency, the cost of
1729                  * a byteswap here saves bcopys elsewhere
1730                  */
1731                 return (xdr_u_longlong_t(xdrs, &howp->createhow3_u.verf));
1732         default:
1733                 return (FALSE);
1734         }
1735 }
1736 
1737 bool_t
1738 xdr_CREATE3res(XDR *xdrs, CREATE3res *objp)
1739 {
1740         CREATE3resok *resokp;
1741 
1742         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1743                 return (FALSE);
1744         switch (objp->status) {
1745         case NFS3_OK:
1746                 /* xdr_CREATE3resok */
1747                 resokp = &objp->resok;
1748 
1749                 if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1750                         return (FALSE);
1751                 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1752                         return (FALSE);
1753                 return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1754         default:
1755                 /* xdr_CREATE3resfail */
1756                 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1757         }
1758 }
1759 
1760 bool_t
1761 xdr_MKDIR3args(XDR *xdrs, MKDIR3args *objp)
1762 {
1763         if (!xdr_diropargs3(xdrs, &objp->where))
1764                 return (FALSE);
1765         return (xdr_sattr3(xdrs, &objp->attributes));
1766 }
1767 
1768 bool_t
1769 xdr_MKDIR3res(XDR *xdrs, MKDIR3res *objp)
1770 {
1771         MKDIR3resok *resokp;
1772 
1773         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1774                 return (FALSE);
1775         switch (objp->status) {
1776         case NFS3_OK:
1777                 /* xdr_MKDIR3resok */
1778                 resokp = &objp->resok;
1779 
1780                 if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1781                         return (FALSE);
1782                 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1783                         return (FALSE);
1784                 return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1785         default:
1786                 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1787         }
1788 }
1789 
1790 bool_t
1791 xdr_SYMLINK3args(XDR *xdrs, SYMLINK3args *objp)
1792 {
1793         if (!xdr_diropargs3(xdrs, &objp->where))
1794                 return (FALSE);
1795         if (!xdr_sattr3(xdrs, &objp->symlink.symlink_attributes))
1796                 return (FALSE);
1797         return (xdr_string3(xdrs, &objp->symlink.symlink_data, MAXPATHLEN));
1798 }
1799 
1800 bool_t
1801 xdr_SYMLINK3res(XDR *xdrs, SYMLINK3res *objp)
1802 {
1803         SYMLINK3resok *resokp;
1804 
1805         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1806                 return (FALSE);
1807         switch (objp->status) {
1808         case NFS3_OK:
1809                 resokp = &objp->resok;
1810                 /* xdr_SYMLINK3resok */
1811                 if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1812                         return (FALSE);
1813                 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1814                         return (FALSE);
1815                 return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1816         default:
1817                 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1818         }
1819 }
1820 
1821 bool_t
1822 xdr_MKNOD3args(XDR *xdrs, MKNOD3args *objp)
1823 {
1824         mknoddata3 *whatp;
1825         devicedata3 *nod_objp;
1826 
1827         if (!xdr_diropargs3(xdrs, &objp->where))
1828                 return (FALSE);
1829 
1830         whatp = &objp->what;
1831         if (!xdr_enum(xdrs, (enum_t *)&whatp->type))
1832                 return (FALSE);
1833         switch (whatp->type) {
1834         case NF3CHR:
1835         case NF3BLK:
1836                 /* xdr_devicedata3 */
1837                 nod_objp = &whatp->mknoddata3_u.device;
1838                 if (!xdr_sattr3(xdrs, &nod_objp->dev_attributes))
1839                         return (FALSE);
1840                 if (!xdr_u_int(xdrs, &nod_objp->spec.specdata1))
1841                         return (FALSE);
1842                 return (xdr_u_int(xdrs, &nod_objp->spec.specdata2));
1843         case NF3SOCK:
1844         case NF3FIFO:
1845                 return (xdr_sattr3(xdrs, &whatp->mknoddata3_u.pipe_attributes));
1846         default:
1847                 break;
1848         }
1849         return (TRUE);
1850 }
1851 
1852 bool_t
1853 xdr_MKNOD3res(XDR *xdrs, MKNOD3res *objp)
1854 {
1855         MKNOD3resok *resokp;
1856 
1857         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1858                 return (FALSE);
1859         switch (objp->status) {
1860         case NFS3_OK:
1861                 /* xdr_MKNOD3resok */
1862                 resokp = &objp->resok;
1863                 if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1864                         return (FALSE);
1865                 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1866                         return (FALSE);
1867                 return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1868         default:
1869                 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1870         }
1871 }
1872 
1873 bool_t
1874 xdr_REMOVE3res(XDR *xdrs, REMOVE3res *objp)
1875 {
1876         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1877                 return (FALSE);
1878         switch (objp->status) {
1879         case NFS3_OK:
1880                 return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
1881         default:
1882                 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1883         }
1884 }
1885 
1886 bool_t
1887 xdr_RMDIR3res(XDR *xdrs, RMDIR3res *objp)
1888 {
1889         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1890                 return (FALSE);
1891         switch (objp->status) {
1892         case NFS3_OK:
1893                 return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
1894         default:
1895                 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1896         }
1897 }
1898 
1899 bool_t
1900 xdr_RENAME3args(XDR *xdrs, RENAME3args *objp)
1901 {
1902         if (!xdr_diropargs3(xdrs, &objp->from))
1903                 return (FALSE);
1904         return (xdr_diropargs3(xdrs, &objp->to));
1905 }
1906 
1907 bool_t
1908 xdr_RENAME3res(XDR *xdrs, RENAME3res *objp)
1909 {
1910         RENAME3resok *resokp;
1911         RENAME3resfail *resfailp;
1912 
1913         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1914                 return (FALSE);
1915         switch (objp->status) {
1916         case NFS3_OK:
1917                 /* xdr_RENAME3resok */
1918                 resokp = &objp->resok;
1919 
1920                 if (!xdr_wcc_data(xdrs, &resokp->fromdir_wcc))
1921                         return (FALSE);
1922                 return (xdr_wcc_data(xdrs, &resokp->todir_wcc));
1923         default:
1924                 /* xdr_RENAME3resfail */
1925                 resfailp = &objp->resfail;
1926                 if (!xdr_wcc_data(xdrs, &resfailp->fromdir_wcc))
1927                         return (FALSE);
1928                 return (xdr_wcc_data(xdrs, &resfailp->todir_wcc));
1929         }
1930 }
1931 
1932 bool_t
1933 xdr_LINK3args(XDR *xdrs, LINK3args *objp)
1934 {
1935         switch (xdrs->x_op) {
1936         case XDR_FREE:
1937         case XDR_ENCODE:
1938                 if (!xdr_nfs_fh3(xdrs, &objp->file))
1939                         return (FALSE);
1940                 break;
1941         case XDR_DECODE:
1942                 if (!xdr_nfs_fh3_server(xdrs, &objp->file))
1943                         return (FALSE);
1944                 break;
1945         }
1946         return (xdr_diropargs3(xdrs, &objp->link));
1947 }
1948 
1949 bool_t
1950 xdr_LINK3res(XDR *xdrs, LINK3res *objp)
1951 {
1952         LINK3resok *resokp;
1953         LINK3resfail *resfailp;
1954 
1955         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1956                 return (FALSE);
1957         switch (objp->status) {
1958         case NFS3_OK:
1959                 /* xdr_LINK3resok */
1960                 resokp = &objp->resok;
1961                 if (!xdr_post_op_attr(xdrs, &resokp->file_attributes))
1962                         return (FALSE);
1963                 return (xdr_wcc_data(xdrs, &resokp->linkdir_wcc));
1964         default:
1965                 /* xdr_LINK3resfail */
1966                 resfailp = &objp->resfail;
1967                 if (!xdr_post_op_attr(xdrs, &resfailp->file_attributes))
1968                         return (FALSE);
1969                 return (xdr_wcc_data(xdrs, &resfailp->linkdir_wcc));
1970         }
1971 }
1972 
1973 bool_t
1974 xdr_READDIR3args(XDR *xdrs, READDIR3args *objp)
1975 {
1976         rdma_chunkinfo_t rci;
1977         struct xdr_ops *xops = xdrrdma_xops();
1978 
1979         if (xdrs->x_op == XDR_FREE)
1980                 return (TRUE);
1981 
1982         switch (xdrs->x_op) {
1983         case XDR_FREE:
1984         case XDR_ENCODE:
1985                 if (!xdr_nfs_fh3(xdrs, &objp->dir))
1986                         return (FALSE);
1987                 break;
1988         case XDR_DECODE:
1989                 if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
1990                         return (FALSE);
1991                 break;
1992         }
1993         if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
1994             xdrs->x_op == XDR_ENCODE) {
1995                 rci.rci_type = RCI_REPLY_CHUNK;
1996                 rci.rci_len = objp->count;
1997                 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1998         }
1999 
2000         if (!xdr_u_longlong_t(xdrs, &objp->cookie))
2001                 return (FALSE);
2002         /*
2003          * cookieverf is really an opaque 8 byte
2004          * quantity, but we will treat it as a
2005          * hyper for efficiency, the cost of
2006          * a byteswap here saves bcopys elsewhere
2007          */
2008         if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2009                 return (FALSE);
2010         return (xdr_u_int(xdrs, &objp->count));
2011 }
2012 
2013 #ifdef  nextdp
2014 #undef  nextdp
2015 #endif
2016 #define nextdp(dp)      ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
2017 #ifdef  roundup
2018 #undef  roundup
2019 #endif
2020 #define roundup(x, y)   ((((x) + ((y) - 1)) / (y)) * (y))
2021 
2022 /*
2023  * ENCODE ONLY
2024  */
2025 static bool_t
2026 xdr_putdirlist(XDR *xdrs, READDIR3resok *objp)
2027 {
2028         struct dirent64 *dp;
2029         char *name;
2030         int size;
2031         int bufsize;
2032         uint_t namlen;
2033         bool_t true = TRUE;
2034         bool_t false = FALSE;
2035         int entrysz;
2036         int tofit;
2037         fileid3 fileid;
2038         cookie3 cookie;
2039 
2040         if (xdrs->x_op != XDR_ENCODE)
2041                 return (FALSE);
2042 
2043         /*
2044          * bufsize is used to keep track of the size of the response.
2045          * It is primed with:
2046          *      1 for the status +
2047          *      1 for the dir_attributes.attributes boolean +
2048          *      2 for the cookie verifier
2049          * all times BYTES_PER_XDR_UNIT to convert from XDR units
2050          * to bytes.  If there are directory attributes to be
2051          * returned, then:
2052          *      NFS3_SIZEOF_FATTR3 for the dir_attributes.attr fattr3
2053          * time BYTES_PER_XDR_UNIT is added to account for them.
2054          */
2055         bufsize = (1 + 1 + 2) * BYTES_PER_XDR_UNIT;
2056         if (objp->dir_attributes.attributes)
2057                 bufsize += NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
2058         for (size = objp->size, dp = (struct dirent64 *)objp->reply.entries;
2059             size > 0;
2060             size -= dp->d_reclen, dp = nextdp(dp)) {
2061                 if (dp->d_reclen == 0)
2062                         return (FALSE);
2063                 if (dp->d_ino == 0)
2064                         continue;
2065                 name = dp->d_name;
2066                 namlen = (uint_t)strlen(dp->d_name);
2067                 /*
2068                  * An entry is composed of:
2069                  *      1 for the true/false list indicator +
2070                  *      2 for the fileid +
2071                  *      1 for the length of the name +
2072                  *      2 for the cookie +
2073                  * all times BYTES_PER_XDR_UNIT to convert from
2074                  * XDR units to bytes, plus the length of the name
2075                  * rounded up to the nearest BYTES_PER_XDR_UNIT.
2076                  */
2077                 entrysz = (1 + 2 + 1 + 2) * BYTES_PER_XDR_UNIT +
2078                     roundup(namlen, BYTES_PER_XDR_UNIT);
2079                 /*
2080                  * We need to check to see if the number of bytes left
2081                  * to go into the buffer will actually fit into the
2082                  * buffer.  This is calculated as the size of this
2083                  * entry plus:
2084                  *      1 for the true/false list indicator +
2085                  *      1 for the eof indicator
2086                  * times BYTES_PER_XDR_UNIT to convert from from
2087                  * XDR units to bytes.
2088                  */
2089                 tofit = entrysz + (1 + 1) * BYTES_PER_XDR_UNIT;
2090                 if (bufsize + tofit > objp->count) {
2091                         objp->reply.eof = FALSE;
2092                         break;
2093                 }
2094                 fileid = (fileid3)(dp->d_ino);
2095                 cookie = (cookie3)(dp->d_off);
2096                 if (!xdr_bool(xdrs, &true) ||
2097                     !xdr_u_longlong_t(xdrs, &fileid) ||
2098                     !xdr_bytes(xdrs, &name, &namlen, ~0) ||
2099                     !xdr_u_longlong_t(xdrs, &cookie)) {
2100                         return (FALSE);
2101                 }
2102                 bufsize += entrysz;
2103         }
2104         if (!xdr_bool(xdrs, &false))
2105                 return (FALSE);
2106         if (!xdr_bool(xdrs, &objp->reply.eof))
2107                 return (FALSE);
2108         return (TRUE);
2109 }
2110 
2111 bool_t
2112 xdr_READDIR3res(XDR *xdrs, READDIR3res *objp)
2113 {
2114         READDIR3resok *resokp;
2115 
2116         /*
2117          * ENCODE or FREE only
2118          */
2119         if (xdrs->x_op == XDR_DECODE)
2120                 return (FALSE);
2121 
2122         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2123                 return (FALSE);
2124         if (objp->status != NFS3_OK)
2125                 return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
2126 
2127         /* xdr_READDIR3resok */
2128         resokp = &objp->resok;
2129         if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
2130                 return (FALSE);
2131         if (xdrs->x_op != XDR_ENCODE)
2132                 return (TRUE);
2133         /*
2134          * cookieverf is really an opaque 8 byte
2135          * quantity, but we will treat it as a
2136          * hyper for efficiency, the cost of
2137          * a byteswap here saves bcopys elsewhere
2138          */
2139         if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
2140                 return (FALSE);
2141         return (xdr_putdirlist(xdrs, resokp));
2142 }
2143 
2144 bool_t
2145 xdr_READDIR3vres(XDR *xdrs, READDIR3vres *objp)
2146 {
2147         dirent64_t *dp;
2148         uint_t entries_size;
2149         int outcount = 0;
2150 
2151         /*
2152          * DECODE or FREE only
2153          */
2154         if (xdrs->x_op == XDR_FREE)
2155                 return (TRUE);
2156 
2157         if (xdrs->x_op != XDR_DECODE)
2158                 return (FALSE);
2159 
2160         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2161                 return (FALSE);
2162 
2163         if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
2164                 return (FALSE);
2165 
2166         if (objp->status != NFS3_OK)
2167                 return (TRUE);
2168 
2169         /*
2170          * cookieverf is really an opaque 8 byte
2171          * quantity, but we will treat it as a
2172          * hyper for efficiency, the cost of
2173          * a byteswap here saves bcopys elsewhere
2174          */
2175         if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2176                 return (FALSE);
2177 
2178         entries_size = objp->entries_size;
2179         dp = objp->entries;
2180 
2181         for (;;) {
2182                 uint_t this_reclen;
2183                 bool_t valid;
2184                 uint_t namlen;
2185                 ino64_t fileid;
2186 
2187                 if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
2188                         return (FALSE);
2189                 if (!valid) {
2190                         /*
2191                          * We have run out of entries, decode eof.
2192                          */
2193                         if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
2194                                 return (FALSE);
2195 
2196                         break;
2197                 }
2198 
2199                 /*
2200                  * fileid3 fileid
2201                  */
2202                 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
2203                         return (FALSE);
2204 
2205                 /*
2206                  * filename3 name
2207                  */
2208                 if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
2209                         return (FALSE);
2210                 this_reclen = DIRENT64_RECLEN(namlen);
2211 
2212                 /*
2213                  * If this will overflow buffer, stop decoding
2214                  */
2215                 if ((outcount + this_reclen) > entries_size) {
2216                         objp->eof = FALSE;
2217                         break;
2218                 }
2219                 dp->d_reclen = this_reclen;
2220                 dp->d_ino = fileid;
2221 
2222                 if (!xdr_opaque(xdrs, dp->d_name, namlen))
2223                         return (FALSE);
2224                 bzero(&dp->d_name[namlen],
2225                     DIRENT64_NAMELEN(this_reclen) - namlen);
2226 
2227                 /*
2228                  * cookie3 cookie
2229                  */
2230                 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
2231                         return (FALSE);
2232                 objp->loff = dp->d_off;
2233 
2234                 outcount += this_reclen;
2235                 dp = (dirent64_t *)((intptr_t)dp + this_reclen);
2236         }
2237 
2238         objp->size = outcount;
2239         return (TRUE);
2240 }
2241 
2242 bool_t
2243 xdr_READDIRPLUS3args(XDR *xdrs, READDIRPLUS3args *objp)
2244 {
2245         rdma_chunkinfo_t rci;
2246         struct xdr_ops *xops = xdrrdma_xops();
2247 
2248         if (xdrs->x_op == XDR_FREE)
2249                 return (TRUE);
2250 
2251         switch (xdrs->x_op) {
2252         case XDR_FREE:
2253         case XDR_ENCODE:
2254                 if (!xdr_nfs_fh3(xdrs, &objp->dir))
2255                         return (FALSE);
2256                 break;
2257         case XDR_DECODE:
2258                 if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
2259                         return (FALSE);
2260                 break;
2261         }
2262         if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
2263             xdrs->x_op == XDR_ENCODE) {
2264                 rci.rci_type = RCI_REPLY_CHUNK;
2265                 rci.rci_len = objp->maxcount;
2266                 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
2267         }
2268 
2269         if (!xdr_u_longlong_t(xdrs, &objp->cookie))
2270                 return (FALSE);
2271         /*
2272          * cookieverf is really an opaque 8 byte
2273          * quantity, but we will treat it as a
2274          * hyper for efficiency, the cost of
2275          * a byteswap here saves bcopys elsewhere
2276          */
2277         if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2278                 return (FALSE);
2279         if (!xdr_u_int(xdrs, &objp->dircount))
2280                 return (FALSE);
2281         return (xdr_u_int(xdrs, &objp->maxcount));
2282 }
2283 
2284 /*
2285  * ENCODE ONLY
2286  */
2287 static bool_t
2288 xdr_putdirpluslist(XDR *xdrs, READDIRPLUS3resok *objp)
2289 {
2290         struct dirent64 *dp;
2291         char *name;
2292         int nents;
2293         bool_t true = TRUE;
2294         bool_t false = FALSE;
2295         fileid3 fileid;
2296         cookie3 cookie;
2297         entryplus3_info *infop;
2298 
2299         if (xdrs->x_op != XDR_ENCODE)
2300                 return (FALSE);
2301 
2302         dp = (struct dirent64 *)objp->reply.entries;
2303         nents = objp->size;
2304         infop = objp->infop;
2305 
2306         while (nents > 0) {
2307                 if (dp->d_reclen == 0)
2308                         return (FALSE);
2309                 if (dp->d_ino != 0) {
2310                         name = dp->d_name;
2311                         fileid = (fileid3)(dp->d_ino);
2312                         cookie = (cookie3)(dp->d_off);
2313                         if (!xdr_bool(xdrs, &true) ||
2314                             !xdr_u_longlong_t(xdrs, &fileid) ||
2315                             !xdr_bytes(xdrs, &name, &infop->namelen, ~0) ||
2316                             !xdr_u_longlong_t(xdrs, &cookie) ||
2317                             !xdr_post_op_attr(xdrs, &infop->attr) ||
2318                             !xdr_post_op_fh3(xdrs, &infop->fh)) {
2319                                 return (FALSE);
2320                         }
2321                 }
2322                 dp = nextdp(dp);
2323                 infop++;
2324                 nents--;
2325         }
2326 
2327         if (!xdr_bool(xdrs, &false))
2328                 return (FALSE);
2329         if (!xdr_bool(xdrs, &objp->reply.eof))
2330                 return (FALSE);
2331         return (TRUE);
2332 }
2333 
2334 bool_t
2335 xdr_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
2336 {
2337         READDIRPLUS3resok *resokp;
2338 
2339         /*
2340          * ENCODE or FREE only
2341          */
2342         if (xdrs->x_op == XDR_DECODE)
2343                 return (FALSE);
2344 
2345         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2346                 return (FALSE);
2347         switch (objp->status) {
2348         case NFS3_OK:
2349                 /* xdr_READDIRPLUS3resok */
2350                 resokp = &objp->resok;
2351                 if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
2352                         return (FALSE);
2353                 /*
2354                  * cookieverf is really an opaque 8 byte
2355                  * quantity, but we will treat it as a
2356                  * hyper for efficiency, the cost of
2357                  * a byteswap here saves bcopys elsewhere
2358                  */
2359                 if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
2360                         return (FALSE);
2361                 if (xdrs->x_op == XDR_ENCODE) {
2362                         if (!xdr_putdirpluslist(xdrs, resokp))
2363                                 return (FALSE);
2364                 }
2365                 break;
2366         default:
2367                 return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
2368         }
2369         return (TRUE);
2370 }
2371 
2372 /*
2373  * Decode readdirplus directly into a dirent64_t and do the DNLC caching.
2374  */
2375 bool_t
2376 xdr_READDIRPLUS3vres(XDR *xdrs, READDIRPLUS3vres *objp)
2377 {
2378         dirent64_t *dp;
2379         vnode_t *dvp;
2380         uint_t entries_size;
2381         int outcount = 0;
2382         vnode_t *nvp;
2383         rnode_t *rp;
2384         post_op_vattr pov;
2385         vattr_t va;
2386 
2387         /*
2388          * DECODE or FREE only
2389          */
2390         if (xdrs->x_op == XDR_FREE)
2391                 return (TRUE);
2392 
2393         if (xdrs->x_op != XDR_DECODE)
2394                 return (FALSE);
2395 
2396         if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
2397                 return (FALSE);
2398 
2399         if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
2400                 return (FALSE);
2401 
2402         if (objp->status != NFS3_OK)
2403                 return (TRUE);
2404 
2405         /*
2406          * cookieverf is really an opaque 8 byte
2407          * quantity, but we will treat it as a
2408          * hyper for efficiency, the cost of
2409          * a byteswap here saves bcopys elsewhere
2410          */
2411         if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2412                 return (FALSE);
2413 
2414         dvp = objp->dir_attributes.fres.vp;
2415         rp = VTOR(dvp);
2416 
2417         pov.fres.vap = &va;
2418         pov.fres.vp = dvp;
2419 
2420         entries_size = objp->entries_size;
2421         dp = objp->entries;
2422 
2423         for (;;) {
2424                 uint_t this_reclen;
2425                 bool_t valid;
2426                 uint_t namlen;
2427                 nfs_fh3 fh;
2428                 int va_valid;
2429                 int fh_valid;
2430                 ino64_t fileid;
2431 
2432                 if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
2433                         return (FALSE);
2434                 if (!valid) {
2435                         /*
2436                          * We have run out of entries, decode eof.
2437                          */
2438                         if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
2439                                 return (FALSE);
2440 
2441                         break;
2442                 }
2443 
2444                 /*
2445                  * fileid3 fileid
2446                  */
2447                 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
2448                         return (FALSE);
2449 
2450                 /*
2451                  * filename3 name
2452                  */
2453                 if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
2454                         return (FALSE);
2455                 this_reclen = DIRENT64_RECLEN(namlen);
2456 
2457                 /*
2458                  * If this will overflow buffer, stop decoding
2459                  */
2460                 if ((outcount + this_reclen) > entries_size) {
2461                         objp->eof = FALSE;
2462                         break;
2463                 }
2464                 dp->d_reclen = this_reclen;
2465                 dp->d_ino = fileid;
2466 
2467                 if (!xdr_opaque(xdrs, dp->d_name, namlen))
2468                         return (FALSE);
2469                 bzero(&dp->d_name[namlen],
2470                     DIRENT64_NAMELEN(this_reclen) - namlen);
2471 
2472                 /*
2473                  * cookie3 cookie
2474                  */
2475                 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
2476                         return (FALSE);
2477                 objp->loff = dp->d_off;
2478 
2479                 /*
2480                  * post_op_attr name_attributes
2481                  */
2482                 if (!xdr_post_op_vattr(xdrs, &pov))
2483                         return (FALSE);
2484 
2485                 if (pov.attributes == TRUE &&
2486                     pov.fres.status == NFS3_OK)
2487                         va_valid = TRUE;
2488                 else
2489                         va_valid = FALSE;
2490 
2491                 /*
2492                  * post_op_fh3 name_handle
2493                  */
2494                 if (!XDR_GETINT32(xdrs, (int32_t *)&fh_valid))
2495                         return (FALSE);
2496 
2497                 /*
2498                  * By definition of the standard fh_valid can be 0 (FALSE) or
2499                  * 1 (TRUE), but we have to account for it being anything else
2500                  * in case some other system didn't follow the standard.  Note
2501                  * that this is why the else checks if the fh_valid variable
2502                  * is != FALSE.
2503                  */
2504                 if (fh_valid == TRUE) {
2505                         if (!xdr_nfs_fh3(xdrs, &fh))
2506                                 return (FALSE);
2507                 } else {
2508                         if (fh_valid != FALSE)
2509                                 return (FALSE);
2510                 }
2511 
2512                 /*
2513                  * If the name is "." or there are no attributes,
2514                  * don't polute the DNLC with "." entries or files
2515                  * we cannot determine the type for.
2516                  */
2517                 if (!(namlen == 1 && dp->d_name[0] == '.') &&
2518                     va_valid && fh_valid) {
2519 
2520                         /*
2521                          * Do the DNLC caching
2522                          */
2523                         nvp = makenfs3node_va(&fh, &va, dvp->v_vfsp,
2524                             objp->time, objp->credentials,
2525                             rp->r_path, dp->d_name);
2526                         dnlc_update(dvp, dp->d_name, nvp);
2527                         VN_RELE(nvp);
2528                 }
2529 
2530                 outcount += this_reclen;
2531                 dp = (dirent64_t *)((intptr_t)dp + this_reclen);
2532         }
2533 
2534         objp->size = outcount;
2535         return (TRUE);
2536 }
2537 
2538 bool_t
2539 xdr_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp)
2540 {
2541         FSSTAT3resok *resokp;
2542 
2543         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2544                 return (FALSE);
2545         if (objp->status != NFS3_OK)
2546                 return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
2547 
2548         /* xdr_FSSTAT3resok */
2549         resokp = &objp->resok;
2550         if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
2551                 return (FALSE);
2552         if (!xdr_u_longlong_t(xdrs, &resokp->tbytes))
2553                 return (FALSE);
2554         if (!xdr_u_longlong_t(xdrs, &resokp->fbytes))
2555                 return (FALSE);
2556         if (!xdr_u_longlong_t(xdrs, &resokp->abytes))
2557                 return (FALSE);
2558         if (!xdr_u_longlong_t(xdrs, &resokp->tfiles))
2559                 return (FALSE);
2560         if (!xdr_u_longlong_t(xdrs, &resokp->ffiles))
2561                 return (FALSE);
2562         if (!xdr_u_longlong_t(xdrs, &resokp->afiles))
2563                 return (FALSE);
2564         return (xdr_u_int(xdrs, &resokp->invarsec));
2565 }
2566 
2567 bool_t
2568 xdr_FSINFO3res(XDR *xdrs, FSINFO3res *objp)
2569 {
2570         FSINFO3resok *resokp;
2571 
2572         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2573                 return (FALSE);
2574         if (objp->status != NFS3_OK) /* xdr_FSSTAT3resfail */
2575                 return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
2576 
2577         /* xdr_FSINFO3resok */
2578         resokp = &objp->resok;
2579         if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
2580                 return (FALSE);
2581         if (!xdr_u_int(xdrs, &resokp->rtmax))
2582                 return (FALSE);
2583         if (!xdr_u_int(xdrs, &resokp->rtpref))
2584                 return (FALSE);
2585         if (!xdr_u_int(xdrs, &resokp->rtmult))
2586                 return (FALSE);
2587         if (!xdr_u_int(xdrs, &resokp->wtmax))
2588                 return (FALSE);
2589         if (!xdr_u_int(xdrs, &resokp->wtpref))
2590                 return (FALSE);
2591         if (!xdr_u_int(xdrs, &resokp->wtmult))
2592                 return (FALSE);
2593         if (!xdr_u_int(xdrs, &resokp->dtpref))
2594                 return (FALSE);
2595         if (!xdr_u_longlong_t(xdrs, &resokp->maxfilesize))
2596                 return (FALSE);
2597         if (!xdr_u_int(xdrs, &resokp->time_delta.seconds))
2598                 return (FALSE);
2599         if (!xdr_u_int(xdrs, &resokp->time_delta.nseconds))
2600                 return (FALSE);
2601         return (xdr_u_int(xdrs, &resokp->properties));
2602 }
2603 
2604 bool_t
2605 xdr_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp)
2606 {
2607         PATHCONF3resok *resokp;
2608 
2609         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2610                 return (FALSE);
2611         if (objp->status != NFS3_OK)
2612                 return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
2613 
2614         /* xdr_PATHCONF3resok */
2615         resokp = &objp->resok;
2616         if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
2617                 return (FALSE);
2618         if (!xdr_u_int(xdrs, &resokp->info.link_max))
2619                 return (FALSE);
2620         if (!xdr_u_int(xdrs, &resokp->info.name_max))
2621                 return (FALSE);
2622         if (!xdr_bool(xdrs, &resokp->info.no_trunc))
2623                 return (FALSE);
2624         if (!xdr_bool(xdrs, &resokp->info.chown_restricted))
2625                 return (FALSE);
2626         if (!xdr_bool(xdrs, &resokp->info.case_insensitive))
2627                 return (FALSE);
2628         return (xdr_bool(xdrs, &resokp->info.case_preserving));
2629 }
2630 
2631 bool_t
2632 xdr_COMMIT3args(XDR *xdrs, COMMIT3args *objp)
2633 {
2634         if (xdrs->x_op == XDR_FREE)
2635                 return (TRUE);
2636 
2637         switch (xdrs->x_op) {
2638         case XDR_FREE:
2639         case XDR_ENCODE:
2640                 if (!xdr_nfs_fh3(xdrs, &objp->file))
2641                         return (FALSE);
2642                 break;
2643         case XDR_DECODE:
2644                 if (!xdr_nfs_fh3_server(xdrs, &objp->file))
2645                         return (FALSE);
2646                 break;
2647         }
2648         if (!xdr_u_longlong_t(xdrs, &objp->offset))
2649                 return (FALSE);
2650         return (xdr_u_int(xdrs, &objp->count));
2651 }
2652 
2653 bool_t
2654 xdr_COMMIT3res(XDR *xdrs, COMMIT3res *objp)
2655 {
2656         COMMIT3resok *resokp;
2657 
2658         if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2659                 return (FALSE);
2660         if (objp->status != NFS3_OK)
2661                 return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
2662 
2663         /* xdr_COMMIT3resok */
2664         resokp = &objp->resok;
2665         if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
2666                 return (FALSE);
2667         /*
2668          * writeverf3 is really an opaque 8 byte
2669          * quantity, but we will treat it as a
2670          * hyper for efficiency, the cost of
2671          * a byteswap here saves bcopys elsewhere
2672          */
2673         return (xdr_u_longlong_t(xdrs, &resokp->verf));
2674 }