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