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