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