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