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