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