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