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