1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/time.h> 27 #include <sys/systm.h> 28 29 #include <nfs/nfs.h> 30 #include <nfs/nfs4.h> 31 #include <nfs/rnode4.h> 32 #include <nfs/nfs4_clnt.h> 33 #include <sys/cmn_err.h> 34 35 static int 36 timestruc_to_settime4(timestruc_t *tt, settime4 *tt4, int flags) 37 { 38 int error = 0; 39 40 if (flags & ATTR_UTIME) { 41 tt4->set_it = SET_TO_CLIENT_TIME4; 42 error = nfs4_time_vton(tt, &tt4->time); 43 } else { 44 tt4->set_it = SET_TO_SERVER_TIME4; 45 } 46 return (error); 47 } 48 49 50 /* 51 * nfs4_ver_fattr4_attr translates a vattr attribute into a fattr4 attribute 52 * for use by nfsv4 verify. For setting atime or mtime use the entry for 53 * time_XX (XX == access or modify). 54 * Return TRUE if arg was set (even if there was an error) and FALSE 55 * otherwise. Also set error code. The caller should not continue 56 * if error was set, whether or not the return is TRUE or FALSE. Returning 57 * FALSE does not mean there was an error, only that the attr was not set. 58 * 59 * Note: For now we only have the options used by setattr. In the future 60 * the switch statement below should cover all vattr attrs and possibly 61 * sys attrs as well. 62 */ 63 /* ARGSUSED */ 64 static bool_t 65 nfs4_ver_fattr4_attr(vattr_t *vap, struct nfs4_ntov_map *ntovp, 66 union nfs4_attr_u *nap, int flags, int *errorp) 67 { 68 bool_t retval = TRUE; 69 70 /* 71 * Special case for time set: if setting the 72 * time, ignore entry for time access/modify set (setattr) 73 * and instead use that of time access/modify. 74 */ 75 *errorp = 0; 76 /* 77 * Bit matches the mask 78 */ 79 switch (ntovp->vbit & vap->va_mask) { 80 case AT_SIZE: 81 nap->size = vap->va_size; 82 break; 83 case AT_MODE: 84 nap->mode = vap->va_mode; 85 break; 86 case AT_UID: 87 /* 88 * if no mapping, uid could be mapped to a numeric string, 89 * e.g. 12345->"12345" 90 */ 91 if (*errorp = nfs_idmap_uid_str(vap->va_uid, &nap->owner, 92 FALSE)) 93 retval = FALSE; 94 break; 95 case AT_GID: 96 /* 97 * if no mapping, gid will be mapped to a number string, 98 * e.g. "12345" 99 */ 100 if (*errorp = nfs_idmap_gid_str(vap->va_gid, &nap->owner_group, 101 FALSE)) 102 retval = FALSE; 103 break; 104 case AT_ATIME: 105 if ((ntovp->nval != FATTR4_TIME_ACCESS) || 106 (*errorp = nfs4_time_vton(&vap->va_ctime, 107 &nap->time_access))) { 108 /* 109 * either asked for FATTR4_TIME_ACCESS_SET - 110 * not used for setattr 111 * or system time invalid for otw transfers 112 */ 113 retval = FALSE; 114 } 115 break; 116 case AT_MTIME: 117 if ((ntovp->nval != FATTR4_TIME_MODIFY) || 118 (*errorp = nfs4_time_vton(&vap->va_mtime, 119 &nap->time_modify))) { 120 /* 121 * either asked for FATTR4_TIME_MODIFY_SET - 122 * not used for setattr 123 * or system time invalid for otw transfers 124 */ 125 retval = FALSE; 126 } 127 break; 128 case AT_CTIME: 129 if (*errorp = nfs4_time_vton(&vap->va_ctime, 130 &nap->time_metadata)) { 131 /* 132 * system time invalid for otw transfers 133 */ 134 retval = FALSE; 135 } 136 break; 137 default: 138 retval = FALSE; 139 } 140 return (retval); 141 } 142 143 /* 144 * nfs4_set_fattr4_attr translates a vattr attribute into a fattr4 attribute 145 * for use by nfs4_setattr. For setting atime or mtime use the entry for 146 * time_XX_set rather than time_XX (XX == access or modify). 147 * Return TRUE if arg was set (even if there was an error) and FALSE 148 * otherwise. Also set error code. The caller should not continue 149 * if error was set, whether or not the return is TRUE or FALSE. Returning 150 * FALSE does not mean there was an error, only that the attr was not set. 151 */ 152 static bool_t 153 nfs4_set_fattr4_attr(vattr_t *vap, vsecattr_t *vsap, 154 struct nfs4_ntov_map *ntovp, union nfs4_attr_u *nap, int flags, 155 int *errorp) 156 { 157 bool_t retval = TRUE; 158 159 /* 160 * Special case for time set: if setting the 161 * time, ignore entry for time access/modify 162 * and instead use that of time access/modify set. 163 */ 164 *errorp = 0; 165 /* 166 * Bit matches the mask 167 */ 168 switch (ntovp->vbit & vap->va_mask) { 169 case AT_SIZE: 170 nap->size = vap->va_size; 171 break; 172 case AT_MODE: 173 nap->mode = vap->va_mode; 174 break; 175 case AT_UID: 176 /* 177 * if no mapping, uid will be mapped to a number string, 178 * e.g. "12345" 179 */ 180 if (*errorp = nfs_idmap_uid_str(vap->va_uid, &nap->owner, 181 FALSE)) 182 retval = FALSE; 183 break; 184 case AT_GID: 185 /* 186 * if no mapping, gid will be mapped to a number string, 187 * e.g. "12345" 188 */ 189 if (*errorp = nfs_idmap_gid_str(vap->va_gid, &nap->owner_group, 190 FALSE)) 191 retval = FALSE; 192 break; 193 case AT_ATIME: 194 if ((ntovp->nval != FATTR4_TIME_ACCESS_SET) || 195 (*errorp = timestruc_to_settime4(&vap->va_atime, 196 &nap->time_access_set, flags))) { 197 /* FATTR4_TIME_ACCESS - not used for verify */ 198 retval = FALSE; 199 } 200 break; 201 case AT_MTIME: 202 if ((ntovp->nval != FATTR4_TIME_MODIFY_SET) || 203 (*errorp = timestruc_to_settime4(&vap->va_mtime, 204 &nap->time_modify_set, flags))) { 205 /* FATTR4_TIME_MODIFY - not used for verify */ 206 retval = FALSE; 207 } 208 break; 209 default: 210 /* 211 * If the ntovp->vbit == 0 this is most likely the ACL. 212 */ 213 if (ntovp->vbit == 0 && ntovp->fbit == FATTR4_ACL_MASK) { 214 ASSERT(vsap->vsa_mask == (VSA_ACE | VSA_ACECNT)); 215 nap->acl.fattr4_acl_len = vsap->vsa_aclcnt; 216 nap->acl.fattr4_acl_val = vsap->vsa_aclentp; 217 } else 218 retval = FALSE; 219 } 220 221 return (retval); 222 } 223 224 /* 225 * XXX - This is a shorter version of vattr_to_fattr4 which only takes care 226 * of setattr args - size, mode, uid/gid, times. Eventually we should generalize 227 * by using nfs4_ntov_map and the same functions used by the server. 228 * Here we just hardcoded the setattr attributes. Note that the order is 229 * important - it should follow the order of the bits in the mask. 230 */ 231 int 232 vattr_to_fattr4(vattr_t *vap, vsecattr_t *vsap, fattr4 *fattrp, int flags, 233 enum nfs_opnum4 op, bitmap4 supp) 234 { 235 int i, j; 236 union nfs4_attr_u *na = NULL; 237 int attrcnt; 238 int uid_attr = -1; 239 int gid_attr = -1; 240 int acl_attr = -1; 241 XDR xdr; 242 ulong_t xdr_size; 243 char *xdr_attrs; 244 int error = 0; 245 uint8_t amap[NFS4_MAXNUM_ATTRS]; 246 uint_t va_mask = vap->va_mask; 247 bool_t (*attrfunc)(); 248 249 #ifndef lint 250 /* 251 * Make sure that maximum attribute number can be expressed as an 252 * 8 bit quantity. 253 */ 254 ASSERT(NFS4_MAXNUM_ATTRS <= (UINT8_MAX + 1)); 255 #endif 256 fattrp->attrmask = 0; 257 fattrp->attrlist4_len = 0; 258 fattrp->attrlist4 = NULL; 259 na = kmem_zalloc(sizeof (union nfs4_attr_u) * nfs4_ntov_map_size, 260 KM_SLEEP); 261 262 if (op == OP_SETATTR || op == OP_CREATE || op == OP_OPEN) { 263 /* 264 * Note we need to set the attrmask for set operations. 265 * In particular mtime and atime will be set to the 266 * servers time. 267 */ 268 nfs4_vmask_to_nmask_set(va_mask, &fattrp->attrmask); 269 if (vsap != NULL) 270 fattrp->attrmask |= FATTR4_ACL_MASK; 271 attrfunc = nfs4_set_fattr4_attr; 272 } else { /* verify/nverify */ 273 /* 274 * Verfy/nverify use the "normal vmask_to_nmask 275 * this routine knows how to handle all vmask bits 276 */ 277 nfs4_vmask_to_nmask(va_mask, &fattrp->attrmask); 278 /* 279 * XXX verify/nverify only works for a subset of attrs that 280 * directly map to vattr_t attrs. So, verify/nverify is 281 * broken for servers that only support mandatory attrs. 282 * Mask out change attr for now and fix verify op to 283 * work with mandonly servers later. nfs4_vmask_to_nmask 284 * sets change whenever it sees request for ctime/mtime, 285 * so we must turn off change because nfs4_ver_fattr4_attr 286 * will not generate args for change. This is a bug 287 * that will be fixed later. 288 * XXX 289 */ 290 fattrp->attrmask &= ~FATTR4_CHANGE_MASK; 291 attrfunc = nfs4_ver_fattr4_attr; 292 } 293 294 /* Mask out any rec attrs unsupported by server */ 295 fattrp->attrmask &= supp; 296 297 attrcnt = 0; 298 xdr_size = 0; 299 for (i = 0; i < nfs4_ntov_map_size; i++) { 300 /* 301 * In the case of FATTR4_ACL_MASK, the vbit will be 0 (zero) 302 * so we must also check if the fbit is FATTR4_ACL_MASK before 303 * skipping over this attribute. 304 */ 305 if (!(nfs4_ntov_map[i].vbit & vap->va_mask)) { 306 if (nfs4_ntov_map[i].fbit != FATTR4_ACL_MASK) 307 continue; 308 if (vsap == NULL) 309 continue; 310 } 311 312 if (attrfunc == nfs4_set_fattr4_attr) { 313 if (!(*attrfunc)(vap, vsap, &nfs4_ntov_map[i], 314 &na[attrcnt], flags, &error)) 315 continue; 316 } else if (attrfunc == nfs4_ver_fattr4_attr) { 317 if (!(*attrfunc)(vap, &nfs4_ntov_map[i], &na[attrcnt], 318 flags, &error)) 319 continue; 320 } 321 322 if (error) 323 goto done; /* Exit! */ 324 325 /* 326 * Calculate XDR size 327 */ 328 if (nfs4_ntov_map[i].xdr_size != 0) { 329 /* 330 * If we are setting attributes (attrfunc is 331 * nfs4_set_fattr4_attr) and are setting the 332 * mtime or atime, adjust the xdr size down by 333 * 3 words, since we are using the server's 334 * time as the current time. Exception: if 335 * ATTR_UTIME is set, the client sends the 336 * time, so leave the xdr size alone. 337 */ 338 xdr_size += nfs4_ntov_map[i].xdr_size; 339 if ((nfs4_ntov_map[i].nval == FATTR4_TIME_ACCESS_SET || 340 nfs4_ntov_map[i].nval == FATTR4_TIME_MODIFY_SET) && 341 attrfunc == nfs4_set_fattr4_attr && 342 !(flags & ATTR_UTIME)) { 343 xdr_size -= 3 * BYTES_PER_XDR_UNIT; 344 } 345 } else { 346 /* 347 * The only zero xdr_sizes we should see 348 * are AT_UID, AT_GID and FATTR4_ACL_MASK 349 */ 350 ASSERT(nfs4_ntov_map[i].vbit == AT_UID || 351 nfs4_ntov_map[i].vbit == AT_GID || 352 nfs4_ntov_map[i].fbit == FATTR4_ACL_MASK); 353 if (nfs4_ntov_map[i].vbit == AT_UID) { 354 uid_attr = attrcnt; 355 xdr_size += BYTES_PER_XDR_UNIT; /* length */ 356 xdr_size += 357 RNDUP(na[attrcnt].owner.utf8string_len); 358 } else if (nfs4_ntov_map[i].vbit == AT_GID) { 359 gid_attr = attrcnt; 360 xdr_size += BYTES_PER_XDR_UNIT; /* length */ 361 xdr_size += 362 RNDUP( 363 na[attrcnt].owner_group.utf8string_len); 364 } else if (nfs4_ntov_map[i].fbit == FATTR4_ACL_MASK) { 365 nfsace4 *tmpacl = (nfsace4 *)vsap->vsa_aclentp; 366 367 acl_attr = attrcnt; 368 /* fattr4_acl_len */ 369 xdr_size += BYTES_PER_XDR_UNIT; 370 /* fattr4_acl_val */ 371 xdr_size += RNDUP((vsap->vsa_aclcnt * 372 (sizeof (acetype4) + sizeof (aceflag4) 373 + sizeof (acemask4)))); 374 375 for (j = 0; j < vsap->vsa_aclcnt; j++) { 376 /* who - utf8string_len */ 377 xdr_size += BYTES_PER_XDR_UNIT; 378 /* who - utf8string_val */ 379 xdr_size += 380 RNDUP(tmpacl[j].who.utf8string_len); 381 } 382 } 383 } 384 385 /* 386 * This attr is going otw 387 */ 388 amap[attrcnt] = (uint8_t)nfs4_ntov_map[i].nval; 389 attrcnt++; 390 391 /* 392 * Clear this bit from test mask so we stop 393 * as soon as all requested attrs are done. 394 */ 395 va_mask &= ~nfs4_ntov_map[i].vbit; 396 if (va_mask == 0 && 397 (vsap == NULL || (vsap != NULL && acl_attr != -1))) 398 break; 399 } 400 401 if (attrcnt == 0) { 402 goto done; 403 } 404 405 fattrp->attrlist4 = xdr_attrs = kmem_alloc(xdr_size, KM_SLEEP); 406 fattrp->attrlist4_len = xdr_size; 407 xdrmem_create(&xdr, xdr_attrs, xdr_size, XDR_ENCODE); 408 for (i = 0; i < attrcnt; i++) { 409 if ((*nfs4_ntov_map[amap[i]].xfunc)(&xdr, &na[i]) == FALSE) { 410 cmn_err(CE_WARN, "vattr_to_fattr4: xdr encode of " 411 "attribute failed\n"); 412 error = EINVAL; 413 break; 414 } 415 } 416 done: 417 /* 418 * Free any malloc'd attrs, can only be uid or gid 419 */ 420 if (uid_attr != -1 && na[uid_attr].owner.utf8string_val != NULL) { 421 kmem_free(na[uid_attr].owner.utf8string_val, 422 na[uid_attr].owner.utf8string_len); 423 } 424 if (gid_attr != -1 && na[gid_attr].owner_group.utf8string_val != NULL) { 425 kmem_free(na[gid_attr].owner_group.utf8string_val, 426 na[gid_attr].owner_group.utf8string_len); 427 } 428 429 /* xdrmem_destroy(&xdrs); */ /* NO-OP */ 430 kmem_free(na, sizeof (union nfs4_attr_u) * nfs4_ntov_map_size); 431 if (error) 432 nfs4_fattr4_free(fattrp); 433 return (error); 434 } 435 436 void 437 nfs4_fattr4_free(fattr4 *attrp) 438 { 439 /* 440 * set attrlist4val/len to 0 because... 441 * 442 * op_readdir resfree function could call us again 443 * for last entry4 if it was able to encode the name 444 * and cookie but couldn't encode the attrs because 445 * of maxcount violation (from rddir args). In that 446 * case, the last/partial entry4's fattr4 has already 447 * been free'd, but the entry4 remains on the end of 448 * the list. 449 */ 450 attrp->attrmask = 0; 451 452 if (attrp->attrlist4) { 453 kmem_free(attrp->attrlist4, attrp->attrlist4_len); 454 attrp->attrlist4 = NULL; 455 attrp->attrlist4_len = 0; 456 } 457 } 458 459 /* 460 * Translate a vattr_t mask to a fattr4 type bitmap, caller is 461 * responsible for zeroing bitsval if needed. 462 */ 463 void 464 nfs4_vmask_to_nmask(uint_t vmask, bitmap4 *bitsval) 465 { 466 if (vmask == AT_ALL || vmask == NFS4_VTON_ATTR_MASK) { 467 *bitsval |= NFS4_NTOV_ATTR_MASK; 468 return; 469 } 470 471 vmask &= NFS4_VTON_ATTR_MASK; 472 if (vmask == 0) { 473 return; 474 } 475 476 if (vmask & AT_TYPE) 477 *bitsval |= FATTR4_TYPE_MASK; 478 if (vmask & AT_MODE) 479 *bitsval |= FATTR4_MODE_MASK; 480 if (vmask & AT_UID) 481 *bitsval |= FATTR4_OWNER_MASK; 482 if (vmask & AT_GID) 483 *bitsval |= FATTR4_OWNER_GROUP_MASK; 484 if (vmask & AT_FSID) 485 *bitsval |= FATTR4_FSID_MASK; 486 /* set mounted_on_fileid when AT_NODEID requested */ 487 if (vmask & AT_NODEID) 488 *bitsval |= FATTR4_FILEID_MASK | FATTR4_MOUNTED_ON_FILEID_MASK; 489 if (vmask & AT_NLINK) 490 *bitsval |= FATTR4_NUMLINKS_MASK; 491 if (vmask & AT_SIZE) 492 *bitsval |= FATTR4_SIZE_MASK; 493 if (vmask & AT_ATIME) 494 *bitsval |= FATTR4_TIME_ACCESS_MASK; 495 if (vmask & AT_MTIME) 496 *bitsval |= FATTR4_TIME_MODIFY_MASK; 497 /* also set CHANGE whenever AT_CTIME requested */ 498 if (vmask & AT_CTIME) 499 *bitsval |= FATTR4_TIME_METADATA_MASK | FATTR4_CHANGE_MASK; 500 if (vmask & AT_NBLOCKS) 501 *bitsval |= FATTR4_SPACE_USED_MASK; 502 if (vmask & AT_RDEV) 503 *bitsval |= FATTR4_RAWDEV_MASK; 504 } 505 506 /* 507 * nfs4_vmask_to_nmask_set is used for setattr. A separate function needed 508 * because of special treatment to timeset. 509 */ 510 void 511 nfs4_vmask_to_nmask_set(uint_t vmask, bitmap4 *bitsval) 512 { 513 vmask &= NFS4_VTON_ATTR_MASK_SET; 514 515 if (vmask == 0) { 516 return; 517 } 518 519 if (vmask & AT_MODE) 520 *bitsval |= FATTR4_MODE_MASK; 521 if (vmask & AT_UID) 522 *bitsval |= FATTR4_OWNER_MASK; 523 if (vmask & AT_GID) 524 *bitsval |= FATTR4_OWNER_GROUP_MASK; 525 if (vmask & AT_SIZE) 526 *bitsval |= FATTR4_SIZE_MASK; 527 if (vmask & AT_ATIME) 528 *bitsval |= FATTR4_TIME_ACCESS_SET_MASK; 529 if (vmask & AT_MTIME) 530 *bitsval |= FATTR4_TIME_MODIFY_SET_MASK; 531 } 532 533 /* 534 * Convert NFS Version 4 over the network attributes to the local 535 * virtual attributes. 536 */ 537 vtype_t nf4_to_vt[] = { 538 VBAD, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VFIFO, VDIR, VREG 539 }; 540 541 542 /* 543 * { fbit, vbit, vfsstat, mandatory, 544 * nval, xdr_size, xfunc, 545 * sv_getit, prtstr }, 546 */ 547 struct nfs4_ntov_map nfs4_ntov_map[] = { 548 { FATTR4_SUPPORTED_ATTRS_MASK, 0, FALSE, TRUE, 549 FATTR4_SUPPORTED_ATTRS, 2 * BYTES_PER_XDR_UNIT, xdr_bitmap4, 550 NULL, "fattr4_supported_attrs" }, 551 552 { FATTR4_TYPE_MASK, AT_TYPE, FALSE, TRUE, 553 FATTR4_TYPE, BYTES_PER_XDR_UNIT, xdr_int, 554 NULL, "fattr4_type" }, 555 556 { FATTR4_FH_EXPIRE_TYPE_MASK, 0, FALSE, TRUE, 557 FATTR4_FH_EXPIRE_TYPE, BYTES_PER_XDR_UNIT, xdr_u_int, 558 NULL, "fattr4_fh_expire_type" }, 559 560 { FATTR4_CHANGE_MASK, 0, FALSE, TRUE, 561 FATTR4_CHANGE, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 562 NULL, "fattr4_change" }, 563 564 { FATTR4_SIZE_MASK, AT_SIZE, FALSE, TRUE, 565 FATTR4_SIZE, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 566 NULL, "fattr4_size" }, 567 568 { FATTR4_LINK_SUPPORT_MASK, 0, FALSE, TRUE, 569 FATTR4_LINK_SUPPORT, BYTES_PER_XDR_UNIT, xdr_bool, 570 NULL, "fattr4_link_support" }, 571 572 { FATTR4_SYMLINK_SUPPORT_MASK, 0, FALSE, TRUE, 573 FATTR4_SYMLINK_SUPPORT, BYTES_PER_XDR_UNIT, xdr_bool, 574 NULL, "fattr4_symlink_support" }, 575 576 { FATTR4_NAMED_ATTR_MASK, 0, FALSE, TRUE, 577 FATTR4_NAMED_ATTR, BYTES_PER_XDR_UNIT, xdr_bool, 578 NULL, "fattr4_named_attr" }, 579 580 { FATTR4_FSID_MASK, AT_FSID, FALSE, TRUE, 581 FATTR4_FSID, 4 * BYTES_PER_XDR_UNIT, xdr_fattr4_fsid, 582 NULL, "fattr4_fsid" }, 583 584 { FATTR4_UNIQUE_HANDLES_MASK, 0, FALSE, TRUE, 585 FATTR4_UNIQUE_HANDLES, BYTES_PER_XDR_UNIT, xdr_bool, 586 NULL, "fattr4_unique_handles" }, 587 588 { FATTR4_LEASE_TIME_MASK, 0, FALSE, TRUE, 589 FATTR4_LEASE_TIME, BYTES_PER_XDR_UNIT, xdr_u_int, 590 NULL, "fattr4_lease_time" }, 591 592 { FATTR4_RDATTR_ERROR_MASK, 0, FALSE, TRUE, 593 FATTR4_RDATTR_ERROR, BYTES_PER_XDR_UNIT, xdr_int, 594 NULL, "fattr4_rdattr_error" }, 595 596 { FATTR4_ACL_MASK, 0, FALSE, FALSE, 597 FATTR4_ACL, 0, xdr_fattr4_acl, 598 NULL, "fattr4_acl" }, 599 600 { FATTR4_ACLSUPPORT_MASK, 0, FALSE, FALSE, 601 FATTR4_ACLSUPPORT, BYTES_PER_XDR_UNIT, xdr_u_int, 602 NULL, "fattr4_aclsupport" }, 603 604 { FATTR4_ARCHIVE_MASK, 0, FALSE, FALSE, 605 FATTR4_ARCHIVE, BYTES_PER_XDR_UNIT, xdr_bool, 606 NULL, "fattr4_archive" }, 607 608 { FATTR4_CANSETTIME_MASK, 0, FALSE, FALSE, 609 FATTR4_CANSETTIME, BYTES_PER_XDR_UNIT, xdr_bool, 610 NULL, "fattr4_cansettime" }, 611 612 { FATTR4_CASE_INSENSITIVE_MASK, 0, FALSE, FALSE, 613 FATTR4_CASE_INSENSITIVE, BYTES_PER_XDR_UNIT, xdr_bool, 614 NULL, "fattr4_case_insensitive" }, 615 616 { FATTR4_CASE_PRESERVING_MASK, 0, FALSE, FALSE, 617 FATTR4_CASE_PRESERVING, BYTES_PER_XDR_UNIT, xdr_bool, 618 NULL, "fattr4_case_preserving" }, 619 620 { FATTR4_CHOWN_RESTRICTED_MASK, 0, FALSE, FALSE, 621 FATTR4_CHOWN_RESTRICTED, BYTES_PER_XDR_UNIT, xdr_bool, 622 NULL, "fattr4_chown_restricted" }, 623 624 { FATTR4_FILEHANDLE_MASK, 0, FALSE, TRUE, 625 FATTR4_FILEHANDLE, 0, xdr_nfs_fh4, 626 NULL, "fattr4_filehandle" }, 627 628 { FATTR4_FILEID_MASK, AT_NODEID, FALSE, FALSE, 629 FATTR4_FILEID, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 630 NULL, "fattr4_fileid" }, 631 632 { FATTR4_FILES_AVAIL_MASK, 0, TRUE, FALSE, 633 FATTR4_FILES_AVAIL, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 634 NULL, "fattr4_files_avail" }, 635 636 { FATTR4_FILES_FREE_MASK, 0, TRUE, FALSE, 637 FATTR4_FILES_FREE, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 638 NULL, "fattr4_files_free" }, 639 640 { FATTR4_FILES_TOTAL_MASK, 0, TRUE, FALSE, 641 FATTR4_FILES_TOTAL, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 642 NULL, "fattr4_files_total" }, 643 644 { FATTR4_FS_LOCATIONS_MASK, 0, FALSE, FALSE, 645 FATTR4_FS_LOCATIONS, 0, xdr_fattr4_fs_locations, 646 NULL, "fattr4_fs_locations" }, 647 648 { FATTR4_HIDDEN_MASK, 0, FALSE, FALSE, 649 FATTR4_HIDDEN, BYTES_PER_XDR_UNIT, xdr_bool, 650 NULL, "fattr4_hidden" }, 651 652 { FATTR4_HOMOGENEOUS_MASK, 0, FALSE, FALSE, 653 FATTR4_HOMOGENEOUS, BYTES_PER_XDR_UNIT, xdr_bool, 654 NULL, "fattr4_homogeneous" }, 655 656 { FATTR4_MAXFILESIZE_MASK, 0, FALSE, FALSE, 657 FATTR4_MAXFILESIZE, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 658 NULL, "fattr4_maxfilesize" }, 659 660 { FATTR4_MAXLINK_MASK, 0, FALSE, FALSE, 661 FATTR4_MAXLINK, BYTES_PER_XDR_UNIT, xdr_u_int, 662 NULL, "fattr4_maxlink" }, 663 664 { FATTR4_MAXNAME_MASK, 0, FALSE, FALSE, 665 FATTR4_MAXNAME, BYTES_PER_XDR_UNIT, xdr_u_int, 666 NULL, "fattr4_maxname" }, 667 668 { FATTR4_MAXREAD_MASK, 0, FALSE, FALSE, 669 FATTR4_MAXREAD, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 670 NULL, "fattr4_maxread" }, 671 672 { FATTR4_MAXWRITE_MASK, 0, FALSE, FALSE, 673 FATTR4_MAXWRITE, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 674 NULL, "fattr4_maxwrite" }, 675 676 { FATTR4_MIMETYPE_MASK, 0, FALSE, FALSE, 677 FATTR4_MIMETYPE, 0, xdr_utf8string, 678 NULL, "fattr4_mimetype" }, 679 680 { FATTR4_MODE_MASK, AT_MODE, FALSE, FALSE, 681 FATTR4_MODE, BYTES_PER_XDR_UNIT, xdr_u_int, 682 NULL, "fattr4_mode" }, 683 684 { FATTR4_NO_TRUNC_MASK, 0, FALSE, FALSE, 685 FATTR4_NO_TRUNC, BYTES_PER_XDR_UNIT, xdr_bool, 686 NULL, "fattr4_no_trunc" }, 687 688 { FATTR4_NUMLINKS_MASK, AT_NLINK, FALSE, FALSE, 689 FATTR4_NUMLINKS, BYTES_PER_XDR_UNIT, xdr_u_int, 690 NULL, "fattr4_numlinks" }, 691 692 { FATTR4_OWNER_MASK, AT_UID, FALSE, FALSE, 693 FATTR4_OWNER, 0, xdr_utf8string, 694 NULL, "fattr4_owner" }, 695 696 { FATTR4_OWNER_GROUP_MASK, AT_GID, FALSE, FALSE, 697 FATTR4_OWNER_GROUP, 0, xdr_utf8string, 698 NULL, "fattr4_owner_group" }, 699 700 { FATTR4_QUOTA_AVAIL_HARD_MASK, 0, FALSE, FALSE, 701 FATTR4_QUOTA_AVAIL_HARD, 2 * BYTES_PER_XDR_UNIT, 702 xdr_u_longlong_t, 703 NULL, "fattr4_quota_avail_hard" }, 704 705 { FATTR4_QUOTA_AVAIL_SOFT_MASK, 0, FALSE, FALSE, 706 FATTR4_QUOTA_AVAIL_SOFT, 2 * BYTES_PER_XDR_UNIT, 707 xdr_u_longlong_t, 708 NULL, "fattr4_quota_avail_soft" }, 709 710 { FATTR4_QUOTA_USED_MASK, 0, FALSE, FALSE, 711 FATTR4_QUOTA_USED, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 712 NULL, "fattr4_quota_used" }, 713 714 { FATTR4_RAWDEV_MASK, AT_RDEV, FALSE, FALSE, 715 FATTR4_RAWDEV, 2 * BYTES_PER_XDR_UNIT, xdr_fattr4_rawdev, 716 NULL, "fattr4_rawdev" }, 717 718 { FATTR4_SPACE_AVAIL_MASK, 0, TRUE, FALSE, 719 FATTR4_SPACE_AVAIL, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 720 NULL, "fattr4_space_avail" }, 721 722 { FATTR4_SPACE_FREE_MASK, 0, TRUE, FALSE, 723 FATTR4_SPACE_FREE, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 724 NULL, "fattr4_space_free" }, 725 726 { FATTR4_SPACE_TOTAL_MASK, 0, TRUE, FALSE, 727 FATTR4_SPACE_TOTAL, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 728 NULL, "fattr4_space_total" }, 729 730 { FATTR4_SPACE_USED_MASK, AT_NBLOCKS, FALSE, FALSE, 731 FATTR4_SPACE_USED, 2 * BYTES_PER_XDR_UNIT, xdr_u_longlong_t, 732 NULL, "fattr4_space_used" }, 733 734 { FATTR4_SYSTEM_MASK, 0, FALSE, FALSE, 735 FATTR4_SYSTEM, BYTES_PER_XDR_UNIT, xdr_bool, 736 NULL, "fattr4_system" }, 737 738 { FATTR4_TIME_ACCESS_MASK, AT_ATIME, FALSE, FALSE, 739 FATTR4_TIME_ACCESS, 3 * BYTES_PER_XDR_UNIT, xdr_nfstime4, 740 NULL, "fattr4_time_access" }, 741 742 { FATTR4_TIME_ACCESS_SET_MASK, AT_ATIME, FALSE, FALSE, 743 FATTR4_TIME_ACCESS_SET, 4 * BYTES_PER_XDR_UNIT, xdr_settime4, 744 NULL, "fattr4_time_access_set" }, 745 746 { FATTR4_TIME_BACKUP_MASK, 0, FALSE, FALSE, 747 FATTR4_TIME_BACKUP, 3 * BYTES_PER_XDR_UNIT, xdr_nfstime4, 748 NULL, "fattr4_time_backup" }, 749 750 { FATTR4_TIME_CREATE_MASK, 0, FALSE, FALSE, 751 FATTR4_TIME_CREATE, 3 * BYTES_PER_XDR_UNIT, xdr_nfstime4, 752 NULL, "fattr4_time_create" }, 753 754 { FATTR4_TIME_DELTA_MASK, 0, FALSE, FALSE, 755 FATTR4_TIME_DELTA, 3 * BYTES_PER_XDR_UNIT, xdr_nfstime4, 756 NULL, "fattr4_time_delta" }, 757 758 { FATTR4_TIME_METADATA_MASK, AT_CTIME, FALSE, FALSE, 759 FATTR4_TIME_METADATA, 3 * BYTES_PER_XDR_UNIT, xdr_nfstime4, 760 NULL, "fattr4_time_metadata" }, 761 762 { FATTR4_TIME_MODIFY_MASK, AT_MTIME, FALSE, FALSE, 763 FATTR4_TIME_MODIFY, 3 * BYTES_PER_XDR_UNIT, xdr_nfstime4, 764 NULL, "fattr4_time_modify" }, 765 766 { FATTR4_TIME_MODIFY_SET_MASK, AT_MTIME, FALSE, FALSE, 767 FATTR4_TIME_MODIFY_SET, 4 * BYTES_PER_XDR_UNIT, xdr_settime4, 768 NULL, "fattr4_time_modify_set" }, 769 770 { FATTR4_MOUNTED_ON_FILEID_MASK, AT_NODEID, FALSE, FALSE, 771 FATTR4_MOUNTED_ON_FILEID, 2 * BYTES_PER_XDR_UNIT, 772 xdr_u_longlong_t, 773 NULL, "fattr4_mounted_on_fileid" }, 774 775 { FATTR4_SUPPATTR_EXCLCREAT_MASK_LOCAL, 0, FALSE, FALSE, 776 FATTR4_MOUNTED_ON_FILEID + 1, 0, xdr_bitmap4, 777 NULL, "fattr4_suppattr_exclcreat" }, 778 }; 779 780 uint_t nfs4_ntov_map_size = sizeof (nfs4_ntov_map) / 781 sizeof (struct nfs4_ntov_map); 782