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