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]
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>
37 #include <sys/vnode.h>
39 #include <sys/dirent.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>
51 #include <rpc/types.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.
75 xdr_string3(XDR
*xdrs
, char **cpp
, uint_t maxsize
)
80 bool_t mem_alloced
= FALSE
;
83 * first deal with the length since xdr strings are counted-strings
88 if (sp
== NULL
|| sp
== nfs3nametoolong
)
89 return (TRUE
); /* already free */
93 size
= (uint_t
)strlen(sp
);
100 if (!xdr_u_int(xdrs
, &size
))
104 * now deal with the actual bytes
106 switch (xdrs
->x_op
) {
108 if (size
>= maxsize
) {
109 *cpp
= nfs3nametoolong
;
110 if (!XDR_CONTROL(xdrs
, XDR_SKIPBYTES
, &size
))
118 sp
= kmem_alloc(nodesize
, KM_NOSLEEP
);
126 if (xdr_opaque(xdrs
, sp
, size
)) {
127 if (strlen(sp
) != size
) {
129 kmem_free(sp
, nodesize
);
135 kmem_free(sp
, nodesize
);
142 return (xdr_opaque(xdrs
, sp
, size
));
146 kmem_free(sp
, nodesize
);
155 * XDR_INLINE decode a filehandle.
158 xdr_inline_decode_nfs_fh3(uint32_t *ptr
, nfs_fh3
*fhp
, uint32_t fhsize
)
160 uchar_t
*bp
= (uchar_t
*)ptr
;
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
)) {
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
191 cp
= (uchar_t
*)&fhp
->fh3_len
;
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.
207 bcopy(bp
, fhp
->fh3_data
, dsize
);
211 if (fhsize
< sizeof (ushort_t
))
213 cp
= (uchar_t
*)&fhp
->fh3_xlen
;
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.
225 bcopy(bp
, fhp
->fh3_xdata
, dsize
);
230 * We realign things on purpose, so skip any padding
232 resid
= (uintptr_t)bp
% BYTES_PER_XDR_UNIT
;
234 if (fhsize
< (BYTES_PER_XDR_UNIT
- resid
))
236 bp
+= BYTES_PER_XDR_UNIT
- resid
;
237 fhsize
-= BYTES_PER_XDR_UNIT
- resid
;
241 * Make sure client didn't send extra bytes
249 xdr_decode_nfs_fh3(XDR
*xdrs
, nfs_fh3
*objp
)
251 uint32_t fhsize
; /* filehandle size */
256 ASSERT(xdrs
->x_op
== XDR_DECODE
);
259 * Retrieve the filehandle length.
261 if (!XDR_GETINT32(xdrs
, (int32_t *)&fhsize
))
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
))
282 * bring in fhsize plus any padding
284 bufsize
= RNDUP(fhsize
);
285 ptr
= XDR_INLINE(xdrs
, bufsize
);
288 bp
= kmem_alloc(bufsize
, KM_SLEEP
);
289 if (!xdr_opaque(xdrs
, (char *)bp
, bufsize
)) {
290 kmem_free(bp
, bufsize
);
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;
309 kmem_free(bp
, bufsize
);
314 * XDR_INLINE encode a filehandle.
317 xdr_inline_encode_nfs_fh3(uint32_t **ptrp
, uint32_t *ptr_redzone
,
320 uint32_t *ptr
= *ptrp
;
322 uint_t otw_len
, fsize
, xsize
; /* otw, file, and export sizes */
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
)
348 * Zero out the pading.
352 IXDR_PUT_U_INT32(ptr
, otw_len
);
355 * The rest of the filehandle is in native byteorder
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.
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);
390 xdr_encode_nfs_fh3(XDR
*xdrs
, nfs_fh3
*objp
)
392 uint_t otw_len
, fsize
, xsize
; /* otw, file, and export sizes */
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
);
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
);
430 ret
= xdr_opaque(xdrs
, (char *)buf
, otw_len
);
431 kmem_free(buf
, otw_len
);
437 * XDR a NFSv3 filehandle the naive way.
440 xdr_nfs_fh3(XDR
*xdrs
, nfs_fh3
*objp
)
442 if (xdrs
->x_op
== XDR_FREE
)
445 if (!xdr_u_int(xdrs
, &objp
->fh3_length
))
448 if (objp
->fh3_length
> NFS3_FHSIZE
)
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.
460 xdr_nfs_fh3_server(XDR
*xdrs
, nfs_fh3
*objp
)
462 switch (xdrs
->x_op
) {
464 if (objp
->fh3_flags
& FH_WEBNFS
)
465 return (xdr_nfs_fh3(xdrs
, objp
));
467 return (xdr_encode_nfs_fh3(xdrs
, objp
));
469 return (xdr_decode_nfs_fh3(xdrs
, objp
));
471 if (objp
->fh3_u
.data
!= NULL
)
472 bzero(objp
->fh3_u
.data
, sizeof (objp
->fh3_u
.data
));
479 xdr_diropargs3(XDR
*xdrs
, diropargs3
*objp
)
481 switch (xdrs
->x_op
) {
484 if (!xdr_nfs_fh3(xdrs
, objp
->dirp
))
488 if (!xdr_nfs_fh3_server(xdrs
, &objp
->dir
))
492 return (xdr_string3(xdrs
, &objp
->name
, MAXNAMELEN
));
496 xdr_fattr3(XDR
*xdrs
, fattr3
*na
)
500 if (xdrs
->x_op
== XDR_FREE
)
503 ptr
= XDR_INLINE(xdrs
, NFS3_SIZEOF_FATTR3
* BYTES_PER_XDR_UNIT
);
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
);
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
);
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
)))
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
575 xdr_fattr3_to_vattr(XDR
*xdrs
, fattr3_res
*objp
)
581 vattr_t
*vap
= objp
->vap
;
586 ASSERT(xdrs
->x_op
== XDR_DECODE
);
588 /* On success, all attributes will be decoded */
589 vap
->va_mask
= AT_ALL
;
592 ptr
= XDR_INLINE(xdrs
, NFS3_SIZEOF_FATTR3
* BYTES_PER_XDR_UNIT
);
597 vap
->va_type
= IXDR_GET_ENUM(ptr
, enum vtype
);
598 if ((ftype3
)vap
->va_type
< NF3REG
||
599 (ftype3
)vap
->va_type
> NF3FIFO
)
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
;
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 */
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
);
641 * Check if the time would overflow on 32-bit
643 ntime
= IXDR_GET_U_INT32(ptr
);
645 if (NFS3_TIME_OVERFLOW(ntime
)) {
646 objp
->status
= EOVERFLOW
;
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
);
654 if (NFS3_TIME_OVERFLOW(ntime
)) {
655 objp
->status
= EOVERFLOW
;
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
);
663 if (NFS3_TIME_OVERFLOW(ntime
)) {
664 objp
->status
= EOVERFLOW
;
667 vap
->va_ctime
.tv_sec
= ntime
;
668 vap
->va_ctime
.tv_nsec
= IXDR_GET_U_INT32(ptr
);
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
)))
690 if (nfs_allow_preepoch_time
) {
691 if (!xdr_u_int(xdrs
, &ntime
))
693 vap
->va_atime
.tv_sec
= (int32_t)ntime
;
694 if (!xdr_u_int(xdrs
, &ntime
))
696 vap
->va_atime
.tv_nsec
= ntime
;
698 if (!xdr_u_int(xdrs
, &ntime
))
700 vap
->va_mtime
.tv_sec
= (int32_t)ntime
;
701 if (!xdr_u_int(xdrs
, &ntime
))
703 vap
->va_mtime
.tv_nsec
= ntime
;
705 if (!xdr_u_int(xdrs
, &ntime
))
707 vap
->va_ctime
.tv_sec
= (int32_t)ntime
;
708 if (!xdr_u_int(xdrs
, &ntime
))
710 vap
->va_ctime
.tv_nsec
= ntime
;
713 * Check if the time would overflow on 32-bit
714 * Set status and keep decoding stream.
716 if (!xdr_u_int(xdrs
, &ntime
))
719 if (NFS3_TIME_OVERFLOW(ntime
)) {
720 objp
->status
= EOVERFLOW
;
722 vap
->va_atime
.tv_sec
= ntime
;
723 if (!xdr_u_int(xdrs
, &ntime
))
725 vap
->va_atime
.tv_nsec
= ntime
;
727 if (!xdr_u_int(xdrs
, &ntime
))
730 if (NFS3_TIME_OVERFLOW(ntime
)) {
731 objp
->status
= EOVERFLOW
;
733 vap
->va_mtime
.tv_sec
= ntime
;
734 if (!xdr_u_int(xdrs
, &ntime
))
736 vap
->va_mtime
.tv_nsec
= ntime
;
738 if (!xdr_u_int(xdrs
, &ntime
))
741 if (NFS3_TIME_OVERFLOW(ntime
)) {
742 objp
->status
= EOVERFLOW
;
744 vap
->va_ctime
.tv_sec
= ntime
;
745 if (!xdr_u_int(xdrs
, &ntime
))
747 vap
->va_ctime
.tv_nsec
= ntime
;
753 if ((ftype3
)vap
->va_type
< NF3REG
||
754 (ftype3
)vap
->va_type
> NF3FIFO
)
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
;
773 * Fill in derived fields
775 vap
->va_fsid
= objp
->vp
->v_vfsp
->vfs_dev
;
782 vap
->va_blksize
= MAXBSIZE
;
785 switch (vap
->va_type
) {
789 vap
->va_nblocks
= (u_longlong_t
)
790 ((used
+ (size3
)DEV_BSIZE
- (size3
)1) /
794 vap
->va_blksize
= DEV_BSIZE
;
797 vap
->va_rdev
= makedevice(rdev
.specdata1
, rdev
.specdata2
);
809 xdr_post_op_vattr(XDR
*xdrs
, post_op_vattr
*objp
)
814 ASSERT(xdrs
->x_op
== XDR_DECODE
);
816 if (!xdr_bool(xdrs
, &objp
->attributes
))
819 if (objp
->attributes
== FALSE
)
822 if (objp
->attributes
!= TRUE
)
825 if (!xdr_fattr3_to_vattr(xdrs
, &objp
->fres
))
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
;
839 xdr_post_op_attr(XDR
*xdrs
, post_op_attr
*objp
)
841 if (!xdr_bool(xdrs
, &objp
->attributes
))
844 if (objp
->attributes
== FALSE
)
847 if (objp
->attributes
!= TRUE
)
850 if (!xdr_fattr3(xdrs
, &objp
->attr
))
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
;
866 if (!NFS3_FATTR_TIME_OK(&objp
->attr
))
867 objp
->attributes
= FALSE
;
874 xdr_wcc_data(XDR
*xdrs
, wcc_data
*objp
)
879 if (xdrs
->x_op
== XDR_FREE
)
882 if (xdrs
->x_op
== XDR_DECODE
) {
884 if (!xdr_bool(xdrs
, &objp
->before
.attributes
))
887 switch (objp
->before
.attributes
) {
889 attrp
= &objp
->before
.attr
;
890 ptr
= XDR_INLINE(xdrs
, 6 * BYTES_PER_XDR_UNIT
);
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
);
898 if (!xdr_u_longlong_t(xdrs
, &attrp
->size
))
900 if (!xdr_u_int(xdrs
, &attrp
->mtime
.seconds
))
902 if (!xdr_u_int(xdrs
, &attrp
->mtime
.nseconds
))
904 if (!xdr_u_int(xdrs
, &attrp
->ctime
.seconds
))
906 if (!xdr_u_int(xdrs
, &attrp
->ctime
.nseconds
))
912 * check time overflow.
914 if (!NFS3_TIME_OK(attrp
->mtime
.seconds
) ||
915 !NFS3_TIME_OK(attrp
->ctime
.seconds
))
916 objp
->before
.attributes
= FALSE
;
926 if (xdrs
->x_op
== XDR_ENCODE
) {
928 if (!xdr_bool(xdrs
, &objp
->before
.attributes
))
931 switch (objp
->before
.attributes
) {
933 attrp
= &objp
->before
.attr
;
935 ptr
= XDR_INLINE(xdrs
, 6 * BYTES_PER_XDR_UNIT
);
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
);
943 if (!xdr_u_longlong_t(xdrs
, &attrp
->size
))
945 if (!xdr_u_int(xdrs
, &attrp
->mtime
.seconds
))
947 if (!xdr_u_int(xdrs
, &attrp
->mtime
.nseconds
))
949 if (!xdr_u_int(xdrs
, &attrp
->ctime
.seconds
))
951 if (!xdr_u_int(xdrs
, &attrp
->ctime
.nseconds
))
961 return (xdr_post_op_attr(xdrs
, &objp
->after
));
965 xdr_post_op_fh3(XDR
*xdrs
, post_op_fh3
*objp
)
967 if (!xdr_bool(xdrs
, &objp
->handle_follows
))
969 switch (objp
->handle_follows
) {
971 switch (xdrs
->x_op
) {
973 if (!xdr_nfs_fh3_server(xdrs
, &objp
->handle
))
978 if (!xdr_nfs_fh3(xdrs
, &objp
->handle
))
991 xdr_sattr3(XDR
*xdrs
, sattr3
*objp
)
994 if (!xdr_bool(xdrs
, &objp
->mode
.set_it
))
996 if (objp
->mode
.set_it
)
997 if (!xdr_u_int(xdrs
, &objp
->mode
.mode
))
1000 if (!xdr_bool(xdrs
, &objp
->uid
.set_it
))
1002 if (objp
->uid
.set_it
)
1003 if (!xdr_u_int(xdrs
, &objp
->uid
.uid
))
1006 if (!xdr_bool(xdrs
, &objp
->gid
.set_it
))
1008 if (objp
->gid
.set_it
)
1009 if (!xdr_u_int(xdrs
, &objp
->gid
.gid
))
1013 if (!xdr_bool(xdrs
, &objp
->size
.set_it
))
1015 if (objp
->size
.set_it
)
1016 if (!xdr_u_longlong_t(xdrs
, &objp
->size
.size
))
1020 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->atime
.set_it
))
1022 if (objp
->atime
.set_it
== SET_TO_CLIENT_TIME
) {
1023 if (!xdr_u_int(xdrs
, &objp
->atime
.atime
.seconds
))
1025 if (!xdr_u_int(xdrs
, &objp
->atime
.atime
.nseconds
))
1030 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->mtime
.set_it
))
1032 if (objp
->mtime
.set_it
== SET_TO_CLIENT_TIME
) {
1033 if (!xdr_u_int(xdrs
, &objp
->mtime
.mtime
.seconds
))
1035 if (!xdr_u_int(xdrs
, &objp
->mtime
.mtime
.nseconds
))
1043 xdr_GETATTR3res(XDR
*xdrs
, GETATTR3res
*objp
)
1045 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1047 if (objp
->status
!= NFS3_OK
)
1049 /* xdr_GETATTR3resok */
1050 return (xdr_fattr3(xdrs
, &objp
->resok
.obj_attributes
));
1054 xdr_GETATTR3vres(XDR
*xdrs
, GETATTR3vres
*objp
)
1057 * DECODE or FREE only
1059 if (xdrs
->x_op
== XDR_FREE
)
1062 if (xdrs
->x_op
!= XDR_DECODE
)
1065 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1068 if (objp
->status
!= NFS3_OK
)
1071 return (xdr_fattr3_to_vattr(xdrs
, &objp
->fres
));
1076 xdr_SETATTR3args(XDR
*xdrs
, SETATTR3args
*objp
)
1078 switch (xdrs
->x_op
) {
1081 if (!xdr_nfs_fh3(xdrs
, &objp
->object
))
1085 if (!xdr_nfs_fh3_server(xdrs
, &objp
->object
))
1089 if (!xdr_sattr3(xdrs
, &objp
->new_attributes
))
1093 if (!xdr_bool(xdrs
, &objp
->guard
.check
))
1095 switch (objp
->guard
.check
) {
1097 if (!xdr_u_int(xdrs
, &objp
->guard
.obj_ctime
.seconds
))
1099 return (xdr_u_int(xdrs
, &objp
->guard
.obj_ctime
.nseconds
));
1108 xdr_SETATTR3res(XDR
*xdrs
, SETATTR3res
*objp
)
1110 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1112 switch (objp
->status
) {
1114 return (xdr_wcc_data(xdrs
, &objp
->resok
.obj_wcc
));
1116 return (xdr_wcc_data(xdrs
, &objp
->resfail
.obj_wcc
));
1121 xdr_LOOKUP3res(XDR
*xdrs
, LOOKUP3res
*objp
)
1123 LOOKUP3resok
*resokp
;
1125 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
) {
1135 if (!xdr_nfs_fh3_server(xdrs
, &resokp
->object
))
1140 if (!xdr_nfs_fh3(xdrs
, &resokp
->object
))
1144 if (!xdr_post_op_attr(xdrs
, &resokp
->obj_attributes
))
1146 return (xdr_post_op_attr(xdrs
, &resokp
->dir_attributes
));
1150 xdr_LOOKUP3vres(XDR
*xdrs
, LOOKUP3vres
*objp
)
1153 * DECODE or FREE only
1155 if (xdrs
->x_op
== XDR_FREE
)
1158 if (xdrs
->x_op
!= XDR_DECODE
)
1161 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1164 if (objp
->status
!= NFS3_OK
)
1165 return (xdr_post_op_vattr(xdrs
, &objp
->dir_attributes
));
1167 if (!xdr_nfs_fh3(xdrs
, &objp
->object
))
1169 if (!xdr_post_op_vattr(xdrs
, &objp
->obj_attributes
))
1171 return (xdr_post_op_vattr(xdrs
, &objp
->dir_attributes
));
1175 xdr_ACCESS3args(XDR
*xdrs
, ACCESS3args
*objp
)
1177 switch (xdrs
->x_op
) {
1180 if (!xdr_nfs_fh3(xdrs
, &objp
->object
))
1184 if (!xdr_nfs_fh3_server(xdrs
, &objp
->object
))
1188 return (xdr_u_int(xdrs
, &objp
->access
));
1193 xdr_ACCESS3res(XDR
*xdrs
, ACCESS3res
*objp
)
1195 ACCESS3resok
*resokp
;
1197 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
))
1206 return (xdr_u_int(xdrs
, &resokp
->access
));
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
))
1227 xdr_READLINK3res(XDR
*xdrs
, READLINK3res
*objp
)
1230 READLINK3resok
*resokp
;
1232 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
))
1242 return (xdr_string3(xdrs
, &resokp
->data
, MAXPATHLEN
));
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
) {
1255 if (!xdr_nfs_fh3(xdrs
, &objp
->file
))
1259 if (!xdr_nfs_fh3_server(xdrs
, &objp
->file
))
1263 if (!xdr_u_longlong_t(xdrs
, &objp
->offset
))
1265 if (!xdr_u_int(xdrs
, &objp
->count
))
1268 DTRACE_PROBE1(xdr__i__read3_buf_len
, int, objp
->count
);
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
)
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
;
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
;
1308 xdr_READ3res(XDR
*xdrs
, READ3res
*objp
)
1314 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
) {
1328 if (xdrs
->x_op
== XDR_ENCODE
) {
1330 mp
= resokp
->data
.mp
;
1332 if (xdrs
->x_ops
== &xdrmblk_ops
) {
1333 if (xdrmblk_putmblk(xdrs
, mp
, resokp
->count
)) {
1334 resokp
->data
.mp
= NULL
;
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
1356 if (pullupmsg(mp
, -1) == 0)
1358 resokp
->data
.data_val
= (caddr_t
)mp
->b_rptr
;
1361 if (xdr_u_int(xdrs
, &resokp
->count
) == 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
,
1380 * Fall thru for the xdr_bytes()
1382 * note: the mblk will be freed in
1387 /* no RDMA_WRITE transfer -- send data inline */
1389 ret
= xdr_bytes(xdrs
, (char **)&resokp
->data
.data_val
,
1390 &resokp
->data
.data_len
, nfs3tsize());
1396 xdr_READ3vres(XDR
*xdrs
, READ3vres
*objp
)
1400 * DECODE or FREE only
1402 if (xdrs
->x_op
== XDR_FREE
)
1405 if (xdrs
->x_op
!= XDR_DECODE
)
1408 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1411 if (!xdr_post_op_vattr(xdrs
, &objp
->pov
))
1414 if (objp
->status
!= NFS3_OK
)
1417 if (!xdr_u_int(xdrs
, &objp
->count
))
1420 if (!xdr_bool(xdrs
, &objp
->eof
))
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
) {
1430 XDR_CONTROL(xdrs
, XDR_RDMA_GET_WLIST
, &cl
);
1433 if (!xdr_u_int(xdrs
, &ocount
)) {
1436 if (ocount
!= objp
->count
) {
1437 DTRACE_PROBE2(xdr__e__read3vres_fail
,
1438 int, ocount
, int, objp
->count
);
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
)) {
1449 xdr__e__read3vres_fail
,
1451 int, objp
->data
.data_len
);
1459 return (xdr_bytes(xdrs
, (char **)&objp
->data
.data_val
,
1460 &objp
->data
.data_len
, nfs3tsize()));
1464 xdr_READ3uiores(XDR
*xdrs
, READ3uiores
*objp
)
1471 int size
= (int)objp
->size
;
1472 struct uio
*uiop
= objp
->uiop
;
1473 int32_t fattr3_len
= NFS3_SIZEOF_FATTR3
* BYTES_PER_XDR_UNIT
;
1477 * DECODE or FREE only
1479 if (xdrs
->x_op
== XDR_FREE
)
1482 if (xdrs
->x_op
!= XDR_DECODE
)
1485 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->status
))
1488 if (!XDR_GETINT32(xdrs
, (int32_t *)&attributes
))
1492 * For directio we just skip over attributes if present
1494 switch (attributes
) {
1496 if (!XDR_CONTROL(xdrs
, XDR_SKIPBYTES
, &fattr3_len
))
1505 if (objp
->status
!= NFS3_OK
)
1508 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->count
))
1511 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->eof
))
1514 if (xdrs
->x_ops
== &xdrmblk_ops
) {
1515 if (!xdrmblk_getmblk(xdrs
, &mp
, &objp
->size
))
1518 if (objp
->size
== 0)
1521 if (objp
->size
> size
)
1524 size
= (int)objp
->size
;
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
,
1537 while (mp
&& (mp
->b_rptr
>= mp
->b_wptr
))
1539 } while (mp
&& size
> 0 && uiop
->uio_resid
> 0);
1544 if (xdrs
->x_ops
== &xdrrdma_ops
) {
1547 XDR_CONTROL(xdrs
, XDR_RDMA_GET_WLIST
, &cl
);
1552 if (!xdr_u_int(xdrs
, &ocount
)) {
1557 if (ocount
!= objp
->count
) {
1558 DTRACE_PROBE2(xdr__e__read3uiores_fail
,
1559 int, ocount
, int, objp
->count
);
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
;
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
))
1588 if (objp
->size
== 0)
1591 if (objp
->size
> size
)
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
)
1604 if (!XDR_GETBYTES(xdrs
, (caddr_t
)ptr
, size
)) {
1605 kmem_free(ptr
, size
);
1608 error
= uiomove(ptr
, size
, UIO_READ
, uiop
);
1609 kmem_free(ptr
, size
);
1611 return (error
? FALSE
: TRUE
);
1615 xdr_WRITE3args(XDR
*xdrs
, WRITE3args
*objp
)
1617 switch (xdrs
->x_op
) {
1620 if (!xdr_nfs_fh3(xdrs
, &objp
->file
))
1624 if (!xdr_nfs_fh3_server(xdrs
, &objp
->file
))
1628 if (!xdr_u_longlong_t(xdrs
, &objp
->offset
))
1630 if (!xdr_u_int(xdrs
, &objp
->count
))
1632 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->stable
))
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
;
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(
1653 objp
->count
) == FALSE
) {
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
);
1668 objp
->data
.data_val
= NULL
;
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()));
1681 xdr_WRITE3res(XDR
*xdrs
, WRITE3res
*objp
)
1683 WRITE3resok
*resokp
;
1685 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
))
1694 if (!xdr_u_int(xdrs
, &resokp
->count
))
1696 if (!xdr_enum(xdrs
, (enum_t
*)&resokp
->committed
))
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
));
1708 xdr_CREATE3args(XDR
*xdrs
, CREATE3args
*objp
)
1712 if (!xdr_diropargs3(xdrs
, &objp
->where
))
1715 /* xdr_createhow3 */
1718 if (!xdr_enum(xdrs
, (enum_t
*)&howp
->mode
))
1720 switch (howp
->mode
) {
1723 return (xdr_sattr3(xdrs
, &howp
->createhow3_u
.obj_attributes
));
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
));
1738 xdr_CREATE3res(XDR
*xdrs
, CREATE3res
*objp
)
1740 CREATE3resok
*resokp
;
1742 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1744 switch (objp
->status
) {
1746 /* xdr_CREATE3resok */
1747 resokp
= &objp
->resok
;
1749 if (!xdr_post_op_fh3(xdrs
, &resokp
->obj
))
1751 if (!xdr_post_op_attr(xdrs
, &resokp
->obj_attributes
))
1753 return (xdr_wcc_data(xdrs
, &resokp
->dir_wcc
));
1755 /* xdr_CREATE3resfail */
1756 return (xdr_wcc_data(xdrs
, &objp
->resfail
.dir_wcc
));
1761 xdr_MKDIR3args(XDR
*xdrs
, MKDIR3args
*objp
)
1763 if (!xdr_diropargs3(xdrs
, &objp
->where
))
1765 return (xdr_sattr3(xdrs
, &objp
->attributes
));
1769 xdr_MKDIR3res(XDR
*xdrs
, MKDIR3res
*objp
)
1771 MKDIR3resok
*resokp
;
1773 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1775 switch (objp
->status
) {
1777 /* xdr_MKDIR3resok */
1778 resokp
= &objp
->resok
;
1780 if (!xdr_post_op_fh3(xdrs
, &resokp
->obj
))
1782 if (!xdr_post_op_attr(xdrs
, &resokp
->obj_attributes
))
1784 return (xdr_wcc_data(xdrs
, &resokp
->dir_wcc
));
1786 return (xdr_wcc_data(xdrs
, &objp
->resfail
.dir_wcc
));
1791 xdr_SYMLINK3args(XDR
*xdrs
, SYMLINK3args
*objp
)
1793 if (!xdr_diropargs3(xdrs
, &objp
->where
))
1795 if (!xdr_sattr3(xdrs
, &objp
->symlink
.symlink_attributes
))
1797 return (xdr_string3(xdrs
, &objp
->symlink
.symlink_data
, MAXPATHLEN
));
1801 xdr_SYMLINK3res(XDR
*xdrs
, SYMLINK3res
*objp
)
1803 SYMLINK3resok
*resokp
;
1805 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1807 switch (objp
->status
) {
1809 resokp
= &objp
->resok
;
1810 /* xdr_SYMLINK3resok */
1811 if (!xdr_post_op_fh3(xdrs
, &resokp
->obj
))
1813 if (!xdr_post_op_attr(xdrs
, &resokp
->obj_attributes
))
1815 return (xdr_wcc_data(xdrs
, &resokp
->dir_wcc
));
1817 return (xdr_wcc_data(xdrs
, &objp
->resfail
.dir_wcc
));
1822 xdr_MKNOD3args(XDR
*xdrs
, MKNOD3args
*objp
)
1825 devicedata3
*nod_objp
;
1827 if (!xdr_diropargs3(xdrs
, &objp
->where
))
1830 whatp
= &objp
->what
;
1831 if (!xdr_enum(xdrs
, (enum_t
*)&whatp
->type
))
1833 switch (whatp
->type
) {
1836 /* xdr_devicedata3 */
1837 nod_objp
= &whatp
->mknoddata3_u
.device
;
1838 if (!xdr_sattr3(xdrs
, &nod_objp
->dev_attributes
))
1840 if (!xdr_u_int(xdrs
, &nod_objp
->spec
.specdata1
))
1842 return (xdr_u_int(xdrs
, &nod_objp
->spec
.specdata2
));
1845 return (xdr_sattr3(xdrs
, &whatp
->mknoddata3_u
.pipe_attributes
));
1853 xdr_MKNOD3res(XDR
*xdrs
, MKNOD3res
*objp
)
1855 MKNOD3resok
*resokp
;
1857 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1859 switch (objp
->status
) {
1861 /* xdr_MKNOD3resok */
1862 resokp
= &objp
->resok
;
1863 if (!xdr_post_op_fh3(xdrs
, &resokp
->obj
))
1865 if (!xdr_post_op_attr(xdrs
, &resokp
->obj_attributes
))
1867 return (xdr_wcc_data(xdrs
, &resokp
->dir_wcc
));
1869 return (xdr_wcc_data(xdrs
, &objp
->resfail
.dir_wcc
));
1874 xdr_REMOVE3res(XDR
*xdrs
, REMOVE3res
*objp
)
1876 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1878 switch (objp
->status
) {
1880 return (xdr_wcc_data(xdrs
, &objp
->resok
.dir_wcc
));
1882 return (xdr_wcc_data(xdrs
, &objp
->resfail
.dir_wcc
));
1887 xdr_RMDIR3res(XDR
*xdrs
, RMDIR3res
*objp
)
1889 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1891 switch (objp
->status
) {
1893 return (xdr_wcc_data(xdrs
, &objp
->resok
.dir_wcc
));
1895 return (xdr_wcc_data(xdrs
, &objp
->resfail
.dir_wcc
));
1900 xdr_RENAME3args(XDR
*xdrs
, RENAME3args
*objp
)
1902 if (!xdr_diropargs3(xdrs
, &objp
->from
))
1904 return (xdr_diropargs3(xdrs
, &objp
->to
));
1908 xdr_RENAME3res(XDR
*xdrs
, RENAME3res
*objp
)
1910 RENAME3resok
*resokp
;
1911 RENAME3resfail
*resfailp
;
1913 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1915 switch (objp
->status
) {
1917 /* xdr_RENAME3resok */
1918 resokp
= &objp
->resok
;
1920 if (!xdr_wcc_data(xdrs
, &resokp
->fromdir_wcc
))
1922 return (xdr_wcc_data(xdrs
, &resokp
->todir_wcc
));
1924 /* xdr_RENAME3resfail */
1925 resfailp
= &objp
->resfail
;
1926 if (!xdr_wcc_data(xdrs
, &resfailp
->fromdir_wcc
))
1928 return (xdr_wcc_data(xdrs
, &resfailp
->todir_wcc
));
1933 xdr_LINK3args(XDR
*xdrs
, LINK3args
*objp
)
1935 switch (xdrs
->x_op
) {
1938 if (!xdr_nfs_fh3(xdrs
, &objp
->file
))
1942 if (!xdr_nfs_fh3_server(xdrs
, &objp
->file
))
1946 return (xdr_diropargs3(xdrs
, &objp
->link
));
1950 xdr_LINK3res(XDR
*xdrs
, LINK3res
*objp
)
1953 LINK3resfail
*resfailp
;
1955 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
1957 switch (objp
->status
) {
1959 /* xdr_LINK3resok */
1960 resokp
= &objp
->resok
;
1961 if (!xdr_post_op_attr(xdrs
, &resokp
->file_attributes
))
1963 return (xdr_wcc_data(xdrs
, &resokp
->linkdir_wcc
));
1965 /* xdr_LINK3resfail */
1966 resfailp
= &objp
->resfail
;
1967 if (!xdr_post_op_attr(xdrs
, &resfailp
->file_attributes
))
1969 return (xdr_wcc_data(xdrs
, &resfailp
->linkdir_wcc
));
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
)
1982 switch (xdrs
->x_op
) {
1985 if (!xdr_nfs_fh3(xdrs
, &objp
->dir
))
1989 if (!xdr_nfs_fh3_server(xdrs
, &objp
->dir
))
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
))
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
))
2010 return (xdr_u_int(xdrs
, &objp
->count
));
2016 #define nextdp(dp) ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
2020 #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
2026 xdr_putdirlist(XDR
*xdrs
, READDIR3resok
*objp
)
2028 struct dirent64
*dp
;
2034 bool_t
false = FALSE
;
2040 if (xdrs
->x_op
!= XDR_ENCODE
)
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
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 dirent64
*)objp
->reply
.entries
;
2060 size
-= dp
->d_reclen
, dp
= nextdp(dp
)) {
2061 if (dp
->d_reclen
== 0)
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
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
;
2094 fileid
= (fileid3
)(dp
->d_ino
);
2095 cookie
= (cookie3
)(dp
->d_off
);
2096 if (!xdr_bool(xdrs
, &true) ||
2097 !xdr_u_longlong_t(xdrs
, &fileid
) ||
2098 !xdr_bytes(xdrs
, &name
, &namlen
, ~0) ||
2099 !xdr_u_longlong_t(xdrs
, &cookie
)) {
2104 if (!xdr_bool(xdrs
, &false))
2106 if (!xdr_bool(xdrs
, &objp
->reply
.eof
))
2112 xdr_READDIR3res(XDR
*xdrs
, READDIR3res
*objp
)
2114 READDIR3resok
*resokp
;
2117 * ENCODE or FREE only
2119 if (xdrs
->x_op
== XDR_DECODE
)
2122 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
))
2131 if (xdrs
->x_op
!= XDR_ENCODE
)
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
))
2141 return (xdr_putdirlist(xdrs
, resokp
));
2145 xdr_READDIR3vres(XDR
*xdrs
, READDIR3vres
*objp
)
2148 uint_t entries_size
;
2152 * DECODE or FREE only
2154 if (xdrs
->x_op
== XDR_FREE
)
2157 if (xdrs
->x_op
!= XDR_DECODE
)
2160 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
2163 if (!xdr_post_op_vattr(xdrs
, &objp
->dir_attributes
))
2166 if (objp
->status
!= NFS3_OK
)
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
))
2178 entries_size
= objp
->entries_size
;
2187 if (!XDR_GETINT32(xdrs
, (int32_t *)&valid
))
2191 * We have run out of entries, decode eof.
2193 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->eof
))
2202 if (!xdr_u_longlong_t(xdrs
, (u_longlong_t
*)&fileid
))
2208 if (!XDR_GETINT32(xdrs
, (int32_t *)&namlen
))
2210 this_reclen
= DIRENT64_RECLEN(namlen
);
2213 * If this will overflow buffer, stop decoding
2215 if ((outcount
+ this_reclen
) > entries_size
) {
2219 dp
->d_reclen
= this_reclen
;
2222 if (!xdr_opaque(xdrs
, dp
->d_name
, namlen
))
2224 bzero(&dp
->d_name
[namlen
],
2225 DIRENT64_NAMELEN(this_reclen
) - namlen
);
2230 if (!xdr_u_longlong_t(xdrs
, (u_longlong_t
*)&dp
->d_off
))
2232 objp
->loff
= dp
->d_off
;
2234 outcount
+= this_reclen
;
2235 dp
= (dirent64_t
*)((intptr_t)dp
+ this_reclen
);
2238 objp
->size
= outcount
;
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
)
2251 switch (xdrs
->x_op
) {
2254 if (!xdr_nfs_fh3(xdrs
, &objp
->dir
))
2258 if (!xdr_nfs_fh3_server(xdrs
, &objp
->dir
))
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
))
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
))
2279 if (!xdr_u_int(xdrs
, &objp
->dircount
))
2281 return (xdr_u_int(xdrs
, &objp
->maxcount
));
2288 xdr_putdirpluslist(XDR
*xdrs
, READDIRPLUS3resok
*objp
)
2290 struct dirent64
*dp
;
2294 bool_t
false = FALSE
;
2297 entryplus3_info
*infop
;
2299 if (xdrs
->x_op
!= XDR_ENCODE
)
2302 dp
= (struct dirent64
*)objp
->reply
.entries
;
2304 infop
= objp
->infop
;
2307 if (dp
->d_reclen
== 0)
2309 if (dp
->d_ino
!= 0) {
2311 fileid
= (fileid3
)(dp
->d_ino
);
2312 cookie
= (cookie3
)(dp
->d_off
);
2313 if (!xdr_bool(xdrs
, &true) ||
2314 !xdr_u_longlong_t(xdrs
, &fileid
) ||
2315 !xdr_bytes(xdrs
, &name
, &infop
->namelen
, ~0) ||
2316 !xdr_u_longlong_t(xdrs
, &cookie
) ||
2317 !xdr_post_op_attr(xdrs
, &infop
->attr
) ||
2318 !xdr_post_op_fh3(xdrs
, &infop
->fh
)) {
2327 if (!xdr_bool(xdrs
, &false))
2329 if (!xdr_bool(xdrs
, &objp
->reply
.eof
))
2335 xdr_READDIRPLUS3res(XDR
*xdrs
, READDIRPLUS3res
*objp
)
2337 READDIRPLUS3resok
*resokp
;
2340 * ENCODE or FREE only
2342 if (xdrs
->x_op
== XDR_DECODE
)
2345 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
2347 switch (objp
->status
) {
2349 /* xdr_READDIRPLUS3resok */
2350 resokp
= &objp
->resok
;
2351 if (!xdr_post_op_attr(xdrs
, &resokp
->dir_attributes
))
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
))
2361 if (xdrs
->x_op
== XDR_ENCODE
) {
2362 if (!xdr_putdirpluslist(xdrs
, resokp
))
2367 return (xdr_post_op_attr(xdrs
, &objp
->resfail
.dir_attributes
));
2373 * Decode readdirplus directly into a dirent64_t and do the DNLC caching.
2376 xdr_READDIRPLUS3vres(XDR
*xdrs
, READDIRPLUS3vres
*objp
)
2380 uint_t entries_size
;
2388 * DECODE or FREE only
2390 if (xdrs
->x_op
== XDR_FREE
)
2393 if (xdrs
->x_op
!= XDR_DECODE
)
2396 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->status
))
2399 if (!xdr_post_op_vattr(xdrs
, &objp
->dir_attributes
))
2402 if (objp
->status
!= NFS3_OK
)
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
))
2414 dvp
= objp
->dir_attributes
.fres
.vp
;
2420 entries_size
= objp
->entries_size
;
2432 if (!XDR_GETINT32(xdrs
, (int32_t *)&valid
))
2436 * We have run out of entries, decode eof.
2438 if (!XDR_GETINT32(xdrs
, (int32_t *)&objp
->eof
))
2447 if (!xdr_u_longlong_t(xdrs
, (u_longlong_t
*)&fileid
))
2453 if (!XDR_GETINT32(xdrs
, (int32_t *)&namlen
))
2455 this_reclen
= DIRENT64_RECLEN(namlen
);
2458 * If this will overflow buffer, stop decoding
2460 if ((outcount
+ this_reclen
) > entries_size
) {
2464 dp
->d_reclen
= this_reclen
;
2467 if (!xdr_opaque(xdrs
, dp
->d_name
, namlen
))
2469 bzero(&dp
->d_name
[namlen
],
2470 DIRENT64_NAMELEN(this_reclen
) - namlen
);
2475 if (!xdr_u_longlong_t(xdrs
, (u_longlong_t
*)&dp
->d_off
))
2477 objp
->loff
= dp
->d_off
;
2480 * post_op_attr name_attributes
2482 if (!xdr_post_op_vattr(xdrs
, &pov
))
2485 if (pov
.attributes
== TRUE
&&
2486 pov
.fres
.status
== NFS3_OK
)
2492 * post_op_fh3 name_handle
2494 if (!XDR_GETINT32(xdrs
, (int32_t *)&fh_valid
))
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
2504 if (fh_valid
== TRUE
) {
2505 if (!xdr_nfs_fh3(xdrs
, &fh
))
2508 if (fh_valid
!= 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
);
2530 outcount
+= this_reclen
;
2531 dp
= (dirent64_t
*)((intptr_t)dp
+ this_reclen
);
2534 objp
->size
= outcount
;
2539 xdr_FSSTAT3res(XDR
*xdrs
, FSSTAT3res
*objp
)
2541 FSSTAT3resok
*resokp
;
2543 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
))
2552 if (!xdr_u_longlong_t(xdrs
, &resokp
->tbytes
))
2554 if (!xdr_u_longlong_t(xdrs
, &resokp
->fbytes
))
2556 if (!xdr_u_longlong_t(xdrs
, &resokp
->abytes
))
2558 if (!xdr_u_longlong_t(xdrs
, &resokp
->tfiles
))
2560 if (!xdr_u_longlong_t(xdrs
, &resokp
->ffiles
))
2562 if (!xdr_u_longlong_t(xdrs
, &resokp
->afiles
))
2564 return (xdr_u_int(xdrs
, &resokp
->invarsec
));
2568 xdr_FSINFO3res(XDR
*xdrs
, FSINFO3res
*objp
)
2570 FSINFO3resok
*resokp
;
2572 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
))
2581 if (!xdr_u_int(xdrs
, &resokp
->rtmax
))
2583 if (!xdr_u_int(xdrs
, &resokp
->rtpref
))
2585 if (!xdr_u_int(xdrs
, &resokp
->rtmult
))
2587 if (!xdr_u_int(xdrs
, &resokp
->wtmax
))
2589 if (!xdr_u_int(xdrs
, &resokp
->wtpref
))
2591 if (!xdr_u_int(xdrs
, &resokp
->wtmult
))
2593 if (!xdr_u_int(xdrs
, &resokp
->dtpref
))
2595 if (!xdr_u_longlong_t(xdrs
, &resokp
->maxfilesize
))
2597 if (!xdr_u_int(xdrs
, &resokp
->time_delta
.seconds
))
2599 if (!xdr_u_int(xdrs
, &resokp
->time_delta
.nseconds
))
2601 return (xdr_u_int(xdrs
, &resokp
->properties
));
2605 xdr_PATHCONF3res(XDR
*xdrs
, PATHCONF3res
*objp
)
2607 PATHCONF3resok
*resokp
;
2609 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
))
2618 if (!xdr_u_int(xdrs
, &resokp
->info
.link_max
))
2620 if (!xdr_u_int(xdrs
, &resokp
->info
.name_max
))
2622 if (!xdr_bool(xdrs
, &resokp
->info
.no_trunc
))
2624 if (!xdr_bool(xdrs
, &resokp
->info
.chown_restricted
))
2626 if (!xdr_bool(xdrs
, &resokp
->info
.case_insensitive
))
2628 return (xdr_bool(xdrs
, &resokp
->info
.case_preserving
));
2632 xdr_COMMIT3args(XDR
*xdrs
, COMMIT3args
*objp
)
2634 if (xdrs
->x_op
== XDR_FREE
)
2637 switch (xdrs
->x_op
) {
2640 if (!xdr_nfs_fh3(xdrs
, &objp
->file
))
2644 if (!xdr_nfs_fh3_server(xdrs
, &objp
->file
))
2648 if (!xdr_u_longlong_t(xdrs
, &objp
->offset
))
2650 return (xdr_u_int(xdrs
, &objp
->count
));
2654 xdr_COMMIT3res(XDR
*xdrs
, COMMIT3res
*objp
)
2656 COMMIT3resok
*resokp
;
2658 if (!xdr_enum(xdrs
, (enum_t
*)&objp
->status
))
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
))
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
));