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