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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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