Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / kernel / fs / nfs / nfs3_xdr.c
blobee25c111a297222ef17948a1539b17c51f0249ed
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 * Copyright (c) 2013 by Delphix. All rights reserved.
33 #include <sys/param.h>
34 #include <sys/types.h>
35 #include <sys/systm.h>
36 #include <sys/user.h>
37 #include <sys/vnode.h>
38 #include <sys/file.h>
39 #include <sys/dirent.h>
40 #include <sys/vfs.h>
41 #include <sys/stream.h>
42 #include <sys/strsubr.h>
43 #include <sys/debug.h>
44 #include <sys/t_lock.h>
45 #include <sys/cmn_err.h>
46 #include <sys/dnlc.h>
47 #include <sys/cred.h>
48 #include <sys/time.h>
49 #include <sys/sdt.h>
51 #include <rpc/types.h>
52 #include <rpc/xdr.h>
54 #include <nfs/nfs.h>
55 #include <nfs/rnode.h>
56 #include <rpc/rpc_rdma.h>
59 * These are the XDR routines used to serialize and deserialize
60 * the various structures passed as parameters across the network
61 * between NFS clients and servers.
65 * XDR null terminated ASCII strings
66 * xdr_string3 deals with "C strings" - arrays of bytes that are
67 * terminated by a NULL character. The parameter cpp references a
68 * pointer to storage; If the pointer is null, then the necessary
69 * storage is allocated. The last parameter is the max allowed length
70 * of the string as allowed by the system. The NFS Version 3 protocol
71 * does not place limits on strings, but the implementation needs to
72 * place a reasonable limit to avoid problems.
74 bool_t
75 xdr_string3(XDR *xdrs, char **cpp, uint_t maxsize)
77 char *sp;
78 uint_t size;
79 uint_t nodesize;
80 bool_t mem_alloced = FALSE;
83 * first deal with the length since xdr strings are counted-strings
85 sp = *cpp;
86 switch (xdrs->x_op) {
87 case XDR_FREE:
88 if (sp == NULL || sp == nfs3nametoolong)
89 return (TRUE); /* already free */
90 /* FALLTHROUGH */
92 case XDR_ENCODE:
93 size = (uint_t)strlen(sp);
94 break;
96 case XDR_DECODE:
97 break;
100 if (!xdr_u_int(xdrs, &size))
101 return (FALSE);
104 * now deal with the actual bytes
106 switch (xdrs->x_op) {
107 case XDR_DECODE:
108 if (size >= maxsize) {
109 *cpp = nfs3nametoolong;
110 if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &size))
111 return (FALSE);
112 return (TRUE);
114 nodesize = size + 1;
115 if (nodesize == 0)
116 return (TRUE);
117 if (sp == NULL) {
118 sp = kmem_alloc(nodesize, KM_NOSLEEP);
119 *cpp = sp;
120 if (sp == NULL)
121 return (FALSE);
122 mem_alloced = TRUE;
124 sp[size] = 0;
126 if (xdr_opaque(xdrs, sp, size)) {
127 if (strlen(sp) != size) {
128 if (mem_alloced)
129 kmem_free(sp, nodesize);
130 *cpp = NULL;
131 return (FALSE);
133 } else {
134 if (mem_alloced)
135 kmem_free(sp, nodesize);
136 *cpp = NULL;
137 return (FALSE);
139 return (TRUE);
141 case XDR_ENCODE:
142 return (xdr_opaque(xdrs, sp, size));
144 case XDR_FREE:
145 nodesize = size + 1;
146 kmem_free(sp, nodesize);
147 *cpp = NULL;
148 return (TRUE);
151 return (FALSE);
155 * XDR_INLINE decode a filehandle.
157 bool_t
158 xdr_inline_decode_nfs_fh3(uint32_t *ptr, nfs_fh3 *fhp, uint32_t fhsize)
160 uchar_t *bp = (uchar_t *)ptr;
161 uchar_t *cp;
162 uint32_t dsize;
163 uintptr_t resid;
166 * Check to see if what the client sent us is bigger or smaller
167 * than what we can ever possibly send out. NFS_FHMAXDATA is
168 * unfortunately badly named as it is no longer the max and is
169 * really the min of what is sent over the wire.
171 if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) +
172 sizeof (ushort_t) + NFS_FHMAXDATA +
173 sizeof (ushort_t) + NFS_FHMAXDATA)) {
174 return (FALSE);
178 * All internal parts of a filehandle are in native byte order.
180 * Decode what should be fh3_fsid, it is aligned.
182 fhp->fh3_fsid.val[0] = *(uint32_t *)bp;
183 bp += BYTES_PER_XDR_UNIT;
184 fhp->fh3_fsid.val[1] = *(uint32_t *)bp;
185 bp += BYTES_PER_XDR_UNIT;
188 * Decode what should be fh3_len. fh3_len is two bytes, so we're
189 * unaligned now.
191 cp = (uchar_t *)&fhp->fh3_len;
192 *cp++ = *bp++;
193 *cp++ = *bp++;
194 fhsize -= 2 * BYTES_PER_XDR_UNIT + sizeof (ushort_t);
197 * For backwards compatability, the fid length may be less than
198 * NFS_FHMAXDATA, but it was always encoded as NFS_FHMAXDATA bytes.
200 dsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len;
203 * Make sure the client isn't sending us a bogus length for fh3x_data.
205 if (fhsize < dsize)
206 return (FALSE);
207 bcopy(bp, fhp->fh3_data, dsize);
208 bp += dsize;
209 fhsize -= dsize;
211 if (fhsize < sizeof (ushort_t))
212 return (FALSE);
213 cp = (uchar_t *)&fhp->fh3_xlen;
214 *cp++ = *bp++;
215 *cp++ = *bp++;
216 fhsize -= sizeof (ushort_t);
218 dsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen;
221 * Make sure the client isn't sending us a bogus length for fh3x_xdata.
223 if (fhsize < dsize)
224 return (FALSE);
225 bcopy(bp, fhp->fh3_xdata, dsize);
226 fhsize -= dsize;
227 bp += dsize;
230 * We realign things on purpose, so skip any padding
232 resid = (uintptr_t)bp % BYTES_PER_XDR_UNIT;
233 if (resid != 0) {
234 if (fhsize < (BYTES_PER_XDR_UNIT - resid))
235 return (FALSE);
236 bp += BYTES_PER_XDR_UNIT - resid;
237 fhsize -= BYTES_PER_XDR_UNIT - resid;
241 * Make sure client didn't send extra bytes
243 if (fhsize != 0)
244 return (FALSE);
245 return (TRUE);
248 static bool_t
249 xdr_decode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
251 uint32_t fhsize; /* filehandle size */
252 uint32_t bufsize;
253 rpc_inline_t *ptr;
254 uchar_t *bp;
256 ASSERT(xdrs->x_op == XDR_DECODE);
259 * Retrieve the filehandle length.
261 if (!XDR_GETINT32(xdrs, (int32_t *)&fhsize))
262 return (FALSE);
264 bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
265 objp->fh3_length = 0;
268 * Check to see if what the client sent us is bigger or smaller
269 * than what we can ever possibly send out. NFS_FHMAXDATA is
270 * unfortunately badly named as it is no longer the max and is
271 * really the min of what is sent over the wire.
273 if (fhsize > sizeof (fhandle3_t) || fhsize < (sizeof (fsid_t) +
274 sizeof (ushort_t) + NFS_FHMAXDATA +
275 sizeof (ushort_t) + NFS_FHMAXDATA)) {
276 if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fhsize))
277 return (FALSE);
278 return (TRUE);
282 * bring in fhsize plus any padding
284 bufsize = RNDUP(fhsize);
285 ptr = XDR_INLINE(xdrs, bufsize);
286 bp = (uchar_t *)ptr;
287 if (ptr == NULL) {
288 bp = kmem_alloc(bufsize, KM_SLEEP);
289 if (!xdr_opaque(xdrs, (char *)bp, bufsize)) {
290 kmem_free(bp, bufsize);
291 return (FALSE);
295 objp->fh3_length = sizeof (fhandle3_t);
297 if (xdr_inline_decode_nfs_fh3((uint32_t *)bp, objp, fhsize) == FALSE) {
299 * If in the process of decoding we find the file handle
300 * is not correctly formed, we need to continue decoding
301 * and trigger an NFS layer error. Set the nfs_fh3_len to
302 * zero so it gets caught as a bad length.
304 bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
305 objp->fh3_length = 0;
308 if (ptr == NULL)
309 kmem_free(bp, bufsize);
310 return (TRUE);
314 * XDR_INLINE encode a filehandle.
316 bool_t
317 xdr_inline_encode_nfs_fh3(uint32_t **ptrp, uint32_t *ptr_redzone,
318 nfs_fh3 *fhp)
320 uint32_t *ptr = *ptrp;
321 uchar_t *cp;
322 uint_t otw_len, fsize, xsize; /* otw, file, and export sizes */
323 uint32_t padword;
325 fsize = fhp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_len;
326 xsize = fhp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : fhp->fh3_xlen;
329 * First get the initial and variable sized part of the filehandle.
331 otw_len = sizeof (fhp->fh3_fsid) +
332 sizeof (fhp->fh3_len) + fsize +
333 sizeof (fhp->fh3_xlen) + xsize;
336 * Round out to a full word.
338 otw_len = RNDUP(otw_len);
339 padword = (otw_len / BYTES_PER_XDR_UNIT); /* includes fhlen */
342 * Make sure we don't exceed our buffer.
344 if ((ptr + (otw_len / BYTES_PER_XDR_UNIT) + 1) > ptr_redzone)
345 return (FALSE);
348 * Zero out the pading.
350 ptr[padword] = 0;
352 IXDR_PUT_U_INT32(ptr, otw_len);
355 * The rest of the filehandle is in native byteorder
357 /* fh3_fsid */
358 *ptr++ = (uint32_t)fhp->fh3_fsid.val[0];
359 *ptr++ = (uint32_t)fhp->fh3_fsid.val[1];
362 * Since the next pieces are unaligned, we need to
363 * do bytewise copies.
365 cp = (uchar_t *)ptr;
367 /* fh3_len + fh3_data */
368 bcopy(&fhp->fh3_len, cp, sizeof (fhp->fh3_len) + fsize);
369 cp += sizeof (fhp->fh3_len) + fsize;
371 /* fh3_xlen + fh3_xdata */
372 bcopy(&fhp->fh3_xlen, cp, sizeof (fhp->fh3_xlen) + xsize);
373 cp += sizeof (fhp->fh3_xlen) + xsize;
375 /* do necessary rounding/padding */
376 cp = (uchar_t *)RNDUP((uintptr_t)cp);
377 ptr = (uint32_t *)cp;
380 * With the above padding, we're word aligned again.
382 ASSERT(((uintptr_t)ptr % BYTES_PER_XDR_UNIT) == 0);
384 *ptrp = ptr;
386 return (TRUE);
389 static bool_t
390 xdr_encode_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
392 uint_t otw_len, fsize, xsize; /* otw, file, and export sizes */
393 bool_t ret;
394 rpc_inline_t *ptr;
395 rpc_inline_t *buf = NULL;
396 uint32_t *ptr_redzone;
398 ASSERT(xdrs->x_op == XDR_ENCODE);
400 fsize = objp->fh3_len < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_len;
401 xsize = objp->fh3_xlen < NFS_FHMAXDATA ? NFS_FHMAXDATA : objp->fh3_xlen;
404 * First get the over the wire size, it is the 4 bytes
405 * for the length, plus the combined size of the
406 * file handle components.
408 otw_len = BYTES_PER_XDR_UNIT + sizeof (objp->fh3_fsid) +
409 sizeof (objp->fh3_len) + fsize +
410 sizeof (objp->fh3_xlen) + xsize;
412 * Round out to a full word.
414 otw_len = RNDUP(otw_len);
417 * Next try to inline the XDR stream, if that fails (rare)
418 * allocate a buffer to encode the file handle and then
419 * copy it using xdr_opaque and free the buffer.
421 ptr = XDR_INLINE(xdrs, otw_len);
422 if (ptr == NULL)
423 ptr = buf = kmem_alloc(otw_len, KM_SLEEP);
425 ptr_redzone = (uint32_t *)(ptr + (otw_len / BYTES_PER_XDR_UNIT));
426 ret = xdr_inline_encode_nfs_fh3((uint32_t **)&ptr, ptr_redzone, objp);
428 if (buf != NULL) {
429 if (ret == TRUE)
430 ret = xdr_opaque(xdrs, (char *)buf, otw_len);
431 kmem_free(buf, otw_len);
433 return (ret);
437 * XDR a NFSv3 filehandle the naive way.
439 bool_t
440 xdr_nfs_fh3(XDR *xdrs, nfs_fh3 *objp)
442 if (xdrs->x_op == XDR_FREE)
443 return (TRUE);
445 if (!xdr_u_int(xdrs, &objp->fh3_length))
446 return (FALSE);
448 if (objp->fh3_length > NFS3_FHSIZE)
449 return (FALSE);
451 return (xdr_opaque(xdrs, objp->fh3_u.data, objp->fh3_length));
455 * XDR a NFSv3 filehandle with intelligence on the server.
456 * Encoding goes from our in-memory structure to wire format.
457 * Decoding goes from wire format to our in-memory structure.
459 bool_t
460 xdr_nfs_fh3_server(XDR *xdrs, nfs_fh3 *objp)
462 switch (xdrs->x_op) {
463 case XDR_ENCODE:
464 if (objp->fh3_flags & FH_WEBNFS)
465 return (xdr_nfs_fh3(xdrs, objp));
466 else
467 return (xdr_encode_nfs_fh3(xdrs, objp));
468 case XDR_DECODE:
469 return (xdr_decode_nfs_fh3(xdrs, objp));
470 case XDR_FREE:
471 if (objp->fh3_u.data != NULL)
472 bzero(objp->fh3_u.data, sizeof (objp->fh3_u.data));
473 return (TRUE);
475 return (FALSE);
478 bool_t
479 xdr_diropargs3(XDR *xdrs, diropargs3 *objp)
481 switch (xdrs->x_op) {
482 case XDR_FREE:
483 case XDR_ENCODE:
484 if (!xdr_nfs_fh3(xdrs, objp->dirp))
485 return (FALSE);
486 break;
487 case XDR_DECODE:
488 if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
489 return (FALSE);
490 break;
492 return (xdr_string3(xdrs, &objp->name, MAXNAMELEN));
495 static bool_t
496 xdr_fattr3(XDR *xdrs, fattr3 *na)
498 int32_t *ptr;
500 if (xdrs->x_op == XDR_FREE)
501 return (TRUE);
503 ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
504 if (ptr != NULL) {
505 if (xdrs->x_op == XDR_DECODE) {
506 na->type = IXDR_GET_ENUM(ptr, enum ftype3);
507 na->mode = IXDR_GET_U_INT32(ptr);
508 na->nlink = IXDR_GET_U_INT32(ptr);
509 na->uid = IXDR_GET_U_INT32(ptr);
510 na->gid = IXDR_GET_U_INT32(ptr);
511 IXDR_GET_U_HYPER(ptr, na->size);
512 IXDR_GET_U_HYPER(ptr, na->used);
513 na->rdev.specdata1 = IXDR_GET_U_INT32(ptr);
514 na->rdev.specdata2 = IXDR_GET_U_INT32(ptr);
515 IXDR_GET_U_HYPER(ptr, na->fsid);
516 IXDR_GET_U_HYPER(ptr, na->fileid);
517 na->atime.seconds = IXDR_GET_U_INT32(ptr);
518 na->atime.nseconds = IXDR_GET_U_INT32(ptr);
519 na->mtime.seconds = IXDR_GET_U_INT32(ptr);
520 na->mtime.nseconds = IXDR_GET_U_INT32(ptr);
521 na->ctime.seconds = IXDR_GET_U_INT32(ptr);
522 na->ctime.nseconds = IXDR_GET_U_INT32(ptr);
523 } else {
524 IXDR_PUT_ENUM(ptr, na->type);
525 IXDR_PUT_U_INT32(ptr, na->mode);
526 IXDR_PUT_U_INT32(ptr, na->nlink);
527 IXDR_PUT_U_INT32(ptr, na->uid);
528 IXDR_PUT_U_INT32(ptr, na->gid);
529 IXDR_PUT_U_HYPER(ptr, na->size);
530 IXDR_PUT_U_HYPER(ptr, na->used);
531 IXDR_PUT_U_INT32(ptr, na->rdev.specdata1);
532 IXDR_PUT_U_INT32(ptr, na->rdev.specdata2);
533 IXDR_PUT_U_HYPER(ptr, na->fsid);
534 IXDR_PUT_U_HYPER(ptr, na->fileid);
535 IXDR_PUT_U_INT32(ptr, na->atime.seconds);
536 IXDR_PUT_U_INT32(ptr, na->atime.nseconds);
537 IXDR_PUT_U_INT32(ptr, na->mtime.seconds);
538 IXDR_PUT_U_INT32(ptr, na->mtime.nseconds);
539 IXDR_PUT_U_INT32(ptr, na->ctime.seconds);
540 IXDR_PUT_U_INT32(ptr, na->ctime.nseconds);
542 return (TRUE);
544 if (!(xdr_enum(xdrs, (enum_t *)&na->type) &&
545 xdr_u_int(xdrs, &na->mode) &&
546 xdr_u_int(xdrs, &na->nlink) &&
547 xdr_u_int(xdrs, &na->uid) &&
548 xdr_u_int(xdrs, &na->gid) &&
549 xdr_u_longlong_t(xdrs, &na->size) &&
550 xdr_u_longlong_t(xdrs, &na->used) &&
551 xdr_u_int(xdrs, &na->rdev.specdata1) &&
552 xdr_u_int(xdrs, &na->rdev.specdata2) &&
553 xdr_u_longlong_t(xdrs, &na->fsid) &&
554 xdr_u_longlong_t(xdrs, &na->fileid) &&
555 xdr_u_int(xdrs, &na->atime.seconds) &&
556 xdr_u_int(xdrs, &na->atime.nseconds) &&
557 xdr_u_int(xdrs, &na->mtime.seconds) &&
558 xdr_u_int(xdrs, &na->mtime.nseconds) &&
559 xdr_u_int(xdrs, &na->ctime.seconds) &&
560 xdr_u_int(xdrs, &na->ctime.nseconds)))
561 return (FALSE);
562 return (TRUE);
566 * Fast decode of an fattr3 to a vattr
567 * Only return FALSE on decode error, all other fattr to vattr translation
568 * failures set status.
570 * Callers must catch the following errors:
571 * EFBIG - file size will not fit in va_size
572 * EOVERFLOW - time will not fit in va_*time
574 static bool_t
575 xdr_fattr3_to_vattr(XDR *xdrs, fattr3_res *objp)
577 int32_t *ptr;
578 size3 used;
579 specdata3 rdev;
580 uint32_t ntime;
581 vattr_t *vap = objp->vap;
584 * DECODE only
586 ASSERT(xdrs->x_op == XDR_DECODE);
588 /* On success, all attributes will be decoded */
589 vap->va_mask = VATTR_ALL;
591 objp->status = 0;
592 ptr = XDR_INLINE(xdrs, NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT);
593 if (ptr != NULL) {
595 * Common case
597 vap->va_type = IXDR_GET_ENUM(ptr, enum vtype);
598 if ((ftype3)vap->va_type < NF3REG ||
599 (ftype3)vap->va_type > NF3FIFO)
600 vap->va_type = VBAD;
601 else
602 vap->va_type = nf3_to_vt[vap->va_type];
603 vap->va_mode = IXDR_GET_U_INT32(ptr);
604 vap->va_nlink = IXDR_GET_U_INT32(ptr);
605 vap->va_uid = (uid_t)IXDR_GET_U_INT32(ptr);
606 if (vap->va_uid == NFS_UID_NOBODY)
607 vap->va_uid = UID_NOBODY;
608 vap->va_gid = (gid_t)IXDR_GET_U_INT32(ptr);
609 if (vap->va_gid == NFS_GID_NOBODY)
610 vap->va_gid = GID_NOBODY;
611 IXDR_GET_U_HYPER(ptr, vap->va_size);
613 * If invalid size, stop decode, set status, and
614 * return TRUE, x_handy will be correct, caller must ignore vap.
616 if (!NFS3_SIZE_OK(vap->va_size)) {
617 objp->status = EFBIG;
618 return (TRUE);
620 IXDR_GET_U_HYPER(ptr, used);
621 rdev.specdata1 = IXDR_GET_U_INT32(ptr);
622 rdev.specdata2 = IXDR_GET_U_INT32(ptr);
623 /* fsid is ignored */
624 ptr += 2;
625 IXDR_GET_U_HYPER(ptr, vap->va_nodeid);
628 * nfs protocol defines times as unsigned so don't
629 * extend sign, unless sysadmin set nfs_allow_preepoch_time.
630 * The inline macros do the equivilant of NFS_TIME_T_CONVERT
632 if (nfs_allow_preepoch_time) {
633 vap->va_atime.tv_sec = IXDR_GET_INT32(ptr);
634 vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
635 vap->va_mtime.tv_sec = IXDR_GET_INT32(ptr);
636 vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
637 vap->va_ctime.tv_sec = IXDR_GET_INT32(ptr);
638 vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
639 } else {
641 * Check if the time would overflow on 32-bit
643 ntime = IXDR_GET_U_INT32(ptr);
644 /*CONSTCOND*/
645 if (NFS3_TIME_OVERFLOW(ntime)) {
646 objp->status = EOVERFLOW;
647 return (TRUE);
649 vap->va_atime.tv_sec = ntime;
650 vap->va_atime.tv_nsec = IXDR_GET_U_INT32(ptr);
652 ntime = IXDR_GET_U_INT32(ptr);
653 /*CONSTCOND*/
654 if (NFS3_TIME_OVERFLOW(ntime)) {
655 objp->status = EOVERFLOW;
656 return (TRUE);
658 vap->va_mtime.tv_sec = ntime;
659 vap->va_mtime.tv_nsec = IXDR_GET_U_INT32(ptr);
661 ntime = IXDR_GET_U_INT32(ptr);
662 /*CONSTCOND*/
663 if (NFS3_TIME_OVERFLOW(ntime)) {
664 objp->status = EOVERFLOW;
665 return (TRUE);
667 vap->va_ctime.tv_sec = ntime;
668 vap->va_ctime.tv_nsec = IXDR_GET_U_INT32(ptr);
671 } else {
672 uint64 fsid;
675 * Slow path
677 if (!(xdr_enum(xdrs, (enum_t *)&vap->va_type) &&
678 xdr_u_int(xdrs, &vap->va_mode) &&
679 xdr_u_int(xdrs, &vap->va_nlink) &&
680 xdr_u_int(xdrs, (uint_t *)&vap->va_uid) &&
681 xdr_u_int(xdrs, (uint_t *)&vap->va_gid) &&
682 xdr_u_longlong_t(xdrs, &vap->va_size) &&
683 xdr_u_longlong_t(xdrs, &used) &&
684 xdr_u_int(xdrs, &rdev.specdata1) &&
685 xdr_u_int(xdrs, &rdev.specdata2) &&
686 xdr_u_longlong_t(xdrs, &fsid) && /* ignored */
687 xdr_u_longlong_t(xdrs, &vap->va_nodeid)))
688 return (FALSE);
690 if (nfs_allow_preepoch_time) {
691 if (!xdr_u_int(xdrs, &ntime))
692 return (FALSE);
693 vap->va_atime.tv_sec = (int32_t)ntime;
694 if (!xdr_u_int(xdrs, &ntime))
695 return (FALSE);
696 vap->va_atime.tv_nsec = ntime;
698 if (!xdr_u_int(xdrs, &ntime))
699 return (FALSE);
700 vap->va_mtime.tv_sec = (int32_t)ntime;
701 if (!xdr_u_int(xdrs, &ntime))
702 return (FALSE);
703 vap->va_mtime.tv_nsec = ntime;
705 if (!xdr_u_int(xdrs, &ntime))
706 return (FALSE);
707 vap->va_ctime.tv_sec = (int32_t)ntime;
708 if (!xdr_u_int(xdrs, &ntime))
709 return (FALSE);
710 vap->va_ctime.tv_nsec = ntime;
711 } else {
713 * Check if the time would overflow on 32-bit
714 * Set status and keep decoding stream.
716 if (!xdr_u_int(xdrs, &ntime))
717 return (FALSE);
718 /*CONSTCOND*/
719 if (NFS3_TIME_OVERFLOW(ntime)) {
720 objp->status = EOVERFLOW;
722 vap->va_atime.tv_sec = ntime;
723 if (!xdr_u_int(xdrs, &ntime))
724 return (FALSE);
725 vap->va_atime.tv_nsec = ntime;
727 if (!xdr_u_int(xdrs, &ntime))
728 return (FALSE);
729 /*CONSTCOND*/
730 if (NFS3_TIME_OVERFLOW(ntime)) {
731 objp->status = EOVERFLOW;
733 vap->va_mtime.tv_sec = ntime;
734 if (!xdr_u_int(xdrs, &ntime))
735 return (FALSE);
736 vap->va_mtime.tv_nsec = ntime;
738 if (!xdr_u_int(xdrs, &ntime))
739 return (FALSE);
740 /*CONSTCOND*/
741 if (NFS3_TIME_OVERFLOW(ntime)) {
742 objp->status = EOVERFLOW;
744 vap->va_ctime.tv_sec = ntime;
745 if (!xdr_u_int(xdrs, &ntime))
746 return (FALSE);
747 vap->va_ctime.tv_nsec = ntime;
751 * Fixup as needed
753 if ((ftype3)vap->va_type < NF3REG ||
754 (ftype3)vap->va_type > NF3FIFO)
755 vap->va_type = VBAD;
756 else
757 vap->va_type = nf3_to_vt[vap->va_type];
758 if (vap->va_uid == NFS_UID_NOBODY)
759 vap->va_uid = UID_NOBODY;
760 if (vap->va_gid == NFS_GID_NOBODY)
761 vap->va_gid = GID_NOBODY;
763 * If invalid size, set status, and
764 * return TRUE, caller must ignore vap.
766 if (!NFS3_SIZE_OK(vap->va_size)) {
767 objp->status = EFBIG;
768 return (TRUE);
773 * Fill in derived fields
775 vap->va_fsid = objp->vp->v_vfsp->vfs_dev;
776 vap->va_seq = 0;
779 * Common case values
781 vap->va_rdev = 0;
782 vap->va_blksize = MAXBSIZE;
783 vap->va_nblocks = 0;
785 switch (vap->va_type) {
786 case VREG:
787 case VDIR:
788 case VLNK:
789 vap->va_nblocks = (u_longlong_t)
790 ((used + (size3)DEV_BSIZE - (size3)1) /
791 (size3)DEV_BSIZE);
792 break;
793 case VBLK:
794 vap->va_blksize = DEV_BSIZE;
795 /* FALLTHRU */
796 case VCHR:
797 vap->va_rdev = makedevice(rdev.specdata1, rdev.specdata2);
798 break;
799 case VSOCK:
800 case VFIFO:
801 default:
802 break;
805 return (TRUE);
808 static bool_t
809 xdr_post_op_vattr(XDR *xdrs, post_op_vattr *objp)
812 * DECODE only
814 ASSERT(xdrs->x_op == XDR_DECODE);
816 if (!xdr_bool(xdrs, &objp->attributes))
817 return (FALSE);
819 if (objp->attributes == FALSE)
820 return (TRUE);
822 if (objp->attributes != TRUE)
823 return (FALSE);
825 if (!xdr_fattr3_to_vattr(xdrs, &objp->fres))
826 return (FALSE);
829 * The file size may cause an EFBIG or the time values
830 * may cause EOVERFLOW, if so simply drop the attributes.
832 if (objp->fres.status != NFS3_OK)
833 objp->attributes = FALSE;
835 return (TRUE);
838 bool_t
839 xdr_post_op_attr(XDR *xdrs, post_op_attr *objp)
841 if (!xdr_bool(xdrs, &objp->attributes))
842 return (FALSE);
844 if (objp->attributes == FALSE)
845 return (TRUE);
847 if (objp->attributes != TRUE)
848 return (FALSE);
850 if (!xdr_fattr3(xdrs, &objp->attr))
851 return (FALSE);
854 * Check that we don't get a file we can't handle through
855 * existing interfaces (especially stat64()).
856 * Decode only check since on encode the data has
857 * been dealt with in the above call to xdr_fattr3().
859 if (xdrs->x_op == XDR_DECODE) {
860 /* Set attrs to false if invalid size or time */
861 if (!NFS3_SIZE_OK(objp->attr.size)) {
862 objp->attributes = FALSE;
863 return (TRUE);
865 #ifndef _LP64
866 if (!NFS3_FATTR_TIME_OK(&objp->attr))
867 objp->attributes = FALSE;
868 #endif
870 return (TRUE);
873 static bool_t
874 xdr_wcc_data(XDR *xdrs, wcc_data *objp)
876 int32_t *ptr;
877 wcc_attr *attrp;
879 if (xdrs->x_op == XDR_FREE)
880 return (TRUE);
882 if (xdrs->x_op == XDR_DECODE) {
883 /* pre_op_attr */
884 if (!xdr_bool(xdrs, &objp->before.attributes))
885 return (FALSE);
887 switch (objp->before.attributes) {
888 case TRUE:
889 attrp = &objp->before.attr;
890 ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
891 if (ptr != NULL) {
892 IXDR_GET_U_HYPER(ptr, attrp->size);
893 attrp->mtime.seconds = IXDR_GET_U_INT32(ptr);
894 attrp->mtime.nseconds = IXDR_GET_U_INT32(ptr);
895 attrp->ctime.seconds = IXDR_GET_U_INT32(ptr);
896 attrp->ctime.nseconds = IXDR_GET_U_INT32(ptr);
897 } else {
898 if (!xdr_u_longlong_t(xdrs, &attrp->size))
899 return (FALSE);
900 if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
901 return (FALSE);
902 if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
903 return (FALSE);
904 if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
905 return (FALSE);
906 if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
907 return (FALSE);
910 #ifndef _LP64
912 * check time overflow.
914 if (!NFS3_TIME_OK(attrp->mtime.seconds) ||
915 !NFS3_TIME_OK(attrp->ctime.seconds))
916 objp->before.attributes = FALSE;
917 #endif
918 break;
919 case FALSE:
920 break;
921 default:
922 return (FALSE);
926 if (xdrs->x_op == XDR_ENCODE) {
927 /* pre_op_attr */
928 if (!xdr_bool(xdrs, &objp->before.attributes))
929 return (FALSE);
931 switch (objp->before.attributes) {
932 case TRUE:
933 attrp = &objp->before.attr;
935 ptr = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
936 if (ptr != NULL) {
937 IXDR_PUT_U_HYPER(ptr, attrp->size);
938 IXDR_PUT_U_INT32(ptr, attrp->mtime.seconds);
939 IXDR_PUT_U_INT32(ptr, attrp->mtime.nseconds);
940 IXDR_PUT_U_INT32(ptr, attrp->ctime.seconds);
941 IXDR_PUT_U_INT32(ptr, attrp->ctime.nseconds);
942 } else {
943 if (!xdr_u_longlong_t(xdrs, &attrp->size))
944 return (FALSE);
945 if (!xdr_u_int(xdrs, &attrp->mtime.seconds))
946 return (FALSE);
947 if (!xdr_u_int(xdrs, &attrp->mtime.nseconds))
948 return (FALSE);
949 if (!xdr_u_int(xdrs, &attrp->ctime.seconds))
950 return (FALSE);
951 if (!xdr_u_int(xdrs, &attrp->ctime.nseconds))
952 return (FALSE);
954 break;
955 case FALSE:
956 break;
957 default:
958 return (FALSE);
961 return (xdr_post_op_attr(xdrs, &objp->after));
964 bool_t
965 xdr_post_op_fh3(XDR *xdrs, post_op_fh3 *objp)
967 if (!xdr_bool(xdrs, &objp->handle_follows))
968 return (FALSE);
969 switch (objp->handle_follows) {
970 case TRUE:
971 switch (xdrs->x_op) {
972 case XDR_ENCODE:
973 if (!xdr_nfs_fh3_server(xdrs, &objp->handle))
974 return (FALSE);
975 break;
976 case XDR_FREE:
977 case XDR_DECODE:
978 if (!xdr_nfs_fh3(xdrs, &objp->handle))
979 return (FALSE);
980 break;
982 return (TRUE);
983 case FALSE:
984 return (TRUE);
985 default:
986 return (FALSE);
990 static bool_t
991 xdr_sattr3(XDR *xdrs, sattr3 *objp)
993 /* set_mode3 */
994 if (!xdr_bool(xdrs, &objp->mode.set_it))
995 return (FALSE);
996 if (objp->mode.set_it)
997 if (!xdr_u_int(xdrs, &objp->mode.mode))
998 return (FALSE);
999 /* set_uid3 */
1000 if (!xdr_bool(xdrs, &objp->uid.set_it))
1001 return (FALSE);
1002 if (objp->uid.set_it)
1003 if (!xdr_u_int(xdrs, &objp->uid.uid))
1004 return (FALSE);
1005 /* set_gid3 */
1006 if (!xdr_bool(xdrs, &objp->gid.set_it))
1007 return (FALSE);
1008 if (objp->gid.set_it)
1009 if (!xdr_u_int(xdrs, &objp->gid.gid))
1010 return (FALSE);
1012 /* set_size3 */
1013 if (!xdr_bool(xdrs, &objp->size.set_it))
1014 return (FALSE);
1015 if (objp->size.set_it)
1016 if (!xdr_u_longlong_t(xdrs, &objp->size.size))
1017 return (FALSE);
1019 /* set_atime */
1020 if (!xdr_enum(xdrs, (enum_t *)&objp->atime.set_it))
1021 return (FALSE);
1022 if (objp->atime.set_it == SET_TO_CLIENT_TIME) {
1023 if (!xdr_u_int(xdrs, &objp->atime.atime.seconds))
1024 return (FALSE);
1025 if (!xdr_u_int(xdrs, &objp->atime.atime.nseconds))
1026 return (FALSE);
1029 /* set_mtime */
1030 if (!xdr_enum(xdrs, (enum_t *)&objp->mtime.set_it))
1031 return (FALSE);
1032 if (objp->mtime.set_it == SET_TO_CLIENT_TIME) {
1033 if (!xdr_u_int(xdrs, &objp->mtime.mtime.seconds))
1034 return (FALSE);
1035 if (!xdr_u_int(xdrs, &objp->mtime.mtime.nseconds))
1036 return (FALSE);
1039 return (TRUE);
1042 bool_t
1043 xdr_GETATTR3res(XDR *xdrs, GETATTR3res *objp)
1045 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1046 return (FALSE);
1047 if (objp->status != NFS3_OK)
1048 return (TRUE);
1049 /* xdr_GETATTR3resok */
1050 return (xdr_fattr3(xdrs, &objp->resok.obj_attributes));
1053 bool_t
1054 xdr_GETATTR3vres(XDR *xdrs, GETATTR3vres *objp)
1057 * DECODE or FREE only
1059 if (xdrs->x_op == XDR_FREE)
1060 return (TRUE);
1062 if (xdrs->x_op != XDR_DECODE)
1063 return (FALSE);
1065 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1066 return (FALSE);
1068 if (objp->status != NFS3_OK)
1069 return (TRUE);
1071 return (xdr_fattr3_to_vattr(xdrs, &objp->fres));
1075 bool_t
1076 xdr_SETATTR3args(XDR *xdrs, SETATTR3args *objp)
1078 switch (xdrs->x_op) {
1079 case XDR_FREE:
1080 case XDR_ENCODE:
1081 if (!xdr_nfs_fh3(xdrs, &objp->object))
1082 return (FALSE);
1083 break;
1084 case XDR_DECODE:
1085 if (!xdr_nfs_fh3_server(xdrs, &objp->object))
1086 return (FALSE);
1087 break;
1089 if (!xdr_sattr3(xdrs, &objp->new_attributes))
1090 return (FALSE);
1092 /* sattrguard3 */
1093 if (!xdr_bool(xdrs, &objp->guard.check))
1094 return (FALSE);
1095 switch (objp->guard.check) {
1096 case TRUE:
1097 if (!xdr_u_int(xdrs, &objp->guard.obj_ctime.seconds))
1098 return (FALSE);
1099 return (xdr_u_int(xdrs, &objp->guard.obj_ctime.nseconds));
1100 case FALSE:
1101 return (TRUE);
1102 default:
1103 return (FALSE);
1107 bool_t
1108 xdr_SETATTR3res(XDR *xdrs, SETATTR3res *objp)
1110 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1111 return (FALSE);
1112 switch (objp->status) {
1113 case NFS3_OK:
1114 return (xdr_wcc_data(xdrs, &objp->resok.obj_wcc));
1115 default:
1116 return (xdr_wcc_data(xdrs, &objp->resfail.obj_wcc));
1120 bool_t
1121 xdr_LOOKUP3res(XDR *xdrs, LOOKUP3res *objp)
1123 LOOKUP3resok *resokp;
1125 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1126 return (FALSE);
1128 if (objp->status != NFS3_OK)
1129 return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
1131 /* xdr_LOOKUP3resok */
1132 resokp = &objp->resok;
1133 switch (xdrs->x_op) {
1134 case XDR_ENCODE:
1135 if (!xdr_nfs_fh3_server(xdrs, &resokp->object))
1136 return (FALSE);
1137 break;
1138 case XDR_FREE:
1139 case XDR_DECODE:
1140 if (!xdr_nfs_fh3(xdrs, &resokp->object))
1141 return (FALSE);
1142 break;
1144 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1145 return (FALSE);
1146 return (xdr_post_op_attr(xdrs, &resokp->dir_attributes));
1149 bool_t
1150 xdr_LOOKUP3vres(XDR *xdrs, LOOKUP3vres *objp)
1153 * DECODE or FREE only
1155 if (xdrs->x_op == XDR_FREE)
1156 return (TRUE);
1158 if (xdrs->x_op != XDR_DECODE)
1159 return (FALSE);
1161 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1162 return (FALSE);
1164 if (objp->status != NFS3_OK)
1165 return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
1167 if (!xdr_nfs_fh3(xdrs, &objp->object))
1168 return (FALSE);
1169 if (!xdr_post_op_vattr(xdrs, &objp->obj_attributes))
1170 return (FALSE);
1171 return (xdr_post_op_vattr(xdrs, &objp->dir_attributes));
1174 bool_t
1175 xdr_ACCESS3args(XDR *xdrs, ACCESS3args *objp)
1177 switch (xdrs->x_op) {
1178 case XDR_FREE:
1179 case XDR_ENCODE:
1180 if (!xdr_nfs_fh3(xdrs, &objp->object))
1181 return (FALSE);
1182 break;
1183 case XDR_DECODE:
1184 if (!xdr_nfs_fh3_server(xdrs, &objp->object))
1185 return (FALSE);
1186 break;
1188 return (xdr_u_int(xdrs, &objp->access));
1192 bool_t
1193 xdr_ACCESS3res(XDR *xdrs, ACCESS3res *objp)
1195 ACCESS3resok *resokp;
1197 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1198 return (FALSE);
1199 if (objp->status != NFS3_OK)
1200 return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
1202 /* xdr_ACCESS3resok */
1203 resokp = &objp->resok;
1204 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1205 return (FALSE);
1206 return (xdr_u_int(xdrs, &resokp->access));
1209 bool_t
1210 xdr_READLINK3args(XDR *xdrs, READLINK3args *objp)
1212 rdma_chunkinfo_t rci;
1213 struct xdr_ops *xops = xdrrdma_xops();
1215 if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
1216 xdrs->x_op == XDR_ENCODE) {
1217 rci.rci_type = RCI_REPLY_CHUNK;
1218 rci.rci_len = MAXPATHLEN;
1219 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1221 if (!xdr_nfs_fh3(xdrs, (nfs_fh3 *)objp))
1222 return (FALSE);
1223 return (TRUE);
1226 bool_t
1227 xdr_READLINK3res(XDR *xdrs, READLINK3res *objp)
1230 READLINK3resok *resokp;
1232 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1233 return (FALSE);
1234 if (objp->status != NFS3_OK)
1235 return (xdr_post_op_attr(xdrs,
1236 &objp->resfail.symlink_attributes));
1238 /* xdr_READLINK3resok */
1239 resokp = &objp->resok;
1240 if (!xdr_post_op_attr(xdrs, &resokp->symlink_attributes))
1241 return (FALSE);
1242 return (xdr_string3(xdrs, &resokp->data, MAXPATHLEN));
1245 bool_t
1246 xdr_READ3args(XDR *xdrs, READ3args *objp)
1248 rdma_chunkinfo_t rci;
1249 rdma_wlist_conn_info_t rwci;
1250 struct xdr_ops *xops = xdrrdma_xops();
1252 switch (xdrs->x_op) {
1253 case XDR_FREE:
1254 case XDR_ENCODE:
1255 if (!xdr_nfs_fh3(xdrs, &objp->file))
1256 return (FALSE);
1257 break;
1258 case XDR_DECODE:
1259 if (!xdr_nfs_fh3_server(xdrs, &objp->file))
1260 return (FALSE);
1261 break;
1263 if (!xdr_u_longlong_t(xdrs, &objp->offset))
1264 return (FALSE);
1265 if (!xdr_u_int(xdrs, &objp->count))
1266 return (FALSE);
1268 DTRACE_PROBE1(xdr__i__read3_buf_len, int, objp->count);
1270 objp->wlist = NULL;
1272 /* if xdrrdma_sizeof in progress, then store the size */
1273 if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
1274 rci.rci_type = RCI_WRITE_ADDR_CHUNK;
1275 rci.rci_len = objp->count;
1276 (void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
1279 if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
1280 return (TRUE);
1282 if (xdrs->x_op == XDR_ENCODE) {
1284 if (objp->res_uiop != NULL) {
1285 rci.rci_type = RCI_WRITE_UIO_CHUNK;
1286 rci.rci_a.rci_uiop = objp->res_uiop;
1287 rci.rci_len = objp->count;
1288 rci.rci_clpp = &objp->wlist;
1289 } else {
1290 rci.rci_type = RCI_WRITE_ADDR_CHUNK;
1291 rci.rci_a.rci_addr = objp->res_data_val_alt;
1292 rci.rci_len = objp->count;
1293 rci.rci_clpp = &objp->wlist;
1296 return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
1299 /* XDR_DECODE case */
1300 (void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
1301 objp->wlist = rwci.rwci_wlist;
1302 objp->conn = rwci.rwci_conn;
1304 return (TRUE);
1307 bool_t
1308 xdr_READ3res(XDR *xdrs, READ3res *objp)
1310 READ3resok *resokp;
1311 bool_t ret;
1312 mblk_t *mp;
1314 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1315 return (FALSE);
1317 if (objp->status != NFS3_OK)
1318 return (xdr_post_op_attr(xdrs, &objp->resfail.file_attributes));
1320 resokp = &objp->resok;
1322 if (xdr_post_op_attr(xdrs, &resokp->file_attributes) == FALSE ||
1323 xdr_u_int(xdrs, &resokp->count) == FALSE ||
1324 xdr_bool(xdrs, &resokp->eof) == FALSE) {
1325 return (FALSE);
1328 if (xdrs->x_op == XDR_ENCODE) {
1330 mp = resokp->data.mp;
1331 if (mp != NULL) {
1332 if (xdrs->x_ops == &xdrmblk_ops) {
1333 if (xdrmblk_putmblk(xdrs, mp, resokp->count)) {
1334 resokp->data.mp = NULL;
1335 return (TRUE);
1336 } else {
1337 return (FALSE);
1339 } else if (mp->b_cont != NULL) {
1341 * We have read results in an mblk chain, but
1342 * the encoding operations don't handle mblks
1343 * (they'll operate on data.data_val rather
1344 * than data.mp). Because data_val can only
1345 * point at a single data buffer, we need to
1346 * pullup the read results into a single data
1347 * block and reset data_val to point to it.
1349 * This happens with RPC GSS where the wrapping
1350 * function does XDR serialization into a
1351 * temporary buffer prior to applying GSS.
1352 * Because we're not in a performance sensitive
1353 * path, the pullupmsg() here shouldn't hurt us
1354 * too badly.
1356 if (pullupmsg(mp, -1) == 0)
1357 return (FALSE);
1358 resokp->data.data_val = (caddr_t)mp->b_rptr;
1360 } else {
1361 if (xdr_u_int(xdrs, &resokp->count) == FALSE) {
1362 return (FALSE);
1365 * If read data sent by wlist (RDMA_WRITE), don't do
1366 * xdr_bytes() below. RDMA_WRITE transfers the data.
1367 * Note: this is encode-only because the client code
1368 * uses xdr_READ3vres/xdr_READ3uiores to decode results.
1370 if (resokp->wlist) {
1371 if (resokp->count != 0) {
1372 return (xdrrdma_send_read_data(
1373 xdrs, resokp->count,
1374 resokp->wlist));
1376 return (TRUE);
1380 * Fall thru for the xdr_bytes()
1382 * note: the mblk will be freed in
1383 * rfs3_read_free.
1387 /* no RDMA_WRITE transfer -- send data inline */
1389 ret = xdr_bytes(xdrs, (char **)&resokp->data.data_val,
1390 &resokp->data.data_len, nfs3tsize());
1392 return (ret);
1395 bool_t
1396 xdr_READ3vres(XDR *xdrs, READ3vres *objp)
1398 count3 ocount;
1400 * DECODE or FREE only
1402 if (xdrs->x_op == XDR_FREE)
1403 return (TRUE);
1405 if (xdrs->x_op != XDR_DECODE)
1406 return (FALSE);
1408 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1409 return (FALSE);
1411 if (!xdr_post_op_vattr(xdrs, &objp->pov))
1412 return (FALSE);
1414 if (objp->status != NFS3_OK)
1415 return (TRUE);
1417 if (!xdr_u_int(xdrs, &objp->count))
1418 return (FALSE);
1420 if (!xdr_bool(xdrs, &objp->eof))
1421 return (FALSE);
1424 * If read data received via RDMA_WRITE, don't do xdr_bytes().
1425 * RDMA_WRITE already moved the data so decode length of RDMA_WRITE.
1427 if (xdrs->x_ops == &xdrrdma_ops) {
1428 struct clist *cl;
1430 XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
1432 if (cl) {
1433 if (!xdr_u_int(xdrs, &ocount)) {
1434 return (FALSE);
1436 if (ocount != objp->count) {
1437 DTRACE_PROBE2(xdr__e__read3vres_fail,
1438 int, ocount, int, objp->count);
1439 objp->wlist = NULL;
1440 return (FALSE);
1443 objp->wlist_len = clist_len(cl);
1444 objp->data.data_len = ocount;
1446 if (objp->wlist_len !=
1447 roundup(objp->data.data_len, BYTES_PER_XDR_UNIT)) {
1448 DTRACE_PROBE2(
1449 xdr__e__read3vres_fail,
1450 int, ocount,
1451 int, objp->data.data_len);
1452 objp->wlist = NULL;
1453 return (FALSE);
1455 return (TRUE);
1459 return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
1460 &objp->data.data_len, nfs3tsize()));
1463 bool_t
1464 xdr_READ3uiores(XDR *xdrs, READ3uiores *objp)
1466 count3 ocount;
1467 bool_t attributes;
1468 mblk_t *mp;
1469 size_t n;
1470 int error;
1471 int size = (int)objp->size;
1472 struct uio *uiop = objp->uiop;
1473 int32_t fattr3_len = NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
1474 int32_t *ptr;
1477 * DECODE or FREE only
1479 if (xdrs->x_op == XDR_FREE)
1480 return (TRUE);
1482 if (xdrs->x_op != XDR_DECODE)
1483 return (FALSE);
1485 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
1486 return (FALSE);
1488 if (!XDR_GETINT32(xdrs, (int32_t *)&attributes))
1489 return (FALSE);
1492 * For directio we just skip over attributes if present
1494 switch (attributes) {
1495 case TRUE:
1496 if (!XDR_CONTROL(xdrs, XDR_SKIPBYTES, &fattr3_len))
1497 return (FALSE);
1498 break;
1499 case FALSE:
1500 break;
1501 default:
1502 return (FALSE);
1505 if (objp->status != NFS3_OK)
1506 return (TRUE);
1508 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->count))
1509 return (FALSE);
1511 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
1512 return (FALSE);
1514 if (xdrs->x_ops == &xdrmblk_ops) {
1515 if (!xdrmblk_getmblk(xdrs, &mp, &objp->size))
1516 return (FALSE);
1518 if (objp->size == 0)
1519 return (TRUE);
1521 if (objp->size > size)
1522 return (FALSE);
1524 size = (int)objp->size;
1525 do {
1526 n = MIN(size, mp->b_wptr - mp->b_rptr);
1527 if ((n = MIN(uiop->uio_resid, n)) != 0) {
1529 error = uiomove((char *)mp->b_rptr, n, UIO_READ,
1530 uiop);
1531 if (error)
1532 return (FALSE);
1533 mp->b_rptr += n;
1534 size -= n;
1537 while (mp && (mp->b_rptr >= mp->b_wptr))
1538 mp = mp->b_cont;
1539 } while (mp && size > 0 && uiop->uio_resid > 0);
1541 return (TRUE);
1544 if (xdrs->x_ops == &xdrrdma_ops) {
1545 struct clist *cl;
1547 XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
1549 objp->wlist = cl;
1551 if (objp->wlist) {
1552 if (!xdr_u_int(xdrs, &ocount)) {
1553 objp->wlist = NULL;
1554 return (FALSE);
1557 if (ocount != objp->count) {
1558 DTRACE_PROBE2(xdr__e__read3uiores_fail,
1559 int, ocount, int, objp->count);
1560 objp->wlist = NULL;
1561 return (FALSE);
1564 objp->wlist_len = clist_len(cl);
1566 uiop->uio_resid -= objp->count;
1567 uiop->uio_iov->iov_len -= objp->count;
1568 uiop->uio_iov->iov_base += objp->count;
1569 uiop->uio_loffset += objp->count;
1572 * XXX: Assume 1 iov, needs to be changed.
1574 objp->size = objp->count;
1576 return (TRUE);
1581 * This isn't an xdrmblk stream nor RDMA.
1582 * Handle the likely case that it can be
1583 * inlined (ex. xdrmem).
1585 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->size))
1586 return (FALSE);
1588 if (objp->size == 0)
1589 return (TRUE);
1591 if (objp->size > size)
1592 return (FALSE);
1594 size = (int)objp->size;
1595 if ((ptr = XDR_INLINE(xdrs, size)) != NULL)
1596 return (uiomove(ptr, size, UIO_READ, uiop) ? FALSE : TRUE);
1599 * Handle some other (unlikely) stream type that will need a copy.
1601 if ((ptr = kmem_alloc(size, KM_NOSLEEP)) == NULL)
1602 return (FALSE);
1604 if (!XDR_GETBYTES(xdrs, (caddr_t)ptr, size)) {
1605 kmem_free(ptr, size);
1606 return (FALSE);
1608 error = uiomove(ptr, size, UIO_READ, uiop);
1609 kmem_free(ptr, size);
1611 return (error ? FALSE : TRUE);
1614 bool_t
1615 xdr_WRITE3args(XDR *xdrs, WRITE3args *objp)
1617 switch (xdrs->x_op) {
1618 case XDR_FREE:
1619 case XDR_ENCODE:
1620 if (!xdr_nfs_fh3(xdrs, &objp->file))
1621 return (FALSE);
1622 break;
1623 case XDR_DECODE:
1624 if (!xdr_nfs_fh3_server(xdrs, &objp->file))
1625 return (FALSE);
1626 break;
1628 if (!xdr_u_longlong_t(xdrs, &objp->offset))
1629 return (FALSE);
1630 if (!xdr_u_int(xdrs, &objp->count))
1631 return (FALSE);
1632 if (!xdr_enum(xdrs, (enum_t *)&objp->stable))
1633 return (FALSE);
1635 if (xdrs->x_op == XDR_DECODE) {
1636 if (xdrs->x_ops == &xdrmblk_ops) {
1637 if (xdrmblk_getmblk(xdrs, &objp->mblk,
1638 &objp->data.data_len) == TRUE) {
1639 objp->data.data_val = NULL;
1640 return (TRUE);
1643 objp->mblk = NULL;
1645 if (xdrs->x_ops == &xdrrdmablk_ops) {
1646 if (xdrrdma_getrdmablk(xdrs, &objp->rlist,
1647 &objp->data.data_len,
1648 &objp->conn, nfs3tsize()) == TRUE) {
1649 objp->data.data_val = NULL;
1650 if (xdrrdma_read_from_client(
1651 objp->rlist,
1652 &objp->conn,
1653 objp->count) == FALSE) {
1654 return (FALSE);
1656 return (TRUE);
1659 objp->rlist = NULL;
1661 /* Else fall thru for the xdr_bytes(). */
1664 if (xdrs->x_op == XDR_FREE) {
1665 if (objp->rlist != NULL) {
1666 (void) xdrrdma_free_clist(objp->conn, objp->rlist);
1667 objp->rlist = NULL;
1668 objp->data.data_val = NULL;
1669 return (TRUE);
1673 DTRACE_PROBE1(xdr__i__write3_buf_len,
1674 int, objp->data.data_len);
1676 return (xdr_bytes(xdrs, (char **)&objp->data.data_val,
1677 &objp->data.data_len, nfs3tsize()));
1680 bool_t
1681 xdr_WRITE3res(XDR *xdrs, WRITE3res *objp)
1683 WRITE3resok *resokp;
1685 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1686 return (FALSE);
1687 if (objp->status != NFS3_OK) /* xdr_WRITE3resfail */
1688 return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
1690 /* xdr_WRITE3resok */
1691 resokp = &objp->resok;
1692 if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
1693 return (FALSE);
1694 if (!xdr_u_int(xdrs, &resokp->count))
1695 return (FALSE);
1696 if (!xdr_enum(xdrs, (enum_t *)&resokp->committed))
1697 return (FALSE);
1699 * writeverf3 is really an opaque 8 byte
1700 * quantity, but we will treat it as a
1701 * hyper for efficiency, the cost of
1702 * a byteswap here saves bcopys elsewhere
1704 return (xdr_u_longlong_t(xdrs, &resokp->verf));
1707 bool_t
1708 xdr_CREATE3args(XDR *xdrs, CREATE3args *objp)
1710 createhow3 *howp;
1712 if (!xdr_diropargs3(xdrs, &objp->where))
1713 return (FALSE);
1715 /* xdr_createhow3 */
1716 howp = &objp->how;
1718 if (!xdr_enum(xdrs, (enum_t *)&howp->mode))
1719 return (FALSE);
1720 switch (howp->mode) {
1721 case UNCHECKED:
1722 case GUARDED:
1723 return (xdr_sattr3(xdrs, &howp->createhow3_u.obj_attributes));
1724 case EXCLUSIVE:
1726 * createverf3 is really an opaque 8 byte
1727 * quantity, but we will treat it as a
1728 * hyper for efficiency, the cost of
1729 * a byteswap here saves bcopys elsewhere
1731 return (xdr_u_longlong_t(xdrs, &howp->createhow3_u.verf));
1732 default:
1733 return (FALSE);
1737 bool_t
1738 xdr_CREATE3res(XDR *xdrs, CREATE3res *objp)
1740 CREATE3resok *resokp;
1742 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1743 return (FALSE);
1744 switch (objp->status) {
1745 case NFS3_OK:
1746 /* xdr_CREATE3resok */
1747 resokp = &objp->resok;
1749 if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1750 return (FALSE);
1751 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1752 return (FALSE);
1753 return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1754 default:
1755 /* xdr_CREATE3resfail */
1756 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1760 bool_t
1761 xdr_MKDIR3args(XDR *xdrs, MKDIR3args *objp)
1763 if (!xdr_diropargs3(xdrs, &objp->where))
1764 return (FALSE);
1765 return (xdr_sattr3(xdrs, &objp->attributes));
1768 bool_t
1769 xdr_MKDIR3res(XDR *xdrs, MKDIR3res *objp)
1771 MKDIR3resok *resokp;
1773 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1774 return (FALSE);
1775 switch (objp->status) {
1776 case NFS3_OK:
1777 /* xdr_MKDIR3resok */
1778 resokp = &objp->resok;
1780 if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1781 return (FALSE);
1782 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1783 return (FALSE);
1784 return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1785 default:
1786 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1790 bool_t
1791 xdr_SYMLINK3args(XDR *xdrs, SYMLINK3args *objp)
1793 if (!xdr_diropargs3(xdrs, &objp->where))
1794 return (FALSE);
1795 if (!xdr_sattr3(xdrs, &objp->symlink.symlink_attributes))
1796 return (FALSE);
1797 return (xdr_string3(xdrs, &objp->symlink.symlink_data, MAXPATHLEN));
1800 bool_t
1801 xdr_SYMLINK3res(XDR *xdrs, SYMLINK3res *objp)
1803 SYMLINK3resok *resokp;
1805 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1806 return (FALSE);
1807 switch (objp->status) {
1808 case NFS3_OK:
1809 resokp = &objp->resok;
1810 /* xdr_SYMLINK3resok */
1811 if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1812 return (FALSE);
1813 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1814 return (FALSE);
1815 return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1816 default:
1817 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1821 bool_t
1822 xdr_MKNOD3args(XDR *xdrs, MKNOD3args *objp)
1824 mknoddata3 *whatp;
1825 devicedata3 *nod_objp;
1827 if (!xdr_diropargs3(xdrs, &objp->where))
1828 return (FALSE);
1830 whatp = &objp->what;
1831 if (!xdr_enum(xdrs, (enum_t *)&whatp->type))
1832 return (FALSE);
1833 switch (whatp->type) {
1834 case NF3CHR:
1835 case NF3BLK:
1836 /* xdr_devicedata3 */
1837 nod_objp = &whatp->mknoddata3_u.device;
1838 if (!xdr_sattr3(xdrs, &nod_objp->dev_attributes))
1839 return (FALSE);
1840 if (!xdr_u_int(xdrs, &nod_objp->spec.specdata1))
1841 return (FALSE);
1842 return (xdr_u_int(xdrs, &nod_objp->spec.specdata2));
1843 case NF3SOCK:
1844 case NF3FIFO:
1845 return (xdr_sattr3(xdrs, &whatp->mknoddata3_u.pipe_attributes));
1846 default:
1847 break;
1849 return (TRUE);
1852 bool_t
1853 xdr_MKNOD3res(XDR *xdrs, MKNOD3res *objp)
1855 MKNOD3resok *resokp;
1857 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1858 return (FALSE);
1859 switch (objp->status) {
1860 case NFS3_OK:
1861 /* xdr_MKNOD3resok */
1862 resokp = &objp->resok;
1863 if (!xdr_post_op_fh3(xdrs, &resokp->obj))
1864 return (FALSE);
1865 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
1866 return (FALSE);
1867 return (xdr_wcc_data(xdrs, &resokp->dir_wcc));
1868 default:
1869 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1873 bool_t
1874 xdr_REMOVE3res(XDR *xdrs, REMOVE3res *objp)
1876 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1877 return (FALSE);
1878 switch (objp->status) {
1879 case NFS3_OK:
1880 return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
1881 default:
1882 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1886 bool_t
1887 xdr_RMDIR3res(XDR *xdrs, RMDIR3res *objp)
1889 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1890 return (FALSE);
1891 switch (objp->status) {
1892 case NFS3_OK:
1893 return (xdr_wcc_data(xdrs, &objp->resok.dir_wcc));
1894 default:
1895 return (xdr_wcc_data(xdrs, &objp->resfail.dir_wcc));
1899 bool_t
1900 xdr_RENAME3args(XDR *xdrs, RENAME3args *objp)
1902 if (!xdr_diropargs3(xdrs, &objp->from))
1903 return (FALSE);
1904 return (xdr_diropargs3(xdrs, &objp->to));
1907 bool_t
1908 xdr_RENAME3res(XDR *xdrs, RENAME3res *objp)
1910 RENAME3resok *resokp;
1911 RENAME3resfail *resfailp;
1913 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1914 return (FALSE);
1915 switch (objp->status) {
1916 case NFS3_OK:
1917 /* xdr_RENAME3resok */
1918 resokp = &objp->resok;
1920 if (!xdr_wcc_data(xdrs, &resokp->fromdir_wcc))
1921 return (FALSE);
1922 return (xdr_wcc_data(xdrs, &resokp->todir_wcc));
1923 default:
1924 /* xdr_RENAME3resfail */
1925 resfailp = &objp->resfail;
1926 if (!xdr_wcc_data(xdrs, &resfailp->fromdir_wcc))
1927 return (FALSE);
1928 return (xdr_wcc_data(xdrs, &resfailp->todir_wcc));
1932 bool_t
1933 xdr_LINK3args(XDR *xdrs, LINK3args *objp)
1935 switch (xdrs->x_op) {
1936 case XDR_FREE:
1937 case XDR_ENCODE:
1938 if (!xdr_nfs_fh3(xdrs, &objp->file))
1939 return (FALSE);
1940 break;
1941 case XDR_DECODE:
1942 if (!xdr_nfs_fh3_server(xdrs, &objp->file))
1943 return (FALSE);
1944 break;
1946 return (xdr_diropargs3(xdrs, &objp->link));
1949 bool_t
1950 xdr_LINK3res(XDR *xdrs, LINK3res *objp)
1952 LINK3resok *resokp;
1953 LINK3resfail *resfailp;
1955 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
1956 return (FALSE);
1957 switch (objp->status) {
1958 case NFS3_OK:
1959 /* xdr_LINK3resok */
1960 resokp = &objp->resok;
1961 if (!xdr_post_op_attr(xdrs, &resokp->file_attributes))
1962 return (FALSE);
1963 return (xdr_wcc_data(xdrs, &resokp->linkdir_wcc));
1964 default:
1965 /* xdr_LINK3resfail */
1966 resfailp = &objp->resfail;
1967 if (!xdr_post_op_attr(xdrs, &resfailp->file_attributes))
1968 return (FALSE);
1969 return (xdr_wcc_data(xdrs, &resfailp->linkdir_wcc));
1973 bool_t
1974 xdr_READDIR3args(XDR *xdrs, READDIR3args *objp)
1976 rdma_chunkinfo_t rci;
1977 struct xdr_ops *xops = xdrrdma_xops();
1979 if (xdrs->x_op == XDR_FREE)
1980 return (TRUE);
1982 switch (xdrs->x_op) {
1983 case XDR_FREE:
1984 case XDR_ENCODE:
1985 if (!xdr_nfs_fh3(xdrs, &objp->dir))
1986 return (FALSE);
1987 break;
1988 case XDR_DECODE:
1989 if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
1990 return (FALSE);
1991 break;
1993 if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
1994 xdrs->x_op == XDR_ENCODE) {
1995 rci.rci_type = RCI_REPLY_CHUNK;
1996 rci.rci_len = objp->count;
1997 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
2000 if (!xdr_u_longlong_t(xdrs, &objp->cookie))
2001 return (FALSE);
2003 * cookieverf is really an opaque 8 byte
2004 * quantity, but we will treat it as a
2005 * hyper for efficiency, the cost of
2006 * a byteswap here saves bcopys elsewhere
2008 if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2009 return (FALSE);
2010 return (xdr_u_int(xdrs, &objp->count));
2013 #ifdef nextdp
2014 #undef nextdp
2015 #endif
2016 #define nextdp(dp) ((struct dirent *)((char *)(dp) + (dp)->d_reclen))
2017 #ifdef roundup
2018 #undef roundup
2019 #endif
2020 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
2023 * ENCODE ONLY
2025 static bool_t
2026 xdr_putdirlist(XDR *xdrs, READDIR3resok *objp)
2028 struct dirent *dp;
2029 char *name;
2030 int size;
2031 int bufsize;
2032 uint_t namlen;
2033 bool_t t = TRUE;
2034 bool_t f = FALSE;
2035 int entrysz;
2036 int tofit;
2037 fileid3 fileid;
2038 cookie3 cookie;
2040 if (xdrs->x_op != XDR_ENCODE)
2041 return (FALSE);
2044 * bufsize is used to keep track of the size of the response.
2045 * It is primed with:
2046 * 1 for the status +
2047 * 1 for the dir_attributes.attributes boolean +
2048 * 2 for the cookie verifier
2049 * all times BYTES_PER_XDR_UNIT to convert from XDR units
2050 * to bytes. If there are directory attributes to be
2051 * returned, then:
2052 * NFS3_SIZEOF_FATTR3 for the dir_attributes.attr fattr3
2053 * time BYTES_PER_XDR_UNIT is added to account for them.
2055 bufsize = (1 + 1 + 2) * BYTES_PER_XDR_UNIT;
2056 if (objp->dir_attributes.attributes)
2057 bufsize += NFS3_SIZEOF_FATTR3 * BYTES_PER_XDR_UNIT;
2058 for (size = objp->size, dp = (struct dirent *)objp->reply.entries;
2059 size > 0;
2060 size -= dp->d_reclen, dp = nextdp(dp)) {
2061 if (dp->d_reclen == 0)
2062 return (FALSE);
2063 if (dp->d_ino == 0)
2064 continue;
2065 name = dp->d_name;
2066 namlen = (uint_t)strlen(dp->d_name);
2068 * An entry is composed of:
2069 * 1 for the true/false list indicator +
2070 * 2 for the fileid +
2071 * 1 for the length of the name +
2072 * 2 for the cookie +
2073 * all times BYTES_PER_XDR_UNIT to convert from
2074 * XDR units to bytes, plus the length of the name
2075 * rounded up to the nearest BYTES_PER_XDR_UNIT.
2077 entrysz = (1 + 2 + 1 + 2) * BYTES_PER_XDR_UNIT +
2078 roundup(namlen, BYTES_PER_XDR_UNIT);
2080 * We need to check to see if the number of bytes left
2081 * to go into the buffer will actually fit into the
2082 * buffer. This is calculated as the size of this
2083 * entry plus:
2084 * 1 for the true/false list indicator +
2085 * 1 for the eof indicator
2086 * times BYTES_PER_XDR_UNIT to convert from from
2087 * XDR units to bytes.
2089 tofit = entrysz + (1 + 1) * BYTES_PER_XDR_UNIT;
2090 if (bufsize + tofit > objp->count) {
2091 objp->reply.eof = FALSE;
2092 break;
2094 fileid = (fileid3)(dp->d_ino);
2095 cookie = (cookie3)(dp->d_off);
2096 if (!xdr_bool(xdrs, &t) ||
2097 !xdr_u_longlong_t(xdrs, &fileid) ||
2098 !xdr_bytes(xdrs, &name, &namlen, ~0) ||
2099 !xdr_u_longlong_t(xdrs, &cookie)) {
2100 return (FALSE);
2102 bufsize += entrysz;
2104 if (!xdr_bool(xdrs, &f))
2105 return (FALSE);
2106 if (!xdr_bool(xdrs, &objp->reply.eof))
2107 return (FALSE);
2108 return (TRUE);
2111 bool_t
2112 xdr_READDIR3res(XDR *xdrs, READDIR3res *objp)
2114 READDIR3resok *resokp;
2117 * ENCODE or FREE only
2119 if (xdrs->x_op == XDR_DECODE)
2120 return (FALSE);
2122 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2123 return (FALSE);
2124 if (objp->status != NFS3_OK)
2125 return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
2127 /* xdr_READDIR3resok */
2128 resokp = &objp->resok;
2129 if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
2130 return (FALSE);
2131 if (xdrs->x_op != XDR_ENCODE)
2132 return (TRUE);
2134 * cookieverf is really an opaque 8 byte
2135 * quantity, but we will treat it as a
2136 * hyper for efficiency, the cost of
2137 * a byteswap here saves bcopys elsewhere
2139 if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
2140 return (FALSE);
2141 return (xdr_putdirlist(xdrs, resokp));
2144 bool_t
2145 xdr_READDIR3vres(XDR *xdrs, READDIR3vres *objp)
2147 dirent_t *dp;
2148 uint_t entries_size;
2149 int outcount = 0;
2152 * DECODE or FREE only
2154 if (xdrs->x_op == XDR_FREE)
2155 return (TRUE);
2157 if (xdrs->x_op != XDR_DECODE)
2158 return (FALSE);
2160 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2161 return (FALSE);
2163 if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
2164 return (FALSE);
2166 if (objp->status != NFS3_OK)
2167 return (TRUE);
2170 * cookieverf is really an opaque 8 byte
2171 * quantity, but we will treat it as a
2172 * hyper for efficiency, the cost of
2173 * a byteswap here saves bcopys elsewhere
2175 if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2176 return (FALSE);
2178 entries_size = objp->entries_size;
2179 dp = objp->entries;
2181 for (;;) {
2182 uint_t this_reclen;
2183 bool_t valid;
2184 uint_t namlen;
2185 ino64_t fileid;
2187 if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
2188 return (FALSE);
2189 if (!valid) {
2191 * We have run out of entries, decode eof.
2193 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
2194 return (FALSE);
2196 break;
2200 * fileid3 fileid
2202 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
2203 return (FALSE);
2206 * filename3 name
2208 if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
2209 return (FALSE);
2210 this_reclen = DIRENT_RECLEN(namlen);
2213 * If this will overflow buffer, stop decoding
2215 if ((outcount + this_reclen) > entries_size) {
2216 objp->eof = FALSE;
2217 break;
2219 dp->d_reclen = this_reclen;
2220 dp->d_ino = fileid;
2222 if (!xdr_opaque(xdrs, dp->d_name, namlen))
2223 return (FALSE);
2224 bzero(&dp->d_name[namlen],
2225 DIRENT_NAMELEN(this_reclen) - namlen);
2228 * cookie3 cookie
2230 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
2231 return (FALSE);
2232 objp->loff = dp->d_off;
2234 outcount += this_reclen;
2235 dp = (dirent_t *)((intptr_t)dp + this_reclen);
2238 objp->size = outcount;
2239 return (TRUE);
2242 bool_t
2243 xdr_READDIRPLUS3args(XDR *xdrs, READDIRPLUS3args *objp)
2245 rdma_chunkinfo_t rci;
2246 struct xdr_ops *xops = xdrrdma_xops();
2248 if (xdrs->x_op == XDR_FREE)
2249 return (TRUE);
2251 switch (xdrs->x_op) {
2252 case XDR_FREE:
2253 case XDR_ENCODE:
2254 if (!xdr_nfs_fh3(xdrs, &objp->dir))
2255 return (FALSE);
2256 break;
2257 case XDR_DECODE:
2258 if (!xdr_nfs_fh3_server(xdrs, &objp->dir))
2259 return (FALSE);
2260 break;
2262 if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
2263 xdrs->x_op == XDR_ENCODE) {
2264 rci.rci_type = RCI_REPLY_CHUNK;
2265 rci.rci_len = objp->maxcount;
2266 XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
2269 if (!xdr_u_longlong_t(xdrs, &objp->cookie))
2270 return (FALSE);
2272 * cookieverf is really an opaque 8 byte
2273 * quantity, but we will treat it as a
2274 * hyper for efficiency, the cost of
2275 * a byteswap here saves bcopys elsewhere
2277 if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2278 return (FALSE);
2279 if (!xdr_u_int(xdrs, &objp->dircount))
2280 return (FALSE);
2281 return (xdr_u_int(xdrs, &objp->maxcount));
2285 * ENCODE ONLY
2287 static bool_t
2288 xdr_putdirpluslist(XDR *xdrs, READDIRPLUS3resok *objp)
2290 struct dirent *dp;
2291 char *name;
2292 int nents;
2293 bool_t t = TRUE;
2294 bool_t f = FALSE;
2295 fileid3 fileid;
2296 cookie3 cookie;
2297 entryplus3_info *infop;
2299 if (xdrs->x_op != XDR_ENCODE)
2300 return (FALSE);
2302 dp = (struct dirent *)objp->reply.entries;
2303 nents = objp->size;
2304 infop = objp->infop;
2306 while (nents > 0) {
2307 if (dp->d_reclen == 0)
2308 return (FALSE);
2309 if (dp->d_ino != 0) {
2310 name = dp->d_name;
2311 fileid = (fileid3)(dp->d_ino);
2312 cookie = (cookie3)(dp->d_off);
2313 if (!xdr_bool(xdrs, &t) ||
2314 !xdr_u_longlong_t(xdrs, &fileid) ||
2315 !xdr_bytes(xdrs, &name, &infop->namelen, ~0) ||
2316 !xdr_u_longlong_t(xdrs, &cookie) ||
2317 !xdr_post_op_attr(xdrs, &infop->attr) ||
2318 !xdr_post_op_fh3(xdrs, &infop->fh)) {
2319 return (FALSE);
2322 dp = nextdp(dp);
2323 infop++;
2324 nents--;
2327 if (!xdr_bool(xdrs, &f))
2328 return (FALSE);
2329 if (!xdr_bool(xdrs, &objp->reply.eof))
2330 return (FALSE);
2331 return (TRUE);
2334 bool_t
2335 xdr_READDIRPLUS3res(XDR *xdrs, READDIRPLUS3res *objp)
2337 READDIRPLUS3resok *resokp;
2340 * ENCODE or FREE only
2342 if (xdrs->x_op == XDR_DECODE)
2343 return (FALSE);
2345 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2346 return (FALSE);
2347 switch (objp->status) {
2348 case NFS3_OK:
2349 /* xdr_READDIRPLUS3resok */
2350 resokp = &objp->resok;
2351 if (!xdr_post_op_attr(xdrs, &resokp->dir_attributes))
2352 return (FALSE);
2354 * cookieverf is really an opaque 8 byte
2355 * quantity, but we will treat it as a
2356 * hyper for efficiency, the cost of
2357 * a byteswap here saves bcopys elsewhere
2359 if (!xdr_u_longlong_t(xdrs, &resokp->cookieverf))
2360 return (FALSE);
2361 if (xdrs->x_op == XDR_ENCODE) {
2362 if (!xdr_putdirpluslist(xdrs, resokp))
2363 return (FALSE);
2365 break;
2366 default:
2367 return (xdr_post_op_attr(xdrs, &objp->resfail.dir_attributes));
2369 return (TRUE);
2373 * Decode readdirplus directly into a dirent_t and do the DNLC caching.
2375 bool_t
2376 xdr_READDIRPLUS3vres(XDR *xdrs, READDIRPLUS3vres *objp)
2378 dirent_t *dp;
2379 vnode_t *dvp;
2380 uint_t entries_size;
2381 int outcount = 0;
2382 vnode_t *nvp;
2383 rnode_t *rp;
2384 post_op_vattr pov;
2385 vattr_t va;
2388 * DECODE or FREE only
2390 if (xdrs->x_op == XDR_FREE)
2391 return (TRUE);
2393 if (xdrs->x_op != XDR_DECODE)
2394 return (FALSE);
2396 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->status))
2397 return (FALSE);
2399 if (!xdr_post_op_vattr(xdrs, &objp->dir_attributes))
2400 return (FALSE);
2402 if (objp->status != NFS3_OK)
2403 return (TRUE);
2406 * cookieverf is really an opaque 8 byte
2407 * quantity, but we will treat it as a
2408 * hyper for efficiency, the cost of
2409 * a byteswap here saves bcopys elsewhere
2411 if (!xdr_u_longlong_t(xdrs, &objp->cookieverf))
2412 return (FALSE);
2414 dvp = objp->dir_attributes.fres.vp;
2415 rp = VTOR(dvp);
2417 pov.fres.vap = &va;
2418 pov.fres.vp = dvp;
2420 entries_size = objp->entries_size;
2421 dp = objp->entries;
2423 for (;;) {
2424 uint_t this_reclen;
2425 bool_t valid;
2426 uint_t namlen;
2427 nfs_fh3 fh;
2428 int va_valid;
2429 int fh_valid;
2430 ino64_t fileid;
2432 if (!XDR_GETINT32(xdrs, (int32_t *)&valid))
2433 return (FALSE);
2434 if (!valid) {
2436 * We have run out of entries, decode eof.
2438 if (!XDR_GETINT32(xdrs, (int32_t *)&objp->eof))
2439 return (FALSE);
2441 break;
2445 * fileid3 fileid
2447 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&fileid))
2448 return (FALSE);
2451 * filename3 name
2453 if (!XDR_GETINT32(xdrs, (int32_t *)&namlen))
2454 return (FALSE);
2455 this_reclen = DIRENT_RECLEN(namlen);
2458 * If this will overflow buffer, stop decoding
2460 if ((outcount + this_reclen) > entries_size) {
2461 objp->eof = FALSE;
2462 break;
2464 dp->d_reclen = this_reclen;
2465 dp->d_ino = fileid;
2467 if (!xdr_opaque(xdrs, dp->d_name, namlen))
2468 return (FALSE);
2469 bzero(&dp->d_name[namlen],
2470 DIRENT_NAMELEN(this_reclen) - namlen);
2473 * cookie3 cookie
2475 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&dp->d_off))
2476 return (FALSE);
2477 objp->loff = dp->d_off;
2480 * post_op_attr name_attributes
2482 if (!xdr_post_op_vattr(xdrs, &pov))
2483 return (FALSE);
2485 if (pov.attributes == TRUE &&
2486 pov.fres.status == NFS3_OK)
2487 va_valid = TRUE;
2488 else
2489 va_valid = FALSE;
2492 * post_op_fh3 name_handle
2494 if (!XDR_GETINT32(xdrs, (int32_t *)&fh_valid))
2495 return (FALSE);
2498 * By definition of the standard fh_valid can be 0 (FALSE) or
2499 * 1 (TRUE), but we have to account for it being anything else
2500 * in case some other system didn't follow the standard. Note
2501 * that this is why the else checks if the fh_valid variable
2502 * is != FALSE.
2504 if (fh_valid == TRUE) {
2505 if (!xdr_nfs_fh3(xdrs, &fh))
2506 return (FALSE);
2507 } else {
2508 if (fh_valid != FALSE)
2509 return (FALSE);
2513 * If the name is "." or there are no attributes,
2514 * don't polute the DNLC with "." entries or files
2515 * we cannot determine the type for.
2517 if (!(namlen == 1 && dp->d_name[0] == '.') &&
2518 va_valid && fh_valid) {
2521 * Do the DNLC caching
2523 nvp = makenfs3node_va(&fh, &va, dvp->v_vfsp,
2524 objp->time, objp->credentials,
2525 rp->r_path, dp->d_name);
2526 dnlc_update(dvp, dp->d_name, nvp);
2527 VN_RELE(nvp);
2530 outcount += this_reclen;
2531 dp = (dirent_t *)((intptr_t)dp + this_reclen);
2534 objp->size = outcount;
2535 return (TRUE);
2538 bool_t
2539 xdr_FSSTAT3res(XDR *xdrs, FSSTAT3res *objp)
2541 FSSTAT3resok *resokp;
2543 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2544 return (FALSE);
2545 if (objp->status != NFS3_OK)
2546 return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
2548 /* xdr_FSSTAT3resok */
2549 resokp = &objp->resok;
2550 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
2551 return (FALSE);
2552 if (!xdr_u_longlong_t(xdrs, &resokp->tbytes))
2553 return (FALSE);
2554 if (!xdr_u_longlong_t(xdrs, &resokp->fbytes))
2555 return (FALSE);
2556 if (!xdr_u_longlong_t(xdrs, &resokp->abytes))
2557 return (FALSE);
2558 if (!xdr_u_longlong_t(xdrs, &resokp->tfiles))
2559 return (FALSE);
2560 if (!xdr_u_longlong_t(xdrs, &resokp->ffiles))
2561 return (FALSE);
2562 if (!xdr_u_longlong_t(xdrs, &resokp->afiles))
2563 return (FALSE);
2564 return (xdr_u_int(xdrs, &resokp->invarsec));
2567 bool_t
2568 xdr_FSINFO3res(XDR *xdrs, FSINFO3res *objp)
2570 FSINFO3resok *resokp;
2572 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2573 return (FALSE);
2574 if (objp->status != NFS3_OK) /* xdr_FSSTAT3resfail */
2575 return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
2577 /* xdr_FSINFO3resok */
2578 resokp = &objp->resok;
2579 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
2580 return (FALSE);
2581 if (!xdr_u_int(xdrs, &resokp->rtmax))
2582 return (FALSE);
2583 if (!xdr_u_int(xdrs, &resokp->rtpref))
2584 return (FALSE);
2585 if (!xdr_u_int(xdrs, &resokp->rtmult))
2586 return (FALSE);
2587 if (!xdr_u_int(xdrs, &resokp->wtmax))
2588 return (FALSE);
2589 if (!xdr_u_int(xdrs, &resokp->wtpref))
2590 return (FALSE);
2591 if (!xdr_u_int(xdrs, &resokp->wtmult))
2592 return (FALSE);
2593 if (!xdr_u_int(xdrs, &resokp->dtpref))
2594 return (FALSE);
2595 if (!xdr_u_longlong_t(xdrs, &resokp->maxfilesize))
2596 return (FALSE);
2597 if (!xdr_u_int(xdrs, &resokp->time_delta.seconds))
2598 return (FALSE);
2599 if (!xdr_u_int(xdrs, &resokp->time_delta.nseconds))
2600 return (FALSE);
2601 return (xdr_u_int(xdrs, &resokp->properties));
2604 bool_t
2605 xdr_PATHCONF3res(XDR *xdrs, PATHCONF3res *objp)
2607 PATHCONF3resok *resokp;
2609 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2610 return (FALSE);
2611 if (objp->status != NFS3_OK)
2612 return (xdr_post_op_attr(xdrs, &objp->resfail.obj_attributes));
2614 /* xdr_PATHCONF3resok */
2615 resokp = &objp->resok;
2616 if (!xdr_post_op_attr(xdrs, &resokp->obj_attributes))
2617 return (FALSE);
2618 if (!xdr_u_int(xdrs, &resokp->info.link_max))
2619 return (FALSE);
2620 if (!xdr_u_int(xdrs, &resokp->info.name_max))
2621 return (FALSE);
2622 if (!xdr_bool(xdrs, &resokp->info.no_trunc))
2623 return (FALSE);
2624 if (!xdr_bool(xdrs, &resokp->info.chown_restricted))
2625 return (FALSE);
2626 if (!xdr_bool(xdrs, &resokp->info.case_insensitive))
2627 return (FALSE);
2628 return (xdr_bool(xdrs, &resokp->info.case_preserving));
2631 bool_t
2632 xdr_COMMIT3args(XDR *xdrs, COMMIT3args *objp)
2634 if (xdrs->x_op == XDR_FREE)
2635 return (TRUE);
2637 switch (xdrs->x_op) {
2638 case XDR_FREE:
2639 case XDR_ENCODE:
2640 if (!xdr_nfs_fh3(xdrs, &objp->file))
2641 return (FALSE);
2642 break;
2643 case XDR_DECODE:
2644 if (!xdr_nfs_fh3_server(xdrs, &objp->file))
2645 return (FALSE);
2646 break;
2648 if (!xdr_u_longlong_t(xdrs, &objp->offset))
2649 return (FALSE);
2650 return (xdr_u_int(xdrs, &objp->count));
2653 bool_t
2654 xdr_COMMIT3res(XDR *xdrs, COMMIT3res *objp)
2656 COMMIT3resok *resokp;
2658 if (!xdr_enum(xdrs, (enum_t *)&objp->status))
2659 return (FALSE);
2660 if (objp->status != NFS3_OK)
2661 return (xdr_wcc_data(xdrs, &objp->resfail.file_wcc));
2663 /* xdr_COMMIT3resok */
2664 resokp = &objp->resok;
2665 if (!xdr_wcc_data(xdrs, &resokp->file_wcc))
2666 return (FALSE);
2668 * writeverf3 is really an opaque 8 byte
2669 * quantity, but we will treat it as a
2670 * hyper for efficiency, the cost of
2671 * a byteswap here saves bcopys elsewhere
2673 return (xdr_u_longlong_t(xdrs, &resokp->verf));