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