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