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