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