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 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/systm.h> 30 #include <sys/cmn_err.h> 31 #include <nfs/nfs.h> 32 #include <nfs/export.h> 33 #include <nfs/nfs4.h> 34 #include <sys/ddi.h> 35 36 void rfs4_init_compound_state(struct compound_state *); 37 38 bitmap4 rfs4_supported_attrs; 39 int MSG_PRT_DEBUG = FALSE; 40 41 /* If building with DEBUG enabled, enable mandattr tuneable by default */ 42 #ifdef DEBUG 43 #ifndef RFS4_SUPPORT_MANDATTR_ONLY 44 #define RFS4_SUPPORT_MANDATTR_ONLY 45 #endif 46 #endif 47 48 /* 49 * If building with mandattr only code, disable it by default. 50 * To enable, set rfs4_mandattr_only in /etc/system and reboot. 51 * When building without mandattr ifdef, the compiler should 52 * optimize away the the comparisons because RFS4_MANDATTR_ONLY 53 * is defined to be 0. 54 */ 55 #ifdef RFS4_SUPPORT_MANDATTR_ONLY 56 #define NFS4_LAST_MANDATTR FATTR4_RDATTR_ERROR 57 #define RFS4_MANDATTR_ONLY rfs4_mandattr_only 58 int rfs4_mandattr_only = 0; 59 #else 60 #define RFS4_MANDATTR_ONLY 0 61 #endif 62 63 64 static void rfs4_ntov_init(void); 65 static int rfs4_fattr4_supported_attrs(); 66 static int rfs4_fattr4_type(); 67 static int rfs4_fattr4_fh_expire_type(); 68 static int rfs4_fattr4_change(); 69 static int rfs4_fattr4_size(); 70 static int rfs4_fattr4_link_support(); 71 static int rfs4_fattr4_symlink_support(); 72 static int rfs4_fattr4_named_attr(); 73 static int rfs4_fattr4_fsid(); 74 static int rfs4_fattr4_unique_handles(); 75 static int rfs4_fattr4_lease_time(); 76 static int rfs4_fattr4_rdattr_error(); 77 static int rfs4_fattr4_acl(); 78 static int rfs4_fattr4_aclsupport(); 79 static int rfs4_fattr4_archive(); 80 static int rfs4_fattr4_cansettime(); 81 static int rfs4_fattr4_case_insensitive(); 82 static int rfs4_fattr4_case_preserving(); 83 static int rfs4_fattr4_chown_restricted(); 84 static int rfs4_fattr4_filehandle(); 85 static int rfs4_fattr4_fileid(); 86 static int rfs4_fattr4_files_avail(); 87 static int rfs4_fattr4_files_free(); 88 static int rfs4_fattr4_files_total(); 89 static int rfs4_fattr4_fs_locations(); 90 static int rfs4_fattr4_hidden(); 91 static int rfs4_fattr4_homogeneous(); 92 static int rfs4_fattr4_maxfilesize(); 93 static int rfs4_fattr4_maxlink(); 94 static int rfs4_fattr4_maxname(); 95 static int rfs4_fattr4_maxread(); 96 static int rfs4_fattr4_maxwrite(); 97 static int rfs4_fattr4_mimetype(); 98 static int rfs4_fattr4_mode(); 99 static int rfs4_fattr4_no_trunc(); 100 static int rfs4_fattr4_numlinks(); 101 static int rfs4_fattr4_owner(); 102 static int rfs4_fattr4_owner_group(); 103 static int rfs4_fattr4_quota_avail_hard(); 104 static int rfs4_fattr4_quota_avail_soft(); 105 static int rfs4_fattr4_quota_used(); 106 static int rfs4_fattr4_rawdev(); 107 static int rfs4_fattr4_space_avail(); 108 static int rfs4_fattr4_space_free(); 109 static int rfs4_fattr4_space_total(); 110 static int rfs4_fattr4_space_used(); 111 static int rfs4_fattr4_system(); 112 static int rfs4_fattr4_time_access(); 113 static int rfs4_fattr4_time_access_set(); 114 static int rfs4_fattr4_time_backup(); 115 static int rfs4_fattr4_time_create(); 116 static int rfs4_fattr4_time_delta(); 117 static int rfs4_fattr4_time_metadata(); 118 static int rfs4_fattr4_time_modify(); 119 static int rfs4_fattr4_time_modify_set(); 120 121 /* 122 * Initialize the supported attributes 123 */ 124 void 125 rfs4_attr_init() 126 { 127 int i; 128 struct nfs4_svgetit_arg sarg; 129 struct compound_state cs; 130 struct statvfs64 sb; 131 132 rfs4_init_compound_state(&cs); 133 cs.vp = rootvp; 134 cs.fh.nfs_fh4_val = NULL; 135 cs.cr = kcred; 136 137 /* 138 * Get all the supported attributes 139 */ 140 sarg.op = NFS4ATTR_SUPPORTED; 141 sarg.cs = &cs; 142 sarg.vap->va_mask = AT_ALL; 143 sarg.sbp = &sb; 144 sarg.flag = 0; 145 sarg.rdattr_error = NFS4_OK; 146 sarg.rdattr_error_req = FALSE; 147 148 rfs4_ntov_init(); 149 150 rfs4_supported_attrs = 0; 151 for (i = 0; i < NFS4_MAXNUM_ATTRS; i++) { 152 #ifdef RFS4_SUPPORT_MANDATTR_ONLY 153 if (rfs4_mandattr_only == TRUE && i > NFS4_LAST_MANDATTR) 154 continue; 155 #endif 156 if ((*nfs4_ntov_map[i].sv_getit)(NFS4ATTR_SUPPORTED, 157 &sarg, NULL) == 0) { 158 rfs4_supported_attrs |= nfs4_ntov_map[i].fbit; 159 } 160 } 161 } 162 163 /* 164 * The following rfs4_fattr4_* functions convert between the fattr4 165 * arguments/attributes and the system (e.g. vattr) values. The following 166 * commands are currently in use: 167 * 168 * NFS4ATTR_SUPPORTED: checks if the attribute in question is supported: 169 * sarg.op = SUPPORTED - all supported attrs 170 * sarg.op = GETIT - only supported readable attrs 171 * sarg.op = SETIT - only supported writable attrs 172 * 173 * NFS4ATTR_GETIT: getattr type conversion - convert system values 174 * (e.g. vattr struct) to fattr4 type values to be returned to the 175 * user - usually in response to nfsv4 getattr request. 176 * 177 * NFS4ATTR_SETIT: convert fattr4 type values to system values to use by 178 * setattr. Allows only read/write and write attributes, 179 * even if not supported by the filesystem. Note that ufs only allows setattr 180 * of owner/group, mode, size, atime/mtime. 181 * 182 * NFS4ATTR_VERIT: convert fattr4 type values to system values to use by 183 * verify/nverify. Implemented to allow 184 * almost everything that can be returned by getattr into known structs 185 * (like vfsstat64 or vattr_t), that is, both read only and read/write attrs. 186 * The function will return -1 if it found that the arguments don't match. 187 * This applies to system-wide values that don't require a VOP_GETATTR 188 * or other further checks to verify. It will return no error if they 189 * either match or were retrieved successfully for later checking. 190 * 191 * NFS4ATTR_FREEIT: free up any space allocated by either of the above. 192 * The sargp->op should be either NFS4ATTR_GETIT or NFS4ATTR_SETIT 193 * to indicate which op was used to allocate the space. 194 * 195 * XXX Note: these functions are currently used by the server only. A 196 * XXX different method of conversion is used on the client side. 197 * XXX Eventually combining the two (possibly by adding NFS4ATTR_CLNT_GETIT 198 * XXX and SETIT) may be a cleaner approach. 199 */ 200 201 /* 202 * Mandatory attributes 203 */ 204 205 /* ARGSUSED */ 206 static int 207 rfs4_fattr4_supported_attrs(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 208 union nfs4_attr_u *na) 209 { 210 int error = 0; 211 212 switch (cmd) { 213 case NFS4ATTR_SUPPORTED: 214 if (sarg->op == NFS4ATTR_SETIT) 215 error = EINVAL; 216 break; /* this attr is supported */ 217 case NFS4ATTR_GETIT: 218 na->supported_attrs = rfs4_supported_attrs; 219 break; 220 case NFS4ATTR_SETIT: 221 /* 222 * read-only attr 223 */ 224 error = EINVAL; 225 break; 226 case NFS4ATTR_VERIT: 227 /* 228 * Compare the input bitmap to the server's bitmap 229 */ 230 if (na->supported_attrs != rfs4_supported_attrs) { 231 error = -1; /* no match */ 232 } 233 break; 234 case NFS4ATTR_FREEIT: 235 break; 236 } 237 return (error); 238 } 239 240 /* 241 * Translate vnode vtype to nfsv4_ftype. 242 */ 243 static nfs_ftype4 vt_to_nf4[] = { 244 0, NF4REG, NF4DIR, NF4BLK, NF4CHR, NF4LNK, NF4FIFO, 0, 0, NF4SOCK, 0 245 }; 246 247 /* ARGSUSED */ 248 static int 249 rfs4_fattr4_type(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 250 union nfs4_attr_u *na) 251 { 252 int error = 0; 253 254 switch (cmd) { 255 case NFS4ATTR_SUPPORTED: 256 if (sarg->op == NFS4ATTR_SETIT) 257 error = EINVAL; 258 break; /* this attr is supported */ 259 case NFS4ATTR_GETIT: 260 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_TYPE)) { 261 error = -1; /* may be okay if rdattr_error */ 262 break; 263 } 264 ASSERT(sarg->vap->va_mask & AT_TYPE); 265 266 /* 267 * if xattr flag not set, use v4_to_nf4 mapping; 268 * otherwise verify xattr flag is in sync with va_type 269 * and set xattr types. 270 */ 271 if (! (sarg->xattr & (FH4_NAMEDATTR | FH4_ATTRDIR))) 272 na->type = vt_to_nf4[sarg->vap->va_type]; 273 else { 274 /* 275 * FH4 flag was set. Dir type maps to attrdir, 276 * and all other types map to namedattr. 277 */ 278 if (sarg->vap->va_type == VDIR) 279 na->type = NF4ATTRDIR; 280 else 281 na->type = NF4NAMEDATTR; 282 } 283 break; 284 case NFS4ATTR_SETIT: 285 /* 286 * read-only attr 287 */ 288 error = EINVAL; 289 break; 290 case NFS4ATTR_VERIT: 291 /* 292 * Compare the input type to the object type on server 293 */ 294 ASSERT(sarg->vap->va_mask & AT_TYPE); 295 if (sarg->vap->va_type != nf4_to_vt[na->type]) 296 error = -1; /* no match */ 297 break; 298 case NFS4ATTR_FREEIT: 299 break; 300 } 301 return (error); 302 } 303 304 /* ARGSUSED */ 305 static int 306 fattr4_get_fh_expire_type(struct exportinfo *exi, uint32_t *fh_expire_typep) 307 { 308 #ifdef VOLATILE_FH_TEST 309 int ex_flags; 310 311 if (exi == NULL) 312 return (ESTALE); 313 ex_flags = exi->exi_export.ex_flags; 314 if ((ex_flags & (EX_VOLFH | EX_VOLRNM | EX_VOLMIG | EX_NOEXPOPEN)) 315 == 0) { 316 *fh_expire_typep = FH4_PERSISTENT; 317 return (0); 318 } 319 *fh_expire_typep = 0; 320 321 if (ex_flags & EX_NOEXPOPEN) { 322 /* file handles should not expire with open - not used */ 323 *fh_expire_typep = FH4_NOEXPIRE_WITH_OPEN; 324 } 325 if (ex_flags & EX_VOLFH) { 326 /* 327 * file handles may expire any time - on share here. 328 * If volatile any, no need to check other flags. 329 */ 330 *fh_expire_typep |= FH4_VOLATILE_ANY; 331 return (0); 332 } 333 if (ex_flags & EX_VOLRNM) { 334 /* file handles may expire on rename */ 335 *fh_expire_typep |= FH4_VOL_RENAME; 336 } 337 if (ex_flags & EX_VOLMIG) { 338 /* file handles may expire on migration - not used */ 339 *fh_expire_typep |= FH4_VOL_MIGRATION; 340 } 341 #else /* not VOLATILE_FH_TEST */ 342 *fh_expire_typep = FH4_PERSISTENT; 343 #endif /* VOLATILE_FH_TEST */ 344 345 return (0); 346 } 347 348 /* 349 * At this point the only volatile filehandles we allow (for test purposes 350 * only) are either fh's that expire when the filesystem is shared (reshared), 351 * fh's that expire on a rename and persistent ones. 352 */ 353 /* ARGSUSED */ 354 static int 355 rfs4_fattr4_fh_expire_type(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 356 union nfs4_attr_u *na) 357 { 358 uint32_t fh_expire_type; 359 int error = 0; 360 361 switch (cmd) { 362 case NFS4ATTR_SUPPORTED: 363 if (sarg->op == NFS4ATTR_SETIT) 364 error = EINVAL; 365 break; /* this attr is supported */ 366 case NFS4ATTR_GETIT: 367 error = fattr4_get_fh_expire_type(sarg->cs->exi, 368 &na->fh_expire_type); 369 break; 370 case NFS4ATTR_SETIT: 371 /* 372 * read-only attr 373 */ 374 error = EINVAL; 375 break; 376 case NFS4ATTR_VERIT: 377 error = fattr4_get_fh_expire_type(sarg->cs->exi, 378 &fh_expire_type); 379 if (!error && (na->fh_expire_type != fh_expire_type)) 380 error = -1; /* no match */ 381 break; 382 case NFS4ATTR_FREEIT: 383 break; 384 } 385 return (error); 386 } 387 388 static int 389 fattr4_get_change(struct nfs4_svgetit_arg *sarg, fattr4_change *changep) 390 { 391 vattr_t vap2[1], *vap = sarg->vap; 392 struct compound_state *cs = sarg->cs; 393 vnode_t *vp = cs->vp; 394 nfsstat4 status; 395 396 if ((vap->va_mask & AT_CTIME) == 0) { 397 if (sarg->rdattr_error && (vp == NULL)) { 398 return (-1); /* may be okay if rdattr_error */ 399 } 400 ASSERT(vp != NULL); 401 vap = vap2; 402 vap->va_mask = AT_CTIME; 403 status = rfs4_vop_getattr(vp, vap, 0, cs->cr); 404 if (status != NFS4_OK) 405 return (geterrno4(status)); 406 } 407 NFS4_SET_FATTR4_CHANGE(*changep, vap->va_ctime) 408 return (0); 409 } 410 411 /* ARGSUSED */ 412 static int 413 rfs4_fattr4_change(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 414 union nfs4_attr_u *na) 415 { 416 int error = 0; 417 fattr4_change change; 418 uint_t mask; 419 vattr_t *vap = sarg->vap; 420 421 switch (cmd) { 422 case NFS4ATTR_SUPPORTED: 423 if (sarg->op == NFS4ATTR_SETIT) 424 error = EINVAL; 425 break; /* this attr is supported */ 426 case NFS4ATTR_GETIT: 427 error = fattr4_get_change(sarg, &na->change); 428 break; 429 case NFS4ATTR_SETIT: 430 /* 431 * read-only attr 432 */ 433 error = EINVAL; 434 break; 435 case NFS4ATTR_VERIT: 436 mask = vap->va_mask; 437 vap->va_mask &= ~AT_CTIME; /* force a VOP_GETATTR */ 438 error = fattr4_get_change(sarg, &change); 439 vap->va_mask = mask; 440 if (!error && (na->change != change)) 441 error = -1; 442 break; 443 case NFS4ATTR_FREEIT: 444 break; 445 } 446 return (error); 447 } 448 449 /* ARGSUSED */ 450 static int 451 rfs4_fattr4_size(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 452 union nfs4_attr_u *na) 453 { 454 int error = 0; 455 456 switch (cmd) { 457 case NFS4ATTR_SUPPORTED: 458 break; /* this attr is supported */ 459 case NFS4ATTR_GETIT: 460 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_SIZE)) { 461 error = -1; /* may be okay if rdattr_error */ 462 break; 463 } 464 ASSERT(sarg->vap->va_mask & AT_SIZE); 465 na->size = sarg->vap->va_size; 466 break; 467 case NFS4ATTR_SETIT: 468 ASSERT(sarg->vap->va_mask & AT_SIZE); 469 sarg->vap->va_size = na->size; 470 break; 471 case NFS4ATTR_VERIT: 472 ASSERT(sarg->vap->va_mask & AT_SIZE); 473 if (sarg->vap->va_size != na->size) 474 error = -1; /* no match */ 475 break; 476 case NFS4ATTR_FREEIT: 477 break; 478 } 479 return (error); 480 } 481 482 /* 483 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports 484 * hard links. 485 */ 486 /* ARGSUSED */ 487 static int 488 rfs4_fattr4_link_support(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 489 union nfs4_attr_u *na) 490 { 491 int error = 0; 492 493 switch (cmd) { 494 case NFS4ATTR_SUPPORTED: 495 if (sarg->op == NFS4ATTR_SETIT) 496 error = EINVAL; 497 break; /* this attr is supported */ 498 case NFS4ATTR_GETIT: 499 na->link_support = TRUE; 500 break; 501 case NFS4ATTR_SETIT: 502 /* 503 * read-only attr 504 */ 505 error = EINVAL; 506 break; 507 case NFS4ATTR_VERIT: 508 if (!na->link_support) 509 error = -1; /* no match */ 510 break; 511 case NFS4ATTR_FREEIT: 512 break; 513 } 514 return (error); 515 } 516 517 /* 518 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports 519 * sym links. 520 */ 521 /* ARGSUSED */ 522 static int 523 rfs4_fattr4_symlink_support(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 524 union nfs4_attr_u *na) 525 { 526 int error = 0; 527 528 switch (cmd) { 529 case NFS4ATTR_SUPPORTED: 530 if (sarg->op == NFS4ATTR_SETIT) 531 error = EINVAL; 532 break; /* this attr is supported */ 533 case NFS4ATTR_GETIT: 534 na->symlink_support = TRUE; 535 break; 536 case NFS4ATTR_SETIT: 537 /* 538 * read-only attr 539 */ 540 error = EINVAL; 541 break; 542 case NFS4ATTR_VERIT: 543 if (!na->symlink_support) 544 error = -1; /* no match */ 545 break; 546 case NFS4ATTR_FREEIT: 547 break; 548 } 549 return (error); 550 } 551 552 /* ARGSUSED */ 553 static int 554 rfs4_fattr4_named_attr(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 555 union nfs4_attr_u *na) 556 { 557 int error = 0; 558 ulong_t val; 559 560 switch (cmd) { 561 case NFS4ATTR_SUPPORTED: 562 if (sarg->op == NFS4ATTR_SETIT) 563 error = EINVAL; 564 break; /* this attr is supported */ 565 case NFS4ATTR_GETIT: 566 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) { 567 error = -1; /* may be okay if rdattr_error */ 568 break; 569 } 570 ASSERT(sarg->cs->vp != NULL); 571 572 /* 573 * Solaris xattr model requires that VFS_XATTR is set 574 * in file systems enabled for xattr. If VFS_XATTR 575 * not set, no need to call pathconf. 576 */ 577 if (sarg->cs->vp->v_vfsp->vfs_flag & VFS_XATTR) { 578 error = VOP_PATHCONF(sarg->cs->vp, _PC_XATTR_EXISTS, 579 &val, sarg->cs->cr); 580 if (error) 581 break; 582 } else 583 val = 0; 584 na->named_attr = (val ? TRUE : FALSE); 585 break; 586 case NFS4ATTR_SETIT: 587 /* 588 * read-only attr 589 */ 590 error = EINVAL; 591 break; 592 case NFS4ATTR_VERIT: 593 ASSERT(sarg->cs->vp != NULL); 594 if (sarg->cs->vp->v_vfsp->vfs_flag & VFS_XATTR) { 595 error = VOP_PATHCONF(sarg->cs->vp, _PC_XATTR_EXISTS, 596 &val, sarg->cs->cr); 597 if (error) 598 break; 599 } else 600 val = 0; 601 if (na->named_attr != (val ? TRUE : FALSE)) 602 error = -1; /* no match */ 603 break; 604 case NFS4ATTR_FREEIT: 605 break; 606 } 607 return (error); 608 } 609 610 /* ARGSUSED */ 611 static int 612 rfs4_fattr4_fsid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 613 union nfs4_attr_u *na) 614 { 615 int error = 0; 616 int *pmaj = (int *)&na->fsid.major; 617 618 /* 619 * fsid_t is 64bits so it fits completely in fattr4_fsid.major. 620 * fattr4_fsid.minor is always set to 0 since it isn't needed (yet). 621 */ 622 switch (cmd) { 623 case NFS4ATTR_SUPPORTED: 624 if (sarg->op == NFS4ATTR_SETIT) 625 error = EINVAL; 626 break; /* this attr is supported */ 627 case NFS4ATTR_GETIT: 628 if (sarg->cs->exi->exi_volatile_dev) { 629 pmaj[0] = sarg->cs->exi->exi_fsid.val[0]; 630 pmaj[1] = sarg->cs->exi->exi_fsid.val[1]; 631 na->fsid.minor = 0; 632 } else { 633 na->fsid.major = getmajor(sarg->vap->va_fsid); 634 na->fsid.minor = getminor(sarg->vap->va_fsid); 635 } 636 break; 637 case NFS4ATTR_SETIT: 638 error = EINVAL; 639 break; 640 case NFS4ATTR_VERIT: 641 if (sarg->cs->exi->exi_volatile_dev) { 642 if (pmaj[0] != sarg->cs->exi->exi_fsid.val[0] || 643 pmaj[1] != sarg->cs->exi->exi_fsid.val[1] || 644 na->fsid.minor != 0) 645 error = -1; 646 } else { 647 if (na->fsid.major != getmajor(sarg->vap->va_fsid) || 648 na->fsid.minor != getminor(sarg->vap->va_fsid)) 649 error = -1; 650 } 651 break; 652 case NFS4ATTR_FREEIT: 653 break; 654 } 655 return (error); 656 } 657 658 /* ARGSUSED */ 659 static int 660 rfs4_fattr4_unique_handles(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 661 union nfs4_attr_u *na) 662 { 663 /* 664 * XXX 665 * For now, we can't support this. Problem of /export, beinging 666 * a file system, /export/a and /export/b shared separately, 667 * and /export/a/l and /export/b/l are ahrd links of each other. 668 */ 669 int error = 0; 670 671 switch (cmd) { 672 case NFS4ATTR_SUPPORTED: 673 if (sarg->op == NFS4ATTR_SETIT) 674 error = EINVAL; 675 break; /* this attr is supported */ 676 case NFS4ATTR_GETIT: 677 na->unique_handles = FALSE; 678 break; 679 case NFS4ATTR_SETIT: 680 /* 681 * read-only attr 682 */ 683 error = EINVAL; 684 break; 685 case NFS4ATTR_VERIT: 686 if (na->unique_handles) 687 error = -1; /* no match */ 688 break; 689 case NFS4ATTR_FREEIT: 690 break; 691 } 692 return (error); 693 } 694 695 /* ARGSUSED */ 696 static int 697 rfs4_fattr4_lease_time(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 698 union nfs4_attr_u *na) 699 { 700 int error = 0; 701 702 switch (cmd) { 703 case NFS4ATTR_SUPPORTED: 704 if (sarg->op == NFS4ATTR_SETIT) 705 error = EINVAL; 706 break; /* this attr is supported */ 707 case NFS4ATTR_GETIT: 708 na->lease_time = rfs4_lease_time; 709 break; 710 case NFS4ATTR_SETIT: 711 /* 712 * read-only attr 713 */ 714 error = EINVAL; 715 break; 716 case NFS4ATTR_VERIT: 717 if (na->lease_time != rfs4_lease_time) 718 error = -1; /* no match */ 719 break; 720 case NFS4ATTR_FREEIT: 721 break; 722 } 723 return (error); 724 } 725 726 /* ARGSUSED */ 727 static int 728 rfs4_fattr4_rdattr_error(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 729 union nfs4_attr_u *na) 730 { 731 int error = 0; 732 733 switch (cmd) { 734 case NFS4ATTR_SUPPORTED: 735 if ((sarg->op == NFS4ATTR_SETIT) || 736 (sarg->op == NFS4ATTR_VERIT)) 737 error = EINVAL; 738 break; /* this attr is supported */ 739 case NFS4ATTR_GETIT: 740 ASSERT(sarg->rdattr_error_req); 741 na->rdattr_error = sarg->rdattr_error; 742 break; 743 case NFS4ATTR_SETIT: 744 case NFS4ATTR_VERIT: 745 /* 746 * read-only attr 747 */ 748 error = EINVAL; 749 break; 750 case NFS4ATTR_FREEIT: 751 break; 752 } 753 return (error); 754 } 755 756 /* 757 * Server side compare of a filehandle from the wire to a native 758 * server filehandle. 759 */ 760 static int 761 rfs4fhcmp(nfs_fh4 *wirefh, nfs_fh4 *srvfh) 762 { 763 nfs_fh4_fmt_t fh; 764 765 ASSERT(IS_P2ALIGNED(wirefh->nfs_fh4_val, sizeof (uint32_t))); 766 767 bzero(&fh, sizeof (nfs_fh4_fmt_t)); 768 if (!xdr_inline_decode_nfs_fh4((uint32_t *)wirefh->nfs_fh4_val, &fh, 769 wirefh->nfs_fh4_len)) 770 return (1); 771 772 return (bcmp(srvfh->nfs_fh4_val, &fh, srvfh->nfs_fh4_len)); 773 } 774 775 /* ARGSUSED */ 776 static int 777 rfs4_fattr4_filehandle(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 778 union nfs4_attr_u *na) 779 { 780 nfs_fh4 *fh; 781 782 switch (cmd) { 783 case NFS4ATTR_SUPPORTED: 784 if (sarg->op == NFS4ATTR_SETIT) 785 return (EINVAL); 786 return (0); /* this attr is supported */ 787 case NFS4ATTR_GETIT: 788 /* 789 * If sarg->cs->fh is all zeros then should makefh a new 790 * one, otherwise, copy that one over. 791 */ 792 fh = &sarg->cs->fh; 793 if (sarg->cs->fh.nfs_fh4_len == 0) { 794 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) 795 return (-1); /* okay if rdattr_error */ 796 ASSERT(sarg->cs->vp != NULL); 797 na->filehandle.nfs_fh4_val = 798 kmem_alloc(NFS_FH4_LEN, KM_SLEEP); 799 return (makefh4(&na->filehandle, sarg->cs->vp, 800 sarg->cs->exi)); 801 } 802 na->filehandle.nfs_fh4_val = 803 kmem_alloc(fh->nfs_fh4_len, KM_SLEEP); 804 nfs_fh4_copy(fh, &na->filehandle); 805 return (0); 806 case NFS4ATTR_SETIT: 807 /* 808 * read-only attr 809 */ 810 return (EINVAL); 811 case NFS4ATTR_VERIT: 812 /* 813 * A verify of a filehandle will have the client sending 814 * the raw format which needs to be compared to the 815 * native format. 816 */ 817 if (rfs4fhcmp(&na->filehandle, &sarg->cs->fh) == 1) 818 return (-1); /* no match */ 819 return (0); 820 case NFS4ATTR_FREEIT: 821 if (sarg->op != NFS4ATTR_GETIT) 822 return (0); 823 if (na->filehandle.nfs_fh4_val == NULL) 824 return (0); 825 kmem_free(na->filehandle.nfs_fh4_val, 826 na->filehandle.nfs_fh4_len); 827 na->filehandle.nfs_fh4_val = NULL; 828 na->filehandle.nfs_fh4_len = 0; 829 return (0); 830 } 831 return (0); 832 } 833 834 /* 835 * Recommended attributes 836 */ 837 838 /* ARGSUSED */ 839 static int 840 rfs4_fattr4_acl(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 841 union nfs4_attr_u *na) 842 { 843 int error = 0; 844 vsecattr_t vs_native, vs_ace4; 845 ulong_t whichacl; 846 nfsstat4 status; 847 vattr_t va, *vap = sarg->vap; 848 vnode_t *vp = sarg->cs->vp; 849 850 if (RFS4_MANDATTR_ONLY) 851 return (ENOTSUP); 852 853 switch (cmd) { 854 case NFS4ATTR_SUPPORTED: 855 break; 856 857 case NFS4ATTR_VERIT: 858 case NFS4ATTR_GETIT: 859 if (sarg->rdattr_error && (vp == NULL)) { 860 return (-1); 861 } 862 ASSERT(vp != NULL); 863 bzero(&vs_native, sizeof (vs_native)); 864 865 /* see which ACLs fs supports */ 866 error = VOP_PATHCONF(vp, _PC_ACL_ENABLED, &whichacl, 867 sarg->cs->cr); 868 if (error != 0) { 869 /* 870 * If we got an error, then the filesystem 871 * likely does not understand the _PC_ACL_ENABLED 872 * pathconf. In this case, we fall back to trying 873 * POSIX-draft (aka UFS-style) ACLs, since that's 874 * the behavior used by earlier version of NFS. 875 */ 876 error = 0; 877 whichacl = _ACL_ACLENT_ENABLED; 878 } 879 880 if (!(whichacl & (_ACL_ACE_ENABLED | _ACL_ACLENT_ENABLED))) { 881 /* 882 * If the file system supports neither ACE nor 883 * ACLENT ACLs we will fall back to UFS-style ACLs 884 * like we did above if there was an error upon 885 * calling VOP_PATHCONF. 886 * 887 * ACE and ACLENT type ACLs are the only interfaces 888 * supported thus far. If any other bits are set on 889 * 'whichacl' upon return from VOP_PATHCONF, we will 890 * ignore them. 891 */ 892 whichacl = _ACL_ACLENT_ENABLED; 893 } 894 895 if (whichacl & _ACL_ACE_ENABLED) 896 vs_native.vsa_mask = VSA_ACE | VSA_ACECNT; 897 else if (whichacl & _ACL_ACLENT_ENABLED) 898 vs_native.vsa_mask = VSA_ACL | VSA_ACLCNT | 899 VSA_DFACL | VSA_DFACLCNT; 900 901 if (error != 0) 902 break; 903 904 /* get the ACL, and translate it into nfsace4 style */ 905 error = VOP_GETSECATTR(vp, &vs_native, 906 0, sarg->cs->cr); 907 if (error != 0) 908 break; 909 if (whichacl & _ACL_ACE_ENABLED) { 910 error = vs_acet_to_ace4(&vs_native, &vs_ace4, TRUE); 911 vs_acet_destroy(&vs_native); 912 } else { 913 error = vs_aent_to_ace4(&vs_native, &vs_ace4, 914 vp->v_type == VDIR, TRUE); 915 vs_aent_destroy(&vs_native); 916 } 917 if (error != 0) 918 break; 919 920 if (cmd == NFS4ATTR_GETIT) { 921 na->acl.fattr4_acl_len = vs_ace4.vsa_aclcnt; 922 /* see case NFS4ATTR_FREEIT for this being freed */ 923 na->acl.fattr4_acl_val = vs_ace4.vsa_aclentp; 924 } else { 925 if (na->acl.fattr4_acl_len != vs_ace4.vsa_aclcnt) 926 error = -1; /* no match */ 927 else if (ln_ace4_cmp(na->acl.fattr4_acl_val, 928 vs_ace4.vsa_aclentp, 929 vs_ace4.vsa_aclcnt) != 0) 930 error = -1; /* no match */ 931 } 932 933 break; 934 935 case NFS4ATTR_SETIT: 936 if (sarg->rdattr_error && (vp == NULL)) { 937 return (-1); 938 } 939 ASSERT(vp != NULL); 940 941 /* prepare vs_ace4 from fattr4 data */ 942 bzero(&vs_ace4, sizeof (vs_ace4)); 943 vs_ace4.vsa_mask = VSA_ACE | VSA_ACECNT; 944 vs_ace4.vsa_aclcnt = na->acl.fattr4_acl_len; 945 vs_ace4.vsa_aclentp = na->acl.fattr4_acl_val; 946 947 /* make sure we have correct owner/group */ 948 if ((vap->va_mask & (AT_UID | AT_GID)) != 949 (AT_UID | AT_GID)) { 950 vap = &va; 951 vap->va_mask = AT_UID | AT_GID; 952 status = rfs4_vop_getattr(vp, 953 vap, 0, sarg->cs->cr); 954 if (status != NFS4_OK) 955 return (geterrno4(status)); 956 } 957 958 /* see which ACLs the fs supports */ 959 error = VOP_PATHCONF(vp, _PC_ACL_ENABLED, &whichacl, 960 sarg->cs->cr); 961 if (error != 0) { 962 /* 963 * If we got an error, then the filesystem 964 * likely does not understand the _PC_ACL_ENABLED 965 * pathconf. In this case, we fall back to trying 966 * POSIX-draft (aka UFS-style) ACLs, since that's 967 * the behavior used by earlier version of NFS. 968 */ 969 error = 0; 970 whichacl = _ACL_ACLENT_ENABLED; 971 } 972 973 if (!(whichacl & (_ACL_ACLENT_ENABLED | _ACL_ACE_ENABLED))) { 974 /* 975 * If the file system supports neither ACE nor 976 * ACLENT ACLs we will fall back to UFS-style ACLs 977 * like we did above if there was an error upon 978 * calling VOP_PATHCONF. 979 * 980 * ACE and ACLENT type ACLs are the only interfaces 981 * supported thus far. If any other bits are set on 982 * 'whichacl' upon return from VOP_PATHCONF, we will 983 * ignore them. 984 */ 985 whichacl = _ACL_ACLENT_ENABLED; 986 } 987 988 if (whichacl & _ACL_ACE_ENABLED) { 989 error = vs_ace4_to_acet(&vs_ace4, &vs_native, 990 vap->va_uid, vap->va_gid, TRUE, FALSE); 991 if (error != 0) 992 break; 993 (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL); 994 error = VOP_SETSECATTR(vp, &vs_native, 995 0, sarg->cs->cr); 996 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL); 997 vs_acet_destroy(&vs_native); 998 } else if (whichacl & _ACL_ACLENT_ENABLED) { 999 error = vs_ace4_to_aent(&vs_ace4, &vs_native, 1000 vap->va_uid, vap->va_gid, vp->v_type == VDIR, TRUE, 1001 FALSE); 1002 if (error != 0) 1003 break; 1004 (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL); 1005 error = VOP_SETSECATTR(vp, &vs_native, 1006 0, sarg->cs->cr); 1007 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL); 1008 vs_aent_destroy(&vs_native); 1009 } 1010 break; 1011 1012 case NFS4ATTR_FREEIT: 1013 if (sarg->op == NFS4ATTR_GETIT) { 1014 vs_ace4.vsa_mask = VSA_ACE | VSA_ACECNT; 1015 vs_ace4.vsa_aclcnt = na->acl.fattr4_acl_len; 1016 vs_ace4.vsa_aclentp = na->acl.fattr4_acl_val; 1017 vs_ace4_destroy(&vs_ace4); 1018 } 1019 break; 1020 } 1021 1022 return (error); 1023 } 1024 1025 /* ARGSUSED */ 1026 static int 1027 rfs4_fattr4_aclsupport(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1028 union nfs4_attr_u *na) 1029 { 1030 int error = 0; 1031 1032 if (RFS4_MANDATTR_ONLY) 1033 return (ENOTSUP); 1034 1035 switch (cmd) { 1036 case NFS4ATTR_SUPPORTED: 1037 if (sarg->op == NFS4ATTR_SETIT) 1038 error = EINVAL; 1039 break; /* supported */ 1040 case NFS4ATTR_GETIT: 1041 na->aclsupport = ACL4_SUPPORT_ALLOW_ACL | 1042 ACL4_SUPPORT_DENY_ACL; 1043 break; 1044 case NFS4ATTR_SETIT: 1045 error = EINVAL; 1046 break; 1047 case NFS4ATTR_VERIT: 1048 if (na->aclsupport != (ACL4_SUPPORT_ALLOW_ACL | 1049 ACL4_SUPPORT_DENY_ACL)) 1050 error = -1; /* no match */ 1051 break; 1052 } 1053 1054 return (error); 1055 } 1056 1057 /* ARGSUSED */ 1058 static int 1059 rfs4_fattr4_archive(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1060 union nfs4_attr_u *na) 1061 { 1062 return (ENOTSUP); 1063 } 1064 1065 /* ARGSUSED */ 1066 static int 1067 rfs4_fattr4_cansettime(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1068 union nfs4_attr_u *na) 1069 { 1070 int error = 0; 1071 1072 if (RFS4_MANDATTR_ONLY) 1073 return (ENOTSUP); 1074 1075 switch (cmd) { 1076 case NFS4ATTR_SUPPORTED: 1077 if (sarg->op == NFS4ATTR_SETIT) 1078 error = EINVAL; 1079 break; /* this attr is supported */ 1080 case NFS4ATTR_GETIT: 1081 na->cansettime = TRUE; 1082 break; 1083 case NFS4ATTR_SETIT: 1084 /* 1085 * read-only attr 1086 */ 1087 error = EINVAL; 1088 break; 1089 case NFS4ATTR_VERIT: 1090 if (!na->cansettime) 1091 error = -1; /* no match */ 1092 break; 1093 case NFS4ATTR_FREEIT: 1094 break; 1095 } 1096 return (error); 1097 } 1098 1099 /* 1100 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports 1101 * case insenstive. 1102 */ 1103 /* ARGSUSED */ 1104 static int 1105 rfs4_fattr4_case_insensitive(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1106 union nfs4_attr_u *na) 1107 { 1108 int error = 0; 1109 1110 if (RFS4_MANDATTR_ONLY) 1111 return (ENOTSUP); 1112 1113 switch (cmd) { 1114 case NFS4ATTR_SUPPORTED: 1115 if (sarg->op == NFS4ATTR_SETIT) 1116 error = EINVAL; 1117 break; /* this attr is supported */ 1118 case NFS4ATTR_GETIT: 1119 na->case_insensitive = FALSE; 1120 break; 1121 case NFS4ATTR_SETIT: 1122 /* 1123 * read-only attr 1124 */ 1125 error = EINVAL; 1126 break; 1127 case NFS4ATTR_VERIT: 1128 if (!na->case_insensitive) 1129 error = -1; /* no match */ 1130 break; 1131 case NFS4ATTR_FREEIT: 1132 break; 1133 } 1134 return (error); 1135 } 1136 1137 /* ARGSUSED */ 1138 static int 1139 rfs4_fattr4_case_preserving(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1140 union nfs4_attr_u *na) 1141 { 1142 int error = 0; 1143 1144 if (RFS4_MANDATTR_ONLY) 1145 return (ENOTSUP); 1146 1147 switch (cmd) { 1148 case NFS4ATTR_SUPPORTED: 1149 if (sarg->op == NFS4ATTR_SETIT) 1150 error = EINVAL; 1151 break; /* this attr is supported */ 1152 case NFS4ATTR_GETIT: 1153 na->case_preserving = TRUE; 1154 break; 1155 case NFS4ATTR_SETIT: 1156 /* 1157 * read-only attr 1158 */ 1159 error = EINVAL; 1160 break; 1161 case NFS4ATTR_VERIT: 1162 if (!na->case_preserving) 1163 error = -1; /* no match */ 1164 break; 1165 case NFS4ATTR_FREEIT: 1166 break; 1167 } 1168 return (error); 1169 } 1170 1171 /* fattr4_chown_restricted should reall be fattr4_chown_allowed */ 1172 /* ARGSUSED */ 1173 static int 1174 rfs4_fattr4_chown_restricted(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1175 union nfs4_attr_u *na) 1176 { 1177 int error = 0; 1178 ulong_t val; 1179 1180 if (RFS4_MANDATTR_ONLY) 1181 return (ENOTSUP); 1182 1183 switch (cmd) { 1184 case NFS4ATTR_SUPPORTED: 1185 if (sarg->op == NFS4ATTR_SETIT) 1186 error = EINVAL; 1187 break; /* this attr is supported */ 1188 case NFS4ATTR_GETIT: 1189 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) { 1190 error = -1; /* may be okay if rdattr_error */ 1191 break; 1192 } 1193 ASSERT(sarg->cs->vp != NULL); 1194 error = VOP_PATHCONF(sarg->cs->vp, 1195 _PC_CHOWN_RESTRICTED, &val, sarg->cs->cr); 1196 if (error) 1197 break; 1198 1199 na->chown_restricted = (val == 1); 1200 break; 1201 case NFS4ATTR_SETIT: 1202 /* 1203 * read-only attr 1204 */ 1205 error = EINVAL; 1206 break; 1207 case NFS4ATTR_VERIT: 1208 ASSERT(sarg->cs->vp != NULL); 1209 error = VOP_PATHCONF(sarg->cs->vp, 1210 _PC_CHOWN_RESTRICTED, &val, sarg->cs->cr); 1211 if (error) 1212 break; 1213 if (na->chown_restricted != (val == 1)) 1214 error = -1; /* no match */ 1215 break; 1216 case NFS4ATTR_FREEIT: 1217 break; 1218 } 1219 return (error); 1220 } 1221 1222 /* ARGSUSED */ 1223 static int 1224 rfs4_fattr4_fileid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1225 union nfs4_attr_u *na) 1226 { 1227 int error = 0; 1228 1229 if (RFS4_MANDATTR_ONLY) 1230 return (ENOTSUP); 1231 1232 switch (cmd) { 1233 case NFS4ATTR_SUPPORTED: 1234 if (sarg->op == NFS4ATTR_SETIT) 1235 error = EINVAL; 1236 break; /* this attr is supported */ 1237 case NFS4ATTR_GETIT: 1238 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_NODEID)) { 1239 error = -1; /* may be okay if rdattr_error */ 1240 break; 1241 } 1242 ASSERT(sarg->vap->va_mask & AT_NODEID); 1243 na->fileid = sarg->vap->va_nodeid; 1244 break; 1245 case NFS4ATTR_SETIT: 1246 /* 1247 * read-only attr 1248 */ 1249 error = EINVAL; 1250 break; 1251 case NFS4ATTR_VERIT: 1252 ASSERT(sarg->vap->va_mask & AT_NODEID); 1253 if (sarg->vap->va_nodeid != na->fileid) 1254 error = -1; /* no match */ 1255 break; 1256 case NFS4ATTR_FREEIT: 1257 break; 1258 } 1259 return (error); 1260 } 1261 1262 /* ARGSUSED */ 1263 static int 1264 rfs4_get_mntdfileid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg) 1265 { 1266 int error = 0; 1267 vattr_t *vap, va; 1268 vnode_t *stubvp = NULL, *vp; 1269 1270 vp = sarg->cs->vp; 1271 sarg->mntdfid_set = FALSE; 1272 1273 /* VROOT object, must untraverse */ 1274 if (vp->v_flag & VROOT) { 1275 1276 /* extra hold for vp since untraverse might rele */ 1277 VN_HOLD(vp); 1278 stubvp = untraverse(vp); 1279 1280 /* 1281 * If vp/stubvp are same, we must be at system 1282 * root because untraverse returned same vp 1283 * for a VROOT object. sarg->vap was setup 1284 * before we got here, so there's no need to do 1285 * another getattr -- just use the one in sarg. 1286 */ 1287 if (VN_CMP(vp, stubvp)) { 1288 ASSERT(VN_CMP(vp, rootdir)); 1289 vap = sarg->vap; 1290 } else { 1291 va.va_mask = AT_NODEID; 1292 vap = &va; 1293 error = rfs4_vop_getattr(stubvp, vap, 0, sarg->cs->cr); 1294 } 1295 1296 /* 1297 * Done with stub, time to rele. If vp and stubvp 1298 * were the same, then we need to rele either vp or 1299 * stubvp. If they weren't the same, then untraverse() 1300 * already took case of the extra hold on vp, and only 1301 * the stub needs to be rele'd. Both cases are handled 1302 * by unconditionally rele'ing the stub. 1303 */ 1304 VN_RELE(stubvp); 1305 } else 1306 vap = sarg->vap; 1307 1308 /* 1309 * At this point, vap should contain "correct" AT_NODEID -- 1310 * (for V_ROOT case, nodeid of stub, for non-VROOT case, 1311 * nodeid of vp). If error or AT_NODEID not available, then 1312 * make the obligatory (yet mysterious) rdattr_error 1313 * check that is so common in the attr code. 1314 */ 1315 if (!error && (vap->va_mask & AT_NODEID)) { 1316 sarg->mounted_on_fileid = vap->va_nodeid; 1317 sarg->mntdfid_set = TRUE; 1318 } else if (sarg->rdattr_error) 1319 error = -1; 1320 1321 /* 1322 * error describes these cases: 1323 * 0 : success 1324 * -1: failure due to previous attr processing error (rddir only). 1325 * * : new attr failure (if rddir, caller will set rdattr_error) 1326 */ 1327 return (error); 1328 } 1329 1330 /* ARGSUSED */ 1331 static int 1332 rfs4_fattr4_mounted_on_fileid(nfs4_attr_cmd_t cmd, 1333 struct nfs4_svgetit_arg *sarg, union nfs4_attr_u *na) 1334 { 1335 int error = 0; 1336 1337 if (RFS4_MANDATTR_ONLY) 1338 return (ENOTSUP); 1339 1340 switch (cmd) { 1341 case NFS4ATTR_SUPPORTED: 1342 if (sarg->op == NFS4ATTR_SETIT) 1343 error = EINVAL; 1344 break; /* this attr is supported */ 1345 case NFS4ATTR_GETIT: 1346 case NFS4ATTR_VERIT: 1347 if (! sarg->mntdfid_set) 1348 error = rfs4_get_mntdfileid(cmd, sarg); 1349 1350 if (! error && sarg->mntdfid_set) { 1351 if (cmd == NFS4ATTR_GETIT) 1352 na->mounted_on_fileid = sarg->mounted_on_fileid; 1353 else 1354 if (na->mounted_on_fileid != 1355 sarg->mounted_on_fileid) 1356 error = -1; 1357 } 1358 break; 1359 case NFS4ATTR_SETIT: 1360 /* read-only attr */ 1361 error = EINVAL; 1362 break; 1363 case NFS4ATTR_FREEIT: 1364 break; 1365 } 1366 return (error); 1367 } 1368 1369 /* ARGSUSED */ 1370 static int 1371 rfs4_fattr4_files_avail(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1372 union nfs4_attr_u *na) 1373 { 1374 int error = 0; 1375 1376 if (RFS4_MANDATTR_ONLY) 1377 return (ENOTSUP); 1378 1379 switch (cmd) { 1380 case NFS4ATTR_SUPPORTED: 1381 if (sarg->op == NFS4ATTR_SETIT) 1382 error = EINVAL; 1383 break; /* this attr is supported */ 1384 case NFS4ATTR_GETIT: 1385 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 1386 error = -1; /* may be okay if rdattr_error */ 1387 break; 1388 } 1389 ASSERT(sarg->sbp != NULL); 1390 na->files_avail = sarg->sbp->f_favail; 1391 break; 1392 case NFS4ATTR_SETIT: 1393 /* 1394 * read-only attr 1395 */ 1396 error = EINVAL; 1397 break; 1398 case NFS4ATTR_VERIT: 1399 ASSERT(sarg->sbp != NULL); 1400 if (sarg->sbp->f_favail != na->files_avail) 1401 error = -1; /* no match */ 1402 break; 1403 case NFS4ATTR_FREEIT: 1404 break; 1405 } 1406 return (error); 1407 } 1408 1409 /* ARGSUSED */ 1410 static int 1411 rfs4_fattr4_files_free(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1412 union nfs4_attr_u *na) 1413 { 1414 int error = 0; 1415 1416 if (RFS4_MANDATTR_ONLY) 1417 return (ENOTSUP); 1418 1419 switch (cmd) { 1420 case NFS4ATTR_SUPPORTED: 1421 if (sarg->op == NFS4ATTR_SETIT) 1422 error = EINVAL; 1423 break; /* this attr is supported */ 1424 case NFS4ATTR_GETIT: 1425 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 1426 error = -1; /* may be okay if rdattr_error */ 1427 break; 1428 } 1429 ASSERT(sarg->sbp != NULL); 1430 na->files_free = sarg->sbp->f_ffree; 1431 break; 1432 case NFS4ATTR_SETIT: 1433 /* 1434 * read-only attr 1435 */ 1436 error = EINVAL; 1437 break; 1438 case NFS4ATTR_VERIT: 1439 ASSERT(sarg->sbp != NULL); 1440 if (sarg->sbp->f_ffree != na->files_free) 1441 error = -1; /* no match */ 1442 break; 1443 case NFS4ATTR_FREEIT: 1444 break; 1445 } 1446 return (error); 1447 } 1448 1449 /* ARGSUSED */ 1450 static int 1451 rfs4_fattr4_files_total(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1452 union nfs4_attr_u *na) 1453 { 1454 int error = 0; 1455 1456 if (RFS4_MANDATTR_ONLY) 1457 return (ENOTSUP); 1458 1459 switch (cmd) { 1460 case NFS4ATTR_SUPPORTED: 1461 if (sarg->op == NFS4ATTR_SETIT) 1462 error = EINVAL; 1463 break; /* this attr is supported */ 1464 case NFS4ATTR_GETIT: 1465 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 1466 error = -1; /* may be okay if rdattr_error */ 1467 break; 1468 } 1469 ASSERT(sarg->sbp != NULL); 1470 na->files_total = sarg->sbp->f_files; 1471 break; 1472 case NFS4ATTR_SETIT: 1473 /* 1474 * read-only attr 1475 */ 1476 error = EINVAL; 1477 break; 1478 case NFS4ATTR_VERIT: 1479 ASSERT(sarg->sbp != NULL); 1480 if (sarg->sbp->f_files != na->files_total) 1481 error = -1; /* no match */ 1482 break; 1483 case NFS4ATTR_FREEIT: 1484 break; 1485 } 1486 return (error); 1487 } 1488 1489 /* ARGSUSED */ 1490 static int 1491 rfs4_fattr4_fs_locations(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1492 union nfs4_attr_u *na) 1493 { 1494 return (ENOTSUP); 1495 } 1496 1497 /* ARGSUSED */ 1498 static int 1499 rfs4_fattr4_hidden(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1500 union nfs4_attr_u *na) 1501 { 1502 return (ENOTSUP); 1503 } 1504 1505 /* ARGSUSED */ 1506 static int 1507 rfs4_fattr4_homogeneous(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1508 union nfs4_attr_u *na) 1509 { 1510 int error = 0; 1511 1512 if (RFS4_MANDATTR_ONLY) 1513 return (ENOTSUP); 1514 1515 switch (cmd) { 1516 case NFS4ATTR_SUPPORTED: 1517 if (sarg->op == NFS4ATTR_SETIT) 1518 error = EINVAL; 1519 break; /* this attr is supported */ 1520 case NFS4ATTR_GETIT: 1521 na->homogeneous = TRUE; /* XXX - need a VOP extension */ 1522 break; 1523 case NFS4ATTR_SETIT: 1524 /* 1525 * read-only attr 1526 */ 1527 error = EINVAL; 1528 break; 1529 case NFS4ATTR_VERIT: 1530 if (!na->homogeneous) 1531 error = -1; /* no match */ 1532 break; 1533 case NFS4ATTR_FREEIT: 1534 break; 1535 } 1536 return (error); 1537 } 1538 1539 /* ARGSUSED */ 1540 static int 1541 rfs4_fattr4_maxfilesize(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1542 union nfs4_attr_u *na) 1543 { 1544 int error = 0; 1545 ulong_t val; 1546 fattr4_maxfilesize maxfilesize; 1547 1548 if (RFS4_MANDATTR_ONLY) 1549 return (ENOTSUP); 1550 1551 switch (cmd) { 1552 case NFS4ATTR_SUPPORTED: 1553 if (sarg->op == NFS4ATTR_SETIT) 1554 error = EINVAL; 1555 break; /* this attr is supported */ 1556 case NFS4ATTR_GETIT: 1557 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) { 1558 error = -1; /* may be okay if rdattr_error */ 1559 break; 1560 } 1561 ASSERT(sarg->cs->vp != NULL); 1562 error = VOP_PATHCONF(sarg->cs->vp, _PC_FILESIZEBITS, &val, 1563 sarg->cs->cr); 1564 if (error) 1565 break; 1566 if (val >= (sizeof (uint64_t) * 8)) 1567 na->maxfilesize = UINT64_MAX; 1568 else 1569 na->maxfilesize = ((1LL << val) - 1); 1570 break; 1571 case NFS4ATTR_SETIT: 1572 /* 1573 * read-only attr 1574 */ 1575 error = EINVAL; 1576 break; 1577 case NFS4ATTR_VERIT: 1578 ASSERT(sarg->cs->vp != NULL); 1579 error = VOP_PATHCONF(sarg->cs->vp, _PC_FILESIZEBITS, &val, 1580 sarg->cs->cr); 1581 if (error) 1582 break; 1583 if (val >= (sizeof (uint64_t) * 8)) 1584 maxfilesize = UINT64_MAX; 1585 else 1586 maxfilesize = ((1LL << val) - 1); 1587 if (na->maxfilesize != maxfilesize) 1588 error = -1; /* no match */ 1589 break; 1590 case NFS4ATTR_FREEIT: 1591 break; 1592 } 1593 return (error); 1594 } 1595 1596 /* ARGSUSED */ 1597 static int 1598 rfs4_fattr4_maxlink(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1599 union nfs4_attr_u *na) 1600 { 1601 int error = 0; 1602 ulong_t val; 1603 1604 if (RFS4_MANDATTR_ONLY) 1605 return (ENOTSUP); 1606 1607 switch (cmd) { 1608 case NFS4ATTR_SUPPORTED: 1609 if (sarg->op == NFS4ATTR_SETIT) 1610 error = EINVAL; 1611 break; /* this attr is supported */ 1612 case NFS4ATTR_GETIT: 1613 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) { 1614 error = -1; /* may be okay if rdattr_error */ 1615 break; 1616 } 1617 ASSERT(sarg->cs->vp != NULL); 1618 error = VOP_PATHCONF(sarg->cs->vp, _PC_LINK_MAX, &val, 1619 sarg->cs->cr); 1620 if (error == 0) { 1621 na->maxlink = val; 1622 } 1623 break; 1624 case NFS4ATTR_SETIT: 1625 /* 1626 * read-only attr 1627 */ 1628 error = EINVAL; 1629 break; 1630 case NFS4ATTR_VERIT: 1631 ASSERT(sarg->cs->vp != NULL); 1632 error = VOP_PATHCONF(sarg->cs->vp, _PC_LINK_MAX, &val, 1633 sarg->cs->cr); 1634 if (!error && (na->maxlink != val)) 1635 error = -1; /* no match */ 1636 break; 1637 case NFS4ATTR_FREEIT: 1638 break; 1639 } 1640 return (error); 1641 } 1642 1643 /* ARGSUSED */ 1644 static int 1645 rfs4_fattr4_maxname(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1646 union nfs4_attr_u *na) 1647 { 1648 int error = 0; 1649 ulong_t val; 1650 1651 if (RFS4_MANDATTR_ONLY) 1652 return (ENOTSUP); 1653 1654 switch (cmd) { 1655 case NFS4ATTR_SUPPORTED: 1656 if (sarg->op == NFS4ATTR_SETIT) 1657 error = EINVAL; 1658 break; /* this attr is supported */ 1659 case NFS4ATTR_GETIT: 1660 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) { 1661 error = -1; /* may be okay if rdattr_error */ 1662 break; 1663 } 1664 ASSERT(sarg->cs->vp != NULL); 1665 error = VOP_PATHCONF(sarg->cs->vp, _PC_NAME_MAX, &val, 1666 sarg->cs->cr); 1667 if (error == 0) { 1668 na->maxname = val; 1669 } 1670 break; 1671 case NFS4ATTR_SETIT: 1672 /* 1673 * read-only attr 1674 */ 1675 error = EINVAL; 1676 break; 1677 case NFS4ATTR_VERIT: 1678 ASSERT(sarg->cs->vp != NULL); 1679 error = VOP_PATHCONF(sarg->cs->vp, _PC_NAME_MAX, &val, 1680 sarg->cs->cr); 1681 if (!error && (na->maxname != val)) 1682 error = -1; /* no match */ 1683 break; 1684 case NFS4ATTR_FREEIT: 1685 break; 1686 } 1687 return (error); 1688 } 1689 1690 /* ARGSUSED */ 1691 static int 1692 rfs4_fattr4_maxread(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1693 union nfs4_attr_u *na) 1694 { 1695 int error = 0; 1696 1697 if (RFS4_MANDATTR_ONLY) 1698 return (ENOTSUP); 1699 1700 switch (cmd) { 1701 case NFS4ATTR_SUPPORTED: 1702 if (sarg->op == NFS4ATTR_SETIT) 1703 error = EINVAL; 1704 break; /* this attr is supported */ 1705 case NFS4ATTR_GETIT: 1706 na->maxread = rfs4_tsize(sarg->cs->req); 1707 break; 1708 case NFS4ATTR_SETIT: 1709 /* 1710 * read-only attr 1711 */ 1712 error = EINVAL; 1713 break; 1714 case NFS4ATTR_VERIT: 1715 if (na->maxread != rfs4_tsize(sarg->cs->req)) 1716 error = -1; /* no match */ 1717 break; 1718 case NFS4ATTR_FREEIT: 1719 break; 1720 } 1721 return (error); 1722 } 1723 1724 /* ARGSUSED */ 1725 static int 1726 rfs4_fattr4_maxwrite(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1727 union nfs4_attr_u *na) 1728 { 1729 int error = 0; 1730 1731 if (RFS4_MANDATTR_ONLY) 1732 return (ENOTSUP); 1733 1734 switch (cmd) { 1735 case NFS4ATTR_SUPPORTED: 1736 if (sarg->op == NFS4ATTR_SETIT) 1737 error = EINVAL; 1738 break; /* this attr is supported */ 1739 case NFS4ATTR_GETIT: 1740 na->maxwrite = rfs4_tsize(sarg->cs->req); 1741 break; 1742 case NFS4ATTR_SETIT: 1743 /* 1744 * read-only attr 1745 */ 1746 error = EINVAL; 1747 break; 1748 case NFS4ATTR_VERIT: 1749 if (na->maxwrite != rfs4_tsize(sarg->cs->req)) 1750 error = -1; /* no match */ 1751 break; 1752 case NFS4ATTR_FREEIT: 1753 break; 1754 } 1755 return (error); 1756 } 1757 1758 /* ARGSUSED */ 1759 static int 1760 rfs4_fattr4_mimetype(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1761 union nfs4_attr_u *na) 1762 { 1763 return (ENOTSUP); 1764 } 1765 1766 /* ARGSUSED */ 1767 static int 1768 rfs4_fattr4_mode(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1769 union nfs4_attr_u *na) 1770 { 1771 int error = 0; 1772 1773 if (RFS4_MANDATTR_ONLY) 1774 return (ENOTSUP); 1775 1776 switch (cmd) { 1777 case NFS4ATTR_SUPPORTED: 1778 break; /* this attr is supported */ 1779 case NFS4ATTR_GETIT: 1780 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_MODE)) { 1781 error = -1; /* may be okay if rdattr_error */ 1782 break; 1783 } 1784 ASSERT(sarg->vap->va_mask & AT_MODE); 1785 na->mode = sarg->vap->va_mode; 1786 break; 1787 case NFS4ATTR_SETIT: 1788 ASSERT(sarg->vap->va_mask & AT_MODE); 1789 sarg->vap->va_mode = na->mode; 1790 /* 1791 * If the filesystem is exported with nosuid, then mask off 1792 * the setuid and setgid bits. 1793 */ 1794 if (sarg->cs->vp->v_type == VREG && 1795 (sarg->cs->exi->exi_export.ex_flags & EX_NOSUID)) 1796 sarg->vap->va_mode &= ~(VSUID | VSGID); 1797 break; 1798 case NFS4ATTR_VERIT: 1799 ASSERT(sarg->vap->va_mask & AT_MODE); 1800 if (sarg->vap->va_mode != na->mode) 1801 error = -1; /* no match */ 1802 break; 1803 case NFS4ATTR_FREEIT: 1804 break; 1805 } 1806 return (error); 1807 } 1808 1809 /* ARGSUSED */ 1810 static int 1811 rfs4_fattr4_no_trunc(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1812 union nfs4_attr_u *na) 1813 { 1814 int error = 0; 1815 1816 if (RFS4_MANDATTR_ONLY) 1817 return (ENOTSUP); 1818 1819 switch (cmd) { 1820 case NFS4ATTR_SUPPORTED: 1821 if (sarg->op == NFS4ATTR_SETIT) 1822 error = EINVAL; 1823 break; /* this attr is supported */ 1824 case NFS4ATTR_GETIT: 1825 na->no_trunc = TRUE; 1826 break; 1827 case NFS4ATTR_SETIT: 1828 /* 1829 * read-only attr 1830 */ 1831 error = EINVAL; 1832 break; 1833 case NFS4ATTR_VERIT: 1834 if (!na->no_trunc) 1835 error = -1; /* no match */ 1836 break; 1837 case NFS4ATTR_FREEIT: 1838 break; 1839 } 1840 return (error); 1841 } 1842 1843 /* ARGSUSED */ 1844 static int 1845 rfs4_fattr4_numlinks(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1846 union nfs4_attr_u *na) 1847 { 1848 int error = 0; 1849 1850 if (RFS4_MANDATTR_ONLY) 1851 return (ENOTSUP); 1852 1853 switch (cmd) { 1854 case NFS4ATTR_SUPPORTED: 1855 if (sarg->op == NFS4ATTR_SETIT) 1856 error = EINVAL; 1857 break; /* this attr is supported */ 1858 case NFS4ATTR_GETIT: 1859 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_NLINK)) { 1860 error = -1; /* may be okay if rdattr_error */ 1861 break; 1862 } 1863 ASSERT(sarg->vap->va_mask & AT_NLINK); 1864 na->numlinks = sarg->vap->va_nlink; 1865 break; 1866 case NFS4ATTR_SETIT: 1867 /* 1868 * read-only attr 1869 */ 1870 error = EINVAL; 1871 break; 1872 case NFS4ATTR_VERIT: 1873 ASSERT(sarg->vap->va_mask & AT_NLINK); 1874 if (sarg->vap->va_nlink != na->numlinks) 1875 error = -1; /* no match */ 1876 break; 1877 case NFS4ATTR_FREEIT: 1878 break; 1879 } 1880 return (error); 1881 } 1882 1883 /* ARGSUSED */ 1884 static int 1885 rfs4_fattr4_owner(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1886 union nfs4_attr_u *na) 1887 { 1888 int error = 0; 1889 uid_t uid; 1890 1891 if (RFS4_MANDATTR_ONLY) 1892 return (ENOTSUP); 1893 1894 switch (cmd) { 1895 case NFS4ATTR_SUPPORTED: 1896 break; /* this attr is supported */ 1897 case NFS4ATTR_GETIT: 1898 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_UID)) { 1899 error = -1; /* may be okay if rdattr_error */ 1900 break; 1901 } 1902 ASSERT(sarg->vap->va_mask & AT_UID); 1903 1904 /* 1905 * There are well defined polices for what happens on server- 1906 * side GETATTR when uid to attribute string conversion cannot 1907 * occur. Please refer to nfs4_idmap.c for details. 1908 */ 1909 error = nfs_idmap_uid_str(sarg->vap->va_uid, &na->owner, TRUE); 1910 switch (error) { 1911 case ECONNREFUSED: 1912 error = NFS4ERR_DELAY; 1913 break; 1914 default: 1915 break; 1916 } 1917 break; 1918 1919 case NFS4ATTR_SETIT: 1920 ASSERT(sarg->vap->va_mask & AT_UID); 1921 1922 /* 1923 * There are well defined policies for what happens on server- 1924 * side SETATTR of 'owner' when a "user@domain" mapping cannot 1925 * occur. Please refer to nfs4_idmap.c for details. 1926 * 1927 * Any other errors, such as the mapping not being found by 1928 * nfsmapid(1m), and interrupted clnt_call, etc, will result 1929 * in NFS4ERR_BADOWNER. 1930 * 1931 * XXX need to return consistent errors, perhaps all 1932 * server side attribute routines should return NFS4ERR*. 1933 */ 1934 error = nfs_idmap_str_uid(&na->owner, &sarg->vap->va_uid, TRUE); 1935 switch (error) { 1936 case NFS4_OK: 1937 case ENOTSUP: 1938 /* 1939 * Ignore warning that we are the 1940 * nfsmapid (can't happen on srv) 1941 */ 1942 error = 0; 1943 MSG_PRT_DEBUG = FALSE; 1944 break; 1945 1946 case ECOMM: 1947 case ECONNREFUSED: 1948 if (!MSG_PRT_DEBUG) { 1949 /* 1950 * printed just once per daemon death, 1951 * inform the user and then stay silent 1952 */ 1953 cmn_err(CE_WARN, "!Unable to contact " 1954 "nfsmapid"); 1955 MSG_PRT_DEBUG = TRUE; 1956 } 1957 error = NFS4ERR_DELAY; 1958 break; 1959 1960 case EINVAL: 1961 error = NFS4ERR_INVAL; 1962 break; 1963 1964 default: 1965 error = NFS4ERR_BADOWNER; 1966 break; 1967 } 1968 break; 1969 1970 case NFS4ATTR_VERIT: 1971 ASSERT(sarg->vap->va_mask & AT_UID); 1972 error = nfs_idmap_str_uid(&na->owner, &uid, TRUE); 1973 /* 1974 * Ignore warning that we are the nfsmapid (can't happen on srv) 1975 */ 1976 if (error == ENOTSUP) 1977 error = 0; 1978 if (error) 1979 error = -1; /* no match */ 1980 else if (sarg->vap->va_uid != uid) 1981 error = -1; /* no match */ 1982 break; 1983 case NFS4ATTR_FREEIT: 1984 if (sarg->op == NFS4ATTR_GETIT) { 1985 if (na->owner.utf8string_val) { 1986 UTF8STRING_FREE(na->owner) 1987 bzero(&na->owner, sizeof (na->owner)); 1988 } 1989 } 1990 break; 1991 } 1992 return (error); 1993 } 1994 1995 /* ARGSUSED */ 1996 static int 1997 rfs4_fattr4_owner_group(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1998 union nfs4_attr_u *na) 1999 { 2000 int error = 0; 2001 gid_t gid; 2002 2003 if (RFS4_MANDATTR_ONLY) 2004 return (ENOTSUP); 2005 2006 switch (cmd) { 2007 case NFS4ATTR_SUPPORTED: 2008 break; /* this attr is supported */ 2009 case NFS4ATTR_GETIT: 2010 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_GID)) { 2011 error = -1; /* may be okay if rdattr_error */ 2012 break; 2013 } 2014 ASSERT(sarg->vap->va_mask & AT_GID); 2015 2016 /* 2017 * There are well defined polices for what happens on server- 2018 * side GETATTR when gid to attribute string conversion cannot 2019 * occur. Please refer to nfs4_idmap.c for details. 2020 */ 2021 error = nfs_idmap_gid_str(sarg->vap->va_gid, &na->owner_group, 2022 TRUE); 2023 switch (error) { 2024 case ECONNREFUSED: 2025 error = NFS4ERR_DELAY; 2026 break; 2027 default: 2028 break; 2029 } 2030 break; 2031 2032 case NFS4ATTR_SETIT: 2033 ASSERT(sarg->vap->va_mask & AT_GID); 2034 2035 /* 2036 * There are well defined policies for what happens on server- 2037 * side SETATTR of 'owner_group' when a "group@domain" mapping 2038 * cannot occur. Please refer to nfs4_idmap.c for details. 2039 * 2040 * Any other errors, such as the mapping not being found by 2041 * nfsmapid(1m), and interrupted clnt_call, etc, will result 2042 * in NFS4ERR_BADOWNER. 2043 * 2044 * XXX need to return consistent errors, perhaps all 2045 * server side attribute routines should return NFS4ERR*. 2046 */ 2047 error = nfs_idmap_str_gid(&na->owner_group, &sarg->vap->va_gid, 2048 TRUE); 2049 switch (error) { 2050 case NFS4_OK: 2051 case ENOTSUP: 2052 /* 2053 * Ignore warning that we are the 2054 * nfsmapid (can't happen on srv) 2055 */ 2056 error = 0; 2057 MSG_PRT_DEBUG = FALSE; 2058 break; 2059 2060 case ECOMM: 2061 case ECONNREFUSED: 2062 if (!MSG_PRT_DEBUG) { 2063 /* 2064 * printed just once per daemon death, 2065 * inform the user and then stay silent 2066 */ 2067 cmn_err(CE_WARN, "!Unable to contact " 2068 "nfsmapid"); 2069 MSG_PRT_DEBUG = TRUE; 2070 } 2071 error = NFS4ERR_DELAY; 2072 break; 2073 2074 case EINVAL: 2075 error = NFS4ERR_INVAL; 2076 break; 2077 2078 default: 2079 error = NFS4ERR_BADOWNER; 2080 break; 2081 } 2082 break; 2083 2084 case NFS4ATTR_VERIT: 2085 ASSERT(sarg->vap->va_mask & AT_GID); 2086 error = nfs_idmap_str_gid(&na->owner_group, &gid, TRUE); 2087 /* 2088 * Ignore warning that we are the nfsmapid (can't happen on srv) 2089 */ 2090 if (error == ENOTSUP) 2091 error = 0; 2092 if (error) 2093 error = -1; /* no match */ 2094 else if (sarg->vap->va_gid != gid) 2095 error = -1; /* no match */ 2096 break; 2097 case NFS4ATTR_FREEIT: 2098 if (sarg->op == NFS4ATTR_GETIT) { 2099 if (na->owner_group.utf8string_val) { 2100 UTF8STRING_FREE(na->owner_group) 2101 bzero(&na->owner_group, 2102 sizeof (na->owner_group)); 2103 } 2104 } 2105 break; 2106 } 2107 return (error); 2108 } 2109 2110 /* XXX - quota attributes should be supportable on Solaris 2 */ 2111 /* ARGSUSED */ 2112 static int 2113 rfs4_fattr4_quota_avail_hard(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2114 union nfs4_attr_u *na) 2115 { 2116 return (ENOTSUP); 2117 } 2118 2119 /* ARGSUSED */ 2120 static int 2121 rfs4_fattr4_quota_avail_soft(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2122 union nfs4_attr_u *na) 2123 { 2124 return (ENOTSUP); 2125 } 2126 2127 /* ARGSUSED */ 2128 static int 2129 rfs4_fattr4_quota_used(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2130 union nfs4_attr_u *na) 2131 { 2132 return (ENOTSUP); 2133 } 2134 2135 /* ARGSUSED */ 2136 static int 2137 rfs4_fattr4_rawdev(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2138 union nfs4_attr_u *na) 2139 { 2140 int error = 0; 2141 2142 if (RFS4_MANDATTR_ONLY) 2143 return (ENOTSUP); 2144 2145 switch (cmd) { 2146 case NFS4ATTR_SUPPORTED: 2147 if (sarg->op == NFS4ATTR_SETIT) 2148 error = EINVAL; 2149 break; /* this attr is supported */ 2150 case NFS4ATTR_GETIT: 2151 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_RDEV)) { 2152 error = -1; /* may be okay if rdattr_error */ 2153 break; 2154 } 2155 ASSERT(sarg->vap->va_mask & AT_RDEV); 2156 na->rawdev.specdata1 = (uint32)getmajor(sarg->vap->va_rdev); 2157 na->rawdev.specdata2 = (uint32)getminor(sarg->vap->va_rdev); 2158 break; 2159 case NFS4ATTR_SETIT: 2160 /* 2161 * read-only attr 2162 */ 2163 error = EINVAL; 2164 break; 2165 case NFS4ATTR_VERIT: 2166 ASSERT(sarg->vap->va_mask & AT_RDEV); 2167 if ((na->rawdev.specdata1 != 2168 (uint32)getmajor(sarg->vap->va_rdev)) || 2169 (na->rawdev.specdata2 != 2170 (uint32)getminor(sarg->vap->va_rdev))) 2171 error = -1; /* no match */ 2172 break; 2173 case NFS4ATTR_FREEIT: 2174 break; 2175 } 2176 return (error); 2177 } 2178 2179 /* ARGSUSED */ 2180 static int 2181 rfs4_fattr4_space_avail(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2182 union nfs4_attr_u *na) 2183 { 2184 int error = 0; 2185 2186 if (RFS4_MANDATTR_ONLY) 2187 return (ENOTSUP); 2188 2189 switch (cmd) { 2190 case NFS4ATTR_SUPPORTED: 2191 if (sarg->op == NFS4ATTR_SETIT) 2192 error = EINVAL; 2193 break; /* this attr is supported */ 2194 case NFS4ATTR_GETIT: 2195 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 2196 error = -1; /* may be okay if rdattr_error */ 2197 break; 2198 } 2199 ASSERT(sarg->sbp != NULL); 2200 if (sarg->sbp->f_bavail != (fsblkcnt64_t)-1) { 2201 na->space_avail = 2202 (fattr4_space_avail) sarg->sbp->f_frsize * 2203 (fattr4_space_avail) sarg->sbp->f_bavail; 2204 } else { 2205 na->space_avail = 2206 (fattr4_space_avail) sarg->sbp->f_bavail; 2207 } 2208 break; 2209 case NFS4ATTR_SETIT: 2210 /* 2211 * read-only attr 2212 */ 2213 error = EINVAL; 2214 break; 2215 case NFS4ATTR_VERIT: 2216 ASSERT(sarg->sbp != NULL); 2217 if (sarg->sbp->f_bavail != na->space_avail) 2218 error = -1; /* no match */ 2219 break; 2220 case NFS4ATTR_FREEIT: 2221 break; 2222 } 2223 return (error); 2224 } 2225 2226 /* ARGSUSED */ 2227 static int 2228 rfs4_fattr4_space_free(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2229 union nfs4_attr_u *na) 2230 { 2231 int error = 0; 2232 2233 if (RFS4_MANDATTR_ONLY) 2234 return (ENOTSUP); 2235 2236 switch (cmd) { 2237 case NFS4ATTR_SUPPORTED: 2238 if (sarg->op == NFS4ATTR_SETIT) 2239 error = EINVAL; 2240 break; /* this attr is supported */ 2241 case NFS4ATTR_GETIT: 2242 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 2243 error = -1; /* may be okay if rdattr_error */ 2244 break; 2245 } 2246 ASSERT(sarg->sbp != NULL); 2247 if (sarg->sbp->f_bfree != (fsblkcnt64_t)-1) { 2248 na->space_free = 2249 (fattr4_space_free) sarg->sbp->f_frsize * 2250 (fattr4_space_free) sarg->sbp->f_bfree; 2251 } else { 2252 na->space_free = 2253 (fattr4_space_free) sarg->sbp->f_bfree; 2254 } 2255 break; 2256 case NFS4ATTR_SETIT: 2257 /* 2258 * read-only attr 2259 */ 2260 error = EINVAL; 2261 break; 2262 case NFS4ATTR_VERIT: 2263 ASSERT(sarg->sbp != NULL); 2264 if (sarg->sbp->f_bfree != na->space_free) 2265 error = -1; /* no match */ 2266 break; 2267 case NFS4ATTR_FREEIT: 2268 break; 2269 } 2270 return (error); 2271 } 2272 2273 /* ARGSUSED */ 2274 static int 2275 rfs4_fattr4_space_total(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2276 union nfs4_attr_u *na) 2277 { 2278 int error = 0; 2279 2280 if (RFS4_MANDATTR_ONLY) 2281 return (ENOTSUP); 2282 2283 switch (cmd) { 2284 case NFS4ATTR_SUPPORTED: 2285 if (sarg->op == NFS4ATTR_SETIT) 2286 error = EINVAL; 2287 break; /* this attr is supported */ 2288 case NFS4ATTR_GETIT: 2289 if (sarg->rdattr_error_req && (sarg->sbp == NULL)) { 2290 error = -1; /* may be okay if rdattr_error */ 2291 break; 2292 } 2293 ASSERT(sarg->sbp != NULL); 2294 if (sarg->sbp->f_blocks != (fsblkcnt64_t)-1) { 2295 na->space_total = 2296 (fattr4_space_total) sarg->sbp->f_frsize * 2297 (fattr4_space_total) sarg->sbp->f_blocks; 2298 } else { 2299 na->space_total = 2300 (fattr4_space_total) sarg->sbp->f_blocks; 2301 } 2302 break; 2303 case NFS4ATTR_SETIT: 2304 /* 2305 * read-only attr 2306 */ 2307 error = EINVAL; 2308 break; 2309 case NFS4ATTR_VERIT: 2310 ASSERT(sarg->sbp != NULL); 2311 if (sarg->sbp->f_blocks != na->space_total) 2312 error = -1; /* no match */ 2313 break; 2314 case NFS4ATTR_FREEIT: 2315 break; 2316 } 2317 return (error); 2318 } 2319 2320 /* ARGSUSED */ 2321 static int 2322 rfs4_fattr4_space_used(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2323 union nfs4_attr_u *na) 2324 { 2325 int error = 0; 2326 2327 if (RFS4_MANDATTR_ONLY) 2328 return (ENOTSUP); 2329 2330 switch (cmd) { 2331 case NFS4ATTR_SUPPORTED: 2332 if (sarg->op == NFS4ATTR_SETIT) 2333 error = EINVAL; 2334 break; /* this attr is supported */ 2335 case NFS4ATTR_GETIT: 2336 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_NBLOCKS)) { 2337 error = -1; /* may be okay if rdattr_error */ 2338 break; 2339 } 2340 ASSERT(sarg->vap->va_mask & AT_NBLOCKS); 2341 na->space_used = (fattr4_space_used) DEV_BSIZE * 2342 (fattr4_space_used) sarg->vap->va_nblocks; 2343 break; 2344 case NFS4ATTR_SETIT: 2345 /* 2346 * read-only attr 2347 */ 2348 error = EINVAL; 2349 break; 2350 case NFS4ATTR_VERIT: 2351 ASSERT(sarg->vap->va_mask & AT_NBLOCKS); 2352 if (sarg->vap->va_nblocks != na->space_used) 2353 error = -1; /* no match */ 2354 break; 2355 case NFS4ATTR_FREEIT: 2356 break; 2357 } 2358 return (error); 2359 } 2360 2361 /* ARGSUSED */ 2362 static int 2363 rfs4_fattr4_system(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2364 union nfs4_attr_u *na) 2365 { 2366 return (ENOTSUP); 2367 } 2368 2369 /* ARGSUSED */ 2370 static int 2371 rfs4_fattr4_time_access(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2372 union nfs4_attr_u *na) 2373 { 2374 int error = 0; 2375 timestruc_t atime; 2376 2377 if (RFS4_MANDATTR_ONLY) 2378 return (ENOTSUP); 2379 2380 switch (cmd) { 2381 case NFS4ATTR_SUPPORTED: 2382 if (sarg->op == NFS4ATTR_SETIT) 2383 error = EINVAL; 2384 break; /* this attr is supported */ 2385 case NFS4ATTR_GETIT: 2386 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_ATIME)) { 2387 error = -1; /* may be okay if rdattr_error */ 2388 break; 2389 } 2390 ASSERT(sarg->vap->va_mask & AT_ATIME); 2391 error = nfs4_time_vton(&sarg->vap->va_atime, &na->time_access); 2392 break; 2393 case NFS4ATTR_SETIT: 2394 /* 2395 * read-only attr 2396 */ 2397 error = EINVAL; 2398 break; 2399 case NFS4ATTR_VERIT: 2400 ASSERT(sarg->vap->va_mask & AT_ATIME); 2401 error = nfs4_time_ntov(&na->time_access, &atime); 2402 if (error) 2403 break; 2404 if (bcmp(&atime, &sarg->vap->va_atime, sizeof (atime))) 2405 error = -1; /* no match */ 2406 break; 2407 case NFS4ATTR_FREEIT: 2408 break; 2409 } 2410 return (error); 2411 } 2412 2413 /* 2414 * XXX - need to support the setting of access time 2415 */ 2416 /* ARGSUSED */ 2417 static int 2418 rfs4_fattr4_time_access_set(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2419 union nfs4_attr_u *na) 2420 { 2421 int error = 0; 2422 settime4 *ta; 2423 2424 if (RFS4_MANDATTR_ONLY) 2425 return (ENOTSUP); 2426 2427 switch (cmd) { 2428 case NFS4ATTR_SUPPORTED: 2429 if ((sarg->op == NFS4ATTR_GETIT) || 2430 (sarg->op == NFS4ATTR_VERIT)) 2431 error = EINVAL; 2432 break; /* this attr is supported */ 2433 case NFS4ATTR_GETIT: 2434 case NFS4ATTR_VERIT: 2435 /* 2436 * write only attr 2437 */ 2438 error = EINVAL; 2439 break; 2440 case NFS4ATTR_SETIT: 2441 ASSERT(sarg->vap->va_mask & AT_ATIME); 2442 /* 2443 * Set access time (by server or by client) 2444 */ 2445 ta = &na->time_access_set; 2446 if (ta->set_it == SET_TO_CLIENT_TIME4) { 2447 error = nfs4_time_ntov(&ta->time, &sarg->vap->va_atime); 2448 } else if (ta->set_it == SET_TO_SERVER_TIME4) { 2449 gethrestime(&sarg->vap->va_atime); 2450 } else { 2451 error = EINVAL; 2452 } 2453 break; 2454 case NFS4ATTR_FREEIT: 2455 break; 2456 } 2457 return (error); 2458 } 2459 2460 /* ARGSUSED */ 2461 static int 2462 rfs4_fattr4_time_backup(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2463 union nfs4_attr_u *na) 2464 { 2465 return (ENOTSUP); 2466 } 2467 2468 /* ARGSUSED */ 2469 static int 2470 rfs4_fattr4_time_create(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2471 union nfs4_attr_u *na) 2472 { 2473 return (ENOTSUP); 2474 } 2475 2476 /* ARGSUSED */ 2477 static int 2478 rfs4_fattr4_time_delta(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2479 union nfs4_attr_u *na) 2480 { 2481 int error = 0; 2482 2483 if (RFS4_MANDATTR_ONLY) 2484 return (ENOTSUP); 2485 2486 switch (cmd) { 2487 case NFS4ATTR_SUPPORTED: 2488 if (sarg->op == NFS4ATTR_SETIT) 2489 error = EINVAL; 2490 break; /* this attr is supported */ 2491 case NFS4ATTR_GETIT: 2492 na->time_delta.seconds = 0; 2493 na->time_delta.nseconds = 1000; 2494 break; 2495 case NFS4ATTR_SETIT: 2496 /* 2497 * write only attr 2498 */ 2499 error = EINVAL; 2500 break; 2501 case NFS4ATTR_VERIT: 2502 if ((na->time_delta.seconds != 0) || 2503 (na->time_delta.nseconds != 1000)) 2504 error = -1; /* no match */ 2505 break; 2506 case NFS4ATTR_FREEIT: 2507 break; 2508 } 2509 return (error); 2510 } 2511 2512 /* ARGSUSED */ 2513 static int 2514 rfs4_fattr4_time_metadata(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2515 union nfs4_attr_u *na) 2516 { 2517 int error = 0; 2518 timestruc_t ctime; 2519 2520 if (RFS4_MANDATTR_ONLY) 2521 return (ENOTSUP); 2522 2523 switch (cmd) { 2524 case NFS4ATTR_SUPPORTED: 2525 if (sarg->op == NFS4ATTR_SETIT) 2526 error = EINVAL; 2527 break; /* this attr is supported */ 2528 case NFS4ATTR_GETIT: 2529 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_CTIME)) { 2530 error = -1; /* may be okay if rdattr_error */ 2531 break; 2532 } 2533 ASSERT(sarg->vap->va_mask & AT_CTIME); 2534 error = nfs4_time_vton(&sarg->vap->va_ctime, 2535 &na->time_metadata); 2536 break; 2537 case NFS4ATTR_SETIT: 2538 /* 2539 * read-only attr 2540 */ 2541 error = EINVAL; 2542 break; 2543 case NFS4ATTR_VERIT: 2544 ASSERT(sarg->vap->va_mask & AT_CTIME); 2545 error = nfs4_time_ntov(&na->time_metadata, &ctime); 2546 if (error) 2547 break; 2548 if (bcmp(&ctime, &sarg->vap->va_ctime, sizeof (ctime))) 2549 error = -1; /* no match */ 2550 break; 2551 case NFS4ATTR_FREEIT: 2552 break; 2553 } 2554 return (error); 2555 } 2556 2557 /* ARGSUSED */ 2558 static int 2559 rfs4_fattr4_time_modify(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2560 union nfs4_attr_u *na) 2561 { 2562 int error = 0; 2563 timestruc_t mtime; 2564 2565 if (RFS4_MANDATTR_ONLY) 2566 return (ENOTSUP); 2567 2568 switch (cmd) { 2569 case NFS4ATTR_SUPPORTED: 2570 if (sarg->op == NFS4ATTR_SETIT) 2571 error = EINVAL; 2572 break; /* this attr is supported */ 2573 case NFS4ATTR_GETIT: 2574 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_MTIME)) { 2575 error = -1; /* may be okay if rdattr_error */ 2576 break; 2577 } 2578 ASSERT(sarg->vap->va_mask & AT_MTIME); 2579 error = nfs4_time_vton(&sarg->vap->va_mtime, &na->time_modify); 2580 break; 2581 case NFS4ATTR_SETIT: 2582 /* 2583 * read-only attr 2584 */ 2585 error = EINVAL; 2586 break; 2587 case NFS4ATTR_VERIT: 2588 ASSERT(sarg->vap->va_mask & AT_MTIME); 2589 error = nfs4_time_ntov(&na->time_modify, &mtime); 2590 if (error) 2591 break; 2592 if (bcmp(&mtime, &sarg->vap->va_mtime, sizeof (mtime))) 2593 error = -1; /* no match */ 2594 break; 2595 case NFS4ATTR_FREEIT: 2596 break; 2597 } 2598 return (error); 2599 } 2600 2601 /* 2602 * XXX - need to add support for setting modify time 2603 */ 2604 /* ARGSUSED */ 2605 static int 2606 rfs4_fattr4_time_modify_set(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2607 union nfs4_attr_u *na) 2608 { 2609 int error = 0; 2610 settime4 *tm; 2611 2612 if (RFS4_MANDATTR_ONLY) 2613 return (ENOTSUP); 2614 2615 switch (cmd) { 2616 case NFS4ATTR_SUPPORTED: 2617 if ((sarg->op == NFS4ATTR_GETIT) || 2618 (sarg->op == NFS4ATTR_VERIT)) 2619 error = EINVAL; 2620 break; /* this attr is supported */ 2621 case NFS4ATTR_GETIT: 2622 case NFS4ATTR_VERIT: 2623 /* 2624 * write only attr 2625 */ 2626 error = EINVAL; 2627 break; 2628 case NFS4ATTR_SETIT: 2629 ASSERT(sarg->vap->va_mask & AT_MTIME); 2630 /* 2631 * Set modify time (by server or by client) 2632 */ 2633 tm = &na->time_modify_set; 2634 if (tm->set_it == SET_TO_CLIENT_TIME4) { 2635 error = nfs4_time_ntov(&tm->time, &sarg->vap->va_mtime); 2636 sarg->flag = ATTR_UTIME; 2637 } else if (tm->set_it == SET_TO_SERVER_TIME4) { 2638 gethrestime(&sarg->vap->va_mtime); 2639 } else { 2640 error = EINVAL; 2641 } 2642 break; 2643 case NFS4ATTR_FREEIT: 2644 break; 2645 } 2646 return (error); 2647 } 2648 2649 2650 static void 2651 rfs4_ntov_init(void) 2652 { 2653 /* index must be same as corresponding FATTR4_* define */ 2654 nfs4_ntov_map[0].sv_getit = rfs4_fattr4_supported_attrs; 2655 nfs4_ntov_map[1].sv_getit = rfs4_fattr4_type; 2656 nfs4_ntov_map[2].sv_getit = rfs4_fattr4_fh_expire_type; 2657 nfs4_ntov_map[3].sv_getit = rfs4_fattr4_change; 2658 nfs4_ntov_map[4].sv_getit = rfs4_fattr4_size; 2659 nfs4_ntov_map[5].sv_getit = rfs4_fattr4_link_support; 2660 nfs4_ntov_map[6].sv_getit = rfs4_fattr4_symlink_support; 2661 nfs4_ntov_map[7].sv_getit = rfs4_fattr4_named_attr; 2662 nfs4_ntov_map[8].sv_getit = rfs4_fattr4_fsid; 2663 nfs4_ntov_map[9].sv_getit = rfs4_fattr4_unique_handles; 2664 nfs4_ntov_map[10].sv_getit = rfs4_fattr4_lease_time; 2665 nfs4_ntov_map[11].sv_getit = rfs4_fattr4_rdattr_error; 2666 nfs4_ntov_map[12].sv_getit = rfs4_fattr4_acl; 2667 nfs4_ntov_map[13].sv_getit = rfs4_fattr4_aclsupport; 2668 nfs4_ntov_map[14].sv_getit = rfs4_fattr4_archive; 2669 nfs4_ntov_map[15].sv_getit = rfs4_fattr4_cansettime; 2670 nfs4_ntov_map[16].sv_getit = rfs4_fattr4_case_insensitive; 2671 nfs4_ntov_map[17].sv_getit = rfs4_fattr4_case_preserving; 2672 nfs4_ntov_map[18].sv_getit = rfs4_fattr4_chown_restricted; 2673 nfs4_ntov_map[19].sv_getit = rfs4_fattr4_filehandle; 2674 nfs4_ntov_map[20].sv_getit = rfs4_fattr4_fileid; 2675 nfs4_ntov_map[21].sv_getit = rfs4_fattr4_files_avail; 2676 nfs4_ntov_map[22].sv_getit = rfs4_fattr4_files_free; 2677 nfs4_ntov_map[23].sv_getit = rfs4_fattr4_files_total; 2678 nfs4_ntov_map[24].sv_getit = rfs4_fattr4_fs_locations; 2679 nfs4_ntov_map[25].sv_getit = rfs4_fattr4_hidden; 2680 nfs4_ntov_map[26].sv_getit = rfs4_fattr4_homogeneous; 2681 nfs4_ntov_map[27].sv_getit = rfs4_fattr4_maxfilesize; 2682 nfs4_ntov_map[28].sv_getit = rfs4_fattr4_maxlink; 2683 nfs4_ntov_map[29].sv_getit = rfs4_fattr4_maxname; 2684 nfs4_ntov_map[30].sv_getit = rfs4_fattr4_maxread; 2685 nfs4_ntov_map[31].sv_getit = rfs4_fattr4_maxwrite; 2686 nfs4_ntov_map[32].sv_getit = rfs4_fattr4_mimetype; 2687 nfs4_ntov_map[33].sv_getit = rfs4_fattr4_mode; 2688 nfs4_ntov_map[34].sv_getit = rfs4_fattr4_no_trunc; 2689 nfs4_ntov_map[35].sv_getit = rfs4_fattr4_numlinks; 2690 nfs4_ntov_map[36].sv_getit = rfs4_fattr4_owner; 2691 nfs4_ntov_map[37].sv_getit = rfs4_fattr4_owner_group; 2692 nfs4_ntov_map[38].sv_getit = rfs4_fattr4_quota_avail_hard; 2693 nfs4_ntov_map[39].sv_getit = rfs4_fattr4_quota_avail_soft; 2694 nfs4_ntov_map[40].sv_getit = rfs4_fattr4_quota_used; 2695 nfs4_ntov_map[41].sv_getit = rfs4_fattr4_rawdev; 2696 nfs4_ntov_map[42].sv_getit = rfs4_fattr4_space_avail; 2697 nfs4_ntov_map[43].sv_getit = rfs4_fattr4_space_free; 2698 nfs4_ntov_map[44].sv_getit = rfs4_fattr4_space_total; 2699 nfs4_ntov_map[45].sv_getit = rfs4_fattr4_space_used; 2700 nfs4_ntov_map[46].sv_getit = rfs4_fattr4_system; 2701 nfs4_ntov_map[47].sv_getit = rfs4_fattr4_time_access; 2702 nfs4_ntov_map[48].sv_getit = rfs4_fattr4_time_access_set; 2703 nfs4_ntov_map[49].sv_getit = rfs4_fattr4_time_backup; 2704 nfs4_ntov_map[50].sv_getit = rfs4_fattr4_time_create; 2705 nfs4_ntov_map[51].sv_getit = rfs4_fattr4_time_delta; 2706 nfs4_ntov_map[52].sv_getit = rfs4_fattr4_time_metadata; 2707 nfs4_ntov_map[53].sv_getit = rfs4_fattr4_time_modify; 2708 nfs4_ntov_map[54].sv_getit = rfs4_fattr4_time_modify_set; 2709 nfs4_ntov_map[55].sv_getit = rfs4_fattr4_mounted_on_fileid; 2710 } 2711