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