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 2008 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 tunable 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 generic xattr. If VFS_XATTR 574 * not set, no need to call pathconf for _PC_XATTR_EXISTS.. 575 * 576 * However the VFS_XATTR flag doesn't indicate sysattr support 577 * so always check for sysattrs and then only do the 578 * _PC_XATTR_EXISTS pathconf if needed. 579 */ 580 581 val = 0; 582 error = VOP_PATHCONF(sarg->cs->vp, _PC_SATTR_EXISTS, 583 &val, sarg->cs->cr, NULL); 584 if ((error || val == 0) && 585 sarg->cs->vp->v_vfsp->vfs_flag & VFS_XATTR) { 586 error = VOP_PATHCONF(sarg->cs->vp, 587 _PC_XATTR_EXISTS, &val, sarg->cs->cr, NULL); 588 if (error) 589 break; 590 } 591 na->named_attr = (val ? TRUE : FALSE); 592 break; 593 case NFS4ATTR_SETIT: 594 /* 595 * read-only attr 596 */ 597 error = EINVAL; 598 break; 599 case NFS4ATTR_VERIT: 600 ASSERT(sarg->cs->vp != NULL); 601 if (sarg->cs->vp->v_vfsp->vfs_flag & VFS_XATTR) { 602 error = VOP_PATHCONF(sarg->cs->vp, _PC_XATTR_EXISTS, 603 &val, sarg->cs->cr, NULL); 604 if (error) 605 break; 606 } else 607 val = 0; 608 if (na->named_attr != (val ? TRUE : FALSE)) 609 error = -1; /* no match */ 610 break; 611 case NFS4ATTR_FREEIT: 612 break; 613 } 614 return (error); 615 } 616 617 /* ARGSUSED */ 618 static int 619 rfs4_fattr4_fsid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 620 union nfs4_attr_u *na) 621 { 622 int error = 0; 623 int *pmaj = (int *)&na->fsid.major; 624 625 /* 626 * fsid_t is 64bits so it fits completely in fattr4_fsid.major. 627 * fattr4_fsid.minor is always set to 0 since it isn't needed (yet). 628 */ 629 switch (cmd) { 630 case NFS4ATTR_SUPPORTED: 631 if (sarg->op == NFS4ATTR_SETIT) 632 error = EINVAL; 633 break; /* this attr is supported */ 634 case NFS4ATTR_GETIT: 635 if (sarg->cs->exi->exi_volatile_dev) { 636 pmaj[0] = sarg->cs->exi->exi_fsid.val[0]; 637 pmaj[1] = sarg->cs->exi->exi_fsid.val[1]; 638 na->fsid.minor = 0; 639 } else { 640 na->fsid.major = getmajor(sarg->vap->va_fsid); 641 na->fsid.minor = getminor(sarg->vap->va_fsid); 642 } 643 break; 644 case NFS4ATTR_SETIT: 645 error = EINVAL; 646 break; 647 case NFS4ATTR_VERIT: 648 if (sarg->cs->exi->exi_volatile_dev) { 649 if (pmaj[0] != sarg->cs->exi->exi_fsid.val[0] || 650 pmaj[1] != sarg->cs->exi->exi_fsid.val[1] || 651 na->fsid.minor != 0) 652 error = -1; 653 } else { 654 if (na->fsid.major != getmajor(sarg->vap->va_fsid) || 655 na->fsid.minor != getminor(sarg->vap->va_fsid)) 656 error = -1; 657 } 658 break; 659 case NFS4ATTR_FREEIT: 660 break; 661 } 662 return (error); 663 } 664 665 /* ARGSUSED */ 666 static int 667 rfs4_fattr4_unique_handles(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 668 union nfs4_attr_u *na) 669 { 670 /* 671 * XXX 672 * For now, we can't support this. Problem of /export, beinging 673 * a file system, /export/a and /export/b shared separately, 674 * and /export/a/l and /export/b/l are ahrd links of each other. 675 */ 676 int error = 0; 677 678 switch (cmd) { 679 case NFS4ATTR_SUPPORTED: 680 if (sarg->op == NFS4ATTR_SETIT) 681 error = EINVAL; 682 break; /* this attr is supported */ 683 case NFS4ATTR_GETIT: 684 na->unique_handles = FALSE; 685 break; 686 case NFS4ATTR_SETIT: 687 /* 688 * read-only attr 689 */ 690 error = EINVAL; 691 break; 692 case NFS4ATTR_VERIT: 693 if (na->unique_handles) 694 error = -1; /* no match */ 695 break; 696 case NFS4ATTR_FREEIT: 697 break; 698 } 699 return (error); 700 } 701 702 /* ARGSUSED */ 703 static int 704 rfs4_fattr4_lease_time(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 705 union nfs4_attr_u *na) 706 { 707 int error = 0; 708 709 switch (cmd) { 710 case NFS4ATTR_SUPPORTED: 711 if (sarg->op == NFS4ATTR_SETIT) 712 error = EINVAL; 713 break; /* this attr is supported */ 714 case NFS4ATTR_GETIT: 715 na->lease_time = rfs4_lease_time; 716 break; 717 case NFS4ATTR_SETIT: 718 /* 719 * read-only attr 720 */ 721 error = EINVAL; 722 break; 723 case NFS4ATTR_VERIT: 724 if (na->lease_time != rfs4_lease_time) 725 error = -1; /* no match */ 726 break; 727 case NFS4ATTR_FREEIT: 728 break; 729 } 730 return (error); 731 } 732 733 /* ARGSUSED */ 734 static int 735 rfs4_fattr4_rdattr_error(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 736 union nfs4_attr_u *na) 737 { 738 int error = 0; 739 740 switch (cmd) { 741 case NFS4ATTR_SUPPORTED: 742 if ((sarg->op == NFS4ATTR_SETIT) || 743 (sarg->op == NFS4ATTR_VERIT)) 744 error = EINVAL; 745 break; /* this attr is supported */ 746 case NFS4ATTR_GETIT: 747 ASSERT(sarg->rdattr_error_req); 748 na->rdattr_error = sarg->rdattr_error; 749 break; 750 case NFS4ATTR_SETIT: 751 case NFS4ATTR_VERIT: 752 /* 753 * read-only attr 754 */ 755 error = EINVAL; 756 break; 757 case NFS4ATTR_FREEIT: 758 break; 759 } 760 return (error); 761 } 762 763 /* 764 * Server side compare of a filehandle from the wire to a native 765 * server filehandle. 766 */ 767 static int 768 rfs4fhcmp(nfs_fh4 *wirefh, nfs_fh4 *srvfh) 769 { 770 nfs_fh4_fmt_t fh; 771 772 ASSERT(IS_P2ALIGNED(wirefh->nfs_fh4_val, sizeof (uint32_t))); 773 774 bzero(&fh, sizeof (nfs_fh4_fmt_t)); 775 if (!xdr_inline_decode_nfs_fh4((uint32_t *)wirefh->nfs_fh4_val, &fh, 776 wirefh->nfs_fh4_len)) 777 return (1); 778 779 return (bcmp(srvfh->nfs_fh4_val, &fh, srvfh->nfs_fh4_len)); 780 } 781 782 /* ARGSUSED */ 783 static int 784 rfs4_fattr4_filehandle(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 785 union nfs4_attr_u *na) 786 { 787 nfs_fh4 *fh; 788 789 switch (cmd) { 790 case NFS4ATTR_SUPPORTED: 791 if (sarg->op == NFS4ATTR_SETIT) 792 return (EINVAL); 793 return (0); /* this attr is supported */ 794 case NFS4ATTR_GETIT: 795 /* 796 * If sarg->cs->fh is all zeros then should makefh a new 797 * one, otherwise, copy that one over. 798 */ 799 fh = &sarg->cs->fh; 800 if (sarg->cs->fh.nfs_fh4_len == 0) { 801 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) 802 return (-1); /* okay if rdattr_error */ 803 ASSERT(sarg->cs->vp != NULL); 804 na->filehandle.nfs_fh4_val = 805 kmem_alloc(NFS_FH4_LEN, KM_SLEEP); 806 return (makefh4(&na->filehandle, sarg->cs->vp, 807 sarg->cs->exi)); 808 } 809 na->filehandle.nfs_fh4_val = 810 kmem_alloc(fh->nfs_fh4_len, KM_SLEEP); 811 nfs_fh4_copy(fh, &na->filehandle); 812 return (0); 813 case NFS4ATTR_SETIT: 814 /* 815 * read-only attr 816 */ 817 return (EINVAL); 818 case NFS4ATTR_VERIT: 819 /* 820 * A verify of a filehandle will have the client sending 821 * the raw format which needs to be compared to the 822 * native format. 823 */ 824 if (rfs4fhcmp(&na->filehandle, &sarg->cs->fh) == 1) 825 return (-1); /* no match */ 826 return (0); 827 case NFS4ATTR_FREEIT: 828 if (sarg->op != NFS4ATTR_GETIT) 829 return (0); 830 if (na->filehandle.nfs_fh4_val == NULL) 831 return (0); 832 kmem_free(na->filehandle.nfs_fh4_val, 833 na->filehandle.nfs_fh4_len); 834 na->filehandle.nfs_fh4_val = NULL; 835 na->filehandle.nfs_fh4_len = 0; 836 return (0); 837 } 838 return (0); 839 } 840 841 /* 842 * Recommended attributes 843 */ 844 845 /* ARGSUSED */ 846 static int 847 rfs4_fattr4_acl(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 848 union nfs4_attr_u *na) 849 { 850 int error = 0; 851 vsecattr_t vs_native, vs_ace4; 852 ulong_t whichacl; 853 nfsstat4 status; 854 vattr_t va, *vap = sarg->vap; 855 vnode_t *vp = sarg->cs->vp; 856 857 if (RFS4_MANDATTR_ONLY) 858 return (ENOTSUP); 859 860 switch (cmd) { 861 case NFS4ATTR_SUPPORTED: 862 break; 863 864 case NFS4ATTR_VERIT: 865 case NFS4ATTR_GETIT: 866 if (sarg->rdattr_error && (vp == NULL)) { 867 return (-1); 868 } 869 ASSERT(vp != NULL); 870 bzero(&vs_native, sizeof (vs_native)); 871 872 /* see which ACLs fs supports */ 873 error = VOP_PATHCONF(vp, _PC_ACL_ENABLED, &whichacl, 874 sarg->cs->cr, NULL); 875 if (error != 0) { 876 /* 877 * If we got an error, then the filesystem 878 * likely does not understand the _PC_ACL_ENABLED 879 * pathconf. In this case, we fall back to trying 880 * POSIX-draft (aka UFS-style) ACLs, since that's 881 * the behavior used by earlier version of NFS. 882 */ 883 error = 0; 884 whichacl = _ACL_ACLENT_ENABLED; 885 } 886 887 if (!(whichacl & (_ACL_ACE_ENABLED | _ACL_ACLENT_ENABLED))) { 888 /* 889 * If the file system supports neither ACE nor 890 * ACLENT ACLs we will fall back to UFS-style ACLs 891 * like we did above if there was an error upon 892 * calling VOP_PATHCONF. 893 * 894 * ACE and ACLENT type ACLs are the only interfaces 895 * supported thus far. If any other bits are set on 896 * 'whichacl' upon return from VOP_PATHCONF, we will 897 * ignore them. 898 */ 899 whichacl = _ACL_ACLENT_ENABLED; 900 } 901 902 if (whichacl & _ACL_ACE_ENABLED) 903 vs_native.vsa_mask = VSA_ACE | VSA_ACECNT; 904 else if (whichacl & _ACL_ACLENT_ENABLED) 905 vs_native.vsa_mask = VSA_ACL | VSA_ACLCNT | 906 VSA_DFACL | VSA_DFACLCNT; 907 908 if (error != 0) 909 break; 910 911 /* get the ACL, and translate it into nfsace4 style */ 912 error = VOP_GETSECATTR(vp, &vs_native, 913 0, sarg->cs->cr, NULL); 914 if (error != 0) 915 break; 916 if (whichacl & _ACL_ACE_ENABLED) { 917 error = vs_acet_to_ace4(&vs_native, &vs_ace4, TRUE); 918 vs_acet_destroy(&vs_native); 919 } else { 920 error = vs_aent_to_ace4(&vs_native, &vs_ace4, 921 vp->v_type == VDIR, TRUE); 922 vs_aent_destroy(&vs_native); 923 } 924 if (error != 0) 925 break; 926 927 if (cmd == NFS4ATTR_GETIT) { 928 na->acl.fattr4_acl_len = vs_ace4.vsa_aclcnt; 929 /* see case NFS4ATTR_FREEIT for this being freed */ 930 na->acl.fattr4_acl_val = vs_ace4.vsa_aclentp; 931 } else { 932 if (na->acl.fattr4_acl_len != vs_ace4.vsa_aclcnt) 933 error = -1; /* no match */ 934 else if (ln_ace4_cmp(na->acl.fattr4_acl_val, 935 vs_ace4.vsa_aclentp, 936 vs_ace4.vsa_aclcnt) != 0) 937 error = -1; /* no match */ 938 } 939 940 break; 941 942 case NFS4ATTR_SETIT: 943 if (sarg->rdattr_error && (vp == NULL)) { 944 return (-1); 945 } 946 ASSERT(vp != NULL); 947 948 /* prepare vs_ace4 from fattr4 data */ 949 bzero(&vs_ace4, sizeof (vs_ace4)); 950 vs_ace4.vsa_mask = VSA_ACE | VSA_ACECNT; 951 vs_ace4.vsa_aclcnt = na->acl.fattr4_acl_len; 952 vs_ace4.vsa_aclentp = na->acl.fattr4_acl_val; 953 vs_ace4.vsa_aclentsz = vs_ace4.vsa_aclcnt * sizeof (ace_t); 954 /* make sure we have correct owner/group */ 955 if ((vap->va_mask & (AT_UID | AT_GID)) != 956 (AT_UID | AT_GID)) { 957 vap = &va; 958 vap->va_mask = AT_UID | AT_GID; 959 status = rfs4_vop_getattr(vp, 960 vap, 0, sarg->cs->cr); 961 if (status != NFS4_OK) 962 return (geterrno4(status)); 963 } 964 965 /* see which ACLs the fs supports */ 966 error = VOP_PATHCONF(vp, _PC_ACL_ENABLED, &whichacl, 967 sarg->cs->cr, NULL); 968 if (error != 0) { 969 /* 970 * If we got an error, then the filesystem 971 * likely does not understand the _PC_ACL_ENABLED 972 * pathconf. In this case, we fall back to trying 973 * POSIX-draft (aka UFS-style) ACLs, since that's 974 * the behavior used by earlier version of NFS. 975 */ 976 error = 0; 977 whichacl = _ACL_ACLENT_ENABLED; 978 } 979 980 if (!(whichacl & (_ACL_ACLENT_ENABLED | _ACL_ACE_ENABLED))) { 981 /* 982 * If the file system supports neither ACE nor 983 * ACLENT ACLs we will fall back to UFS-style ACLs 984 * like we did above if there was an error upon 985 * calling VOP_PATHCONF. 986 * 987 * ACE and ACLENT type ACLs are the only interfaces 988 * supported thus far. If any other bits are set on 989 * 'whichacl' upon return from VOP_PATHCONF, we will 990 * ignore them. 991 */ 992 whichacl = _ACL_ACLENT_ENABLED; 993 } 994 995 if (whichacl & _ACL_ACE_ENABLED) { 996 error = vs_ace4_to_acet(&vs_ace4, &vs_native, 997 vap->va_uid, vap->va_gid, TRUE, FALSE); 998 if (error != 0) 999 break; 1000 (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL); 1001 error = VOP_SETSECATTR(vp, &vs_native, 1002 0, sarg->cs->cr, NULL); 1003 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL); 1004 vs_acet_destroy(&vs_native); 1005 } else if (whichacl & _ACL_ACLENT_ENABLED) { 1006 error = vs_ace4_to_aent(&vs_ace4, &vs_native, 1007 vap->va_uid, vap->va_gid, vp->v_type == VDIR, TRUE, 1008 FALSE); 1009 if (error != 0) 1010 break; 1011 (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL); 1012 error = VOP_SETSECATTR(vp, &vs_native, 1013 0, sarg->cs->cr, NULL); 1014 VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL); 1015 vs_aent_destroy(&vs_native); 1016 } 1017 break; 1018 1019 case NFS4ATTR_FREEIT: 1020 if (sarg->op == NFS4ATTR_GETIT) { 1021 vs_ace4.vsa_mask = VSA_ACE | VSA_ACECNT; 1022 vs_ace4.vsa_aclcnt = na->acl.fattr4_acl_len; 1023 vs_ace4.vsa_aclentp = na->acl.fattr4_acl_val; 1024 vs_ace4_destroy(&vs_ace4); 1025 } 1026 break; 1027 } 1028 1029 return (error); 1030 } 1031 1032 /* ARGSUSED */ 1033 static int 1034 rfs4_fattr4_aclsupport(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1035 union nfs4_attr_u *na) 1036 { 1037 int error = 0; 1038 1039 if (RFS4_MANDATTR_ONLY) 1040 return (ENOTSUP); 1041 1042 switch (cmd) { 1043 case NFS4ATTR_SUPPORTED: 1044 if (sarg->op == NFS4ATTR_SETIT) 1045 error = EINVAL; 1046 break; /* supported */ 1047 case NFS4ATTR_GETIT: 1048 na->aclsupport = ACL4_SUPPORT_ALLOW_ACL | 1049 ACL4_SUPPORT_DENY_ACL; 1050 break; 1051 case NFS4ATTR_SETIT: 1052 error = EINVAL; 1053 break; 1054 case NFS4ATTR_VERIT: 1055 if (na->aclsupport != (ACL4_SUPPORT_ALLOW_ACL | 1056 ACL4_SUPPORT_DENY_ACL)) 1057 error = -1; /* no match */ 1058 break; 1059 } 1060 1061 return (error); 1062 } 1063 1064 /* ARGSUSED */ 1065 static int 1066 rfs4_fattr4_archive(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1067 union nfs4_attr_u *na) 1068 { 1069 return (ENOTSUP); 1070 } 1071 1072 /* ARGSUSED */ 1073 static int 1074 rfs4_fattr4_cansettime(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1075 union nfs4_attr_u *na) 1076 { 1077 int error = 0; 1078 1079 if (RFS4_MANDATTR_ONLY) 1080 return (ENOTSUP); 1081 1082 switch (cmd) { 1083 case NFS4ATTR_SUPPORTED: 1084 if (sarg->op == NFS4ATTR_SETIT) 1085 error = EINVAL; 1086 break; /* this attr is supported */ 1087 case NFS4ATTR_GETIT: 1088 na->cansettime = TRUE; 1089 break; 1090 case NFS4ATTR_SETIT: 1091 /* 1092 * read-only attr 1093 */ 1094 error = EINVAL; 1095 break; 1096 case NFS4ATTR_VERIT: 1097 if (!na->cansettime) 1098 error = -1; /* no match */ 1099 break; 1100 case NFS4ATTR_FREEIT: 1101 break; 1102 } 1103 return (error); 1104 } 1105 1106 /* 1107 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports 1108 * case insensitive. 1109 */ 1110 /* ARGSUSED */ 1111 static int 1112 rfs4_fattr4_case_insensitive(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1113 union nfs4_attr_u *na) 1114 { 1115 int error = 0; 1116 1117 if (RFS4_MANDATTR_ONLY) 1118 return (ENOTSUP); 1119 1120 switch (cmd) { 1121 case NFS4ATTR_SUPPORTED: 1122 if (sarg->op == NFS4ATTR_SETIT) 1123 error = EINVAL; 1124 break; /* this attr is supported */ 1125 case NFS4ATTR_GETIT: 1126 na->case_insensitive = FALSE; 1127 break; 1128 case NFS4ATTR_SETIT: 1129 /* 1130 * read-only attr 1131 */ 1132 error = EINVAL; 1133 break; 1134 case NFS4ATTR_VERIT: 1135 if (!na->case_insensitive) 1136 error = -1; /* no match */ 1137 break; 1138 case NFS4ATTR_FREEIT: 1139 break; 1140 } 1141 return (error); 1142 } 1143 1144 /* ARGSUSED */ 1145 static int 1146 rfs4_fattr4_case_preserving(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1147 union nfs4_attr_u *na) 1148 { 1149 int error = 0; 1150 1151 if (RFS4_MANDATTR_ONLY) 1152 return (ENOTSUP); 1153 1154 switch (cmd) { 1155 case NFS4ATTR_SUPPORTED: 1156 if (sarg->op == NFS4ATTR_SETIT) 1157 error = EINVAL; 1158 break; /* this attr is supported */ 1159 case NFS4ATTR_GETIT: 1160 na->case_preserving = TRUE; 1161 break; 1162 case NFS4ATTR_SETIT: 1163 /* 1164 * read-only attr 1165 */ 1166 error = EINVAL; 1167 break; 1168 case NFS4ATTR_VERIT: 1169 if (!na->case_preserving) 1170 error = -1; /* no match */ 1171 break; 1172 case NFS4ATTR_FREEIT: 1173 break; 1174 } 1175 return (error); 1176 } 1177 1178 /* fattr4_chown_restricted should reall be fattr4_chown_allowed */ 1179 /* ARGSUSED */ 1180 static int 1181 rfs4_fattr4_chown_restricted(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1182 union nfs4_attr_u *na) 1183 { 1184 int error = 0; 1185 ulong_t val; 1186 1187 if (RFS4_MANDATTR_ONLY) 1188 return (ENOTSUP); 1189 1190 switch (cmd) { 1191 case NFS4ATTR_SUPPORTED: 1192 if (sarg->op == NFS4ATTR_SETIT) 1193 error = EINVAL; 1194 break; /* this attr is supported */ 1195 case NFS4ATTR_GETIT: 1196 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) { 1197 error = -1; /* may be okay if rdattr_error */ 1198 break; 1199 } 1200 ASSERT(sarg->cs->vp != NULL); 1201 error = VOP_PATHCONF(sarg->cs->vp, 1202 _PC_CHOWN_RESTRICTED, &val, sarg->cs->cr, NULL); 1203 if (error) 1204 break; 1205 1206 na->chown_restricted = (val == 1); 1207 break; 1208 case NFS4ATTR_SETIT: 1209 /* 1210 * read-only attr 1211 */ 1212 error = EINVAL; 1213 break; 1214 case NFS4ATTR_VERIT: 1215 ASSERT(sarg->cs->vp != NULL); 1216 error = VOP_PATHCONF(sarg->cs->vp, 1217 _PC_CHOWN_RESTRICTED, &val, sarg->cs->cr, NULL); 1218 if (error) 1219 break; 1220 if (na->chown_restricted != (val == 1)) 1221 error = -1; /* no match */ 1222 break; 1223 case NFS4ATTR_FREEIT: 1224 break; 1225 } 1226 return (error); 1227 } 1228 1229 /* ARGSUSED */ 1230 static int 1231 rfs4_fattr4_fileid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1232 union nfs4_attr_u *na) 1233 { 1234 int error = 0; 1235 1236 if (RFS4_MANDATTR_ONLY) 1237 return (ENOTSUP); 1238 1239 switch (cmd) { 1240 case NFS4ATTR_SUPPORTED: 1241 if (sarg->op == NFS4ATTR_SETIT) 1242 error = EINVAL; 1243 break; /* this attr is supported */ 1244 case NFS4ATTR_GETIT: 1245 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_NODEID)) { 1246 error = -1; /* may be okay if rdattr_error */ 1247 break; 1248 } 1249 ASSERT(sarg->vap->va_mask & AT_NODEID); 1250 na->fileid = sarg->vap->va_nodeid; 1251 break; 1252 case NFS4ATTR_SETIT: 1253 /* 1254 * read-only attr 1255 */ 1256 error = EINVAL; 1257 break; 1258 case NFS4ATTR_VERIT: 1259 ASSERT(sarg->vap->va_mask & AT_NODEID); 1260 if (sarg->vap->va_nodeid != na->fileid) 1261 error = -1; /* no match */ 1262 break; 1263 case NFS4ATTR_FREEIT: 1264 break; 1265 } 1266 return (error); 1267 } 1268 1269 /* ARGSUSED */ 1270 static int 1271 rfs4_get_mntdfileid(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg) 1272 { 1273 int error = 0; 1274 vattr_t *vap, va; 1275 vnode_t *stubvp = NULL, *vp; 1276 1277 vp = sarg->cs->vp; 1278 sarg->mntdfid_set = FALSE; 1279 1280 /* VROOT object, must untraverse */ 1281 if (vp->v_flag & VROOT) { 1282 1283 /* extra hold for vp since untraverse might rele */ 1284 VN_HOLD(vp); 1285 stubvp = untraverse(vp); 1286 1287 /* 1288 * If vp/stubvp are same, we must be at system 1289 * root because untraverse returned same vp 1290 * for a VROOT object. sarg->vap was setup 1291 * before we got here, so there's no need to do 1292 * another getattr -- just use the one in sarg. 1293 */ 1294 if (VN_CMP(vp, stubvp)) { 1295 ASSERT(VN_CMP(vp, rootdir)); 1296 vap = sarg->vap; 1297 } else { 1298 va.va_mask = AT_NODEID; 1299 vap = &va; 1300 error = rfs4_vop_getattr(stubvp, vap, 0, sarg->cs->cr); 1301 } 1302 1303 /* 1304 * Done with stub, time to rele. If vp and stubvp 1305 * were the same, then we need to rele either vp or 1306 * stubvp. If they weren't the same, then untraverse() 1307 * already took case of the extra hold on vp, and only 1308 * the stub needs to be rele'd. Both cases are handled 1309 * by unconditionally rele'ing the stub. 1310 */ 1311 VN_RELE(stubvp); 1312 } else 1313 vap = sarg->vap; 1314 1315 /* 1316 * At this point, vap should contain "correct" AT_NODEID -- 1317 * (for V_ROOT case, nodeid of stub, for non-VROOT case, 1318 * nodeid of vp). If error or AT_NODEID not available, then 1319 * make the obligatory (yet mysterious) rdattr_error 1320 * check that is so common in the attr code. 1321 */ 1322 if (!error && (vap->va_mask & AT_NODEID)) { 1323 sarg->mounted_on_fileid = vap->va_nodeid; 1324 sarg->mntdfid_set = TRUE; 1325 } else if (sarg->rdattr_error) 1326 error = -1; 1327 1328 /* 1329 * error describes these cases: 1330 * 0 : success 1331 * -1: failure due to previous attr processing error (rddir only). 1332 * * : new attr failure (if rddir, caller will set rdattr_error) 1333 */ 1334 return (error); 1335 } 1336 1337 /* ARGSUSED */ 1338 static int 1339 rfs4_fattr4_mounted_on_fileid(nfs4_attr_cmd_t cmd, 1340 struct nfs4_svgetit_arg *sarg, union nfs4_attr_u *na) 1341 { 1342 int error = 0; 1343 1344 if (RFS4_MANDATTR_ONLY) 1345 return (ENOTSUP); 1346 1347 switch (cmd) { 1348 case NFS4ATTR_SUPPORTED: 1349 if (sarg->op == NFS4ATTR_SETIT) 1350 error = EINVAL; 1351 break; /* this attr is supported */ 1352 case NFS4ATTR_GETIT: 1353 case NFS4ATTR_VERIT: 1354 if (! sarg->mntdfid_set) 1355 error = rfs4_get_mntdfileid(cmd, sarg); 1356 1357 if (! error && sarg->mntdfid_set) { 1358 if (cmd == NFS4ATTR_GETIT) 1359 na->mounted_on_fileid = sarg->mounted_on_fileid; 1360 else 1361 if (na->mounted_on_fileid != 1362 sarg->mounted_on_fileid) 1363 error = -1; 1364 } 1365 break; 1366 case NFS4ATTR_SETIT: 1367 /* read-only attr */ 1368 error = EINVAL; 1369 break; 1370 case NFS4ATTR_FREEIT: 1371 break; 1372 } 1373 return (error); 1374 } 1375 1376 /* ARGSUSED */ 1377 static int 1378 rfs4_fattr4_files_avail(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1379 union nfs4_attr_u *na) 1380 { 1381 int error = 0; 1382 1383 if (RFS4_MANDATTR_ONLY) 1384 return (ENOTSUP); 1385 1386 switch (cmd) { 1387 case NFS4ATTR_SUPPORTED: 1388 if (sarg->op == NFS4ATTR_SETIT) 1389 error = EINVAL; 1390 break; /* this attr is supported */ 1391 case NFS4ATTR_GETIT: 1392 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 1393 error = -1; /* may be okay if rdattr_error */ 1394 break; 1395 } 1396 ASSERT(sarg->sbp != NULL); 1397 na->files_avail = sarg->sbp->f_favail; 1398 break; 1399 case NFS4ATTR_SETIT: 1400 /* 1401 * read-only attr 1402 */ 1403 error = EINVAL; 1404 break; 1405 case NFS4ATTR_VERIT: 1406 ASSERT(sarg->sbp != NULL); 1407 if (sarg->sbp->f_favail != na->files_avail) 1408 error = -1; /* no match */ 1409 break; 1410 case NFS4ATTR_FREEIT: 1411 break; 1412 } 1413 return (error); 1414 } 1415 1416 /* ARGSUSED */ 1417 static int 1418 rfs4_fattr4_files_free(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1419 union nfs4_attr_u *na) 1420 { 1421 int error = 0; 1422 1423 if (RFS4_MANDATTR_ONLY) 1424 return (ENOTSUP); 1425 1426 switch (cmd) { 1427 case NFS4ATTR_SUPPORTED: 1428 if (sarg->op == NFS4ATTR_SETIT) 1429 error = EINVAL; 1430 break; /* this attr is supported */ 1431 case NFS4ATTR_GETIT: 1432 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 1433 error = -1; /* may be okay if rdattr_error */ 1434 break; 1435 } 1436 ASSERT(sarg->sbp != NULL); 1437 na->files_free = sarg->sbp->f_ffree; 1438 break; 1439 case NFS4ATTR_SETIT: 1440 /* 1441 * read-only attr 1442 */ 1443 error = EINVAL; 1444 break; 1445 case NFS4ATTR_VERIT: 1446 ASSERT(sarg->sbp != NULL); 1447 if (sarg->sbp->f_ffree != na->files_free) 1448 error = -1; /* no match */ 1449 break; 1450 case NFS4ATTR_FREEIT: 1451 break; 1452 } 1453 return (error); 1454 } 1455 1456 /* ARGSUSED */ 1457 static int 1458 rfs4_fattr4_files_total(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1459 union nfs4_attr_u *na) 1460 { 1461 int error = 0; 1462 1463 if (RFS4_MANDATTR_ONLY) 1464 return (ENOTSUP); 1465 1466 switch (cmd) { 1467 case NFS4ATTR_SUPPORTED: 1468 if (sarg->op == NFS4ATTR_SETIT) 1469 error = EINVAL; 1470 break; /* this attr is supported */ 1471 case NFS4ATTR_GETIT: 1472 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 1473 error = -1; /* may be okay if rdattr_error */ 1474 break; 1475 } 1476 ASSERT(sarg->sbp != NULL); 1477 na->files_total = sarg->sbp->f_files; 1478 break; 1479 case NFS4ATTR_SETIT: 1480 /* 1481 * read-only attr 1482 */ 1483 error = EINVAL; 1484 break; 1485 case NFS4ATTR_VERIT: 1486 ASSERT(sarg->sbp != NULL); 1487 if (sarg->sbp->f_files != na->files_total) 1488 error = -1; /* no match */ 1489 break; 1490 case NFS4ATTR_FREEIT: 1491 break; 1492 } 1493 return (error); 1494 } 1495 1496 /* ARGSUSED */ 1497 static int 1498 rfs4_fattr4_fs_locations(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_hidden(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1507 union nfs4_attr_u *na) 1508 { 1509 return (ENOTSUP); 1510 } 1511 1512 /* ARGSUSED */ 1513 static int 1514 rfs4_fattr4_homogeneous(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1515 union nfs4_attr_u *na) 1516 { 1517 int error = 0; 1518 1519 if (RFS4_MANDATTR_ONLY) 1520 return (ENOTSUP); 1521 1522 switch (cmd) { 1523 case NFS4ATTR_SUPPORTED: 1524 if (sarg->op == NFS4ATTR_SETIT) 1525 error = EINVAL; 1526 break; /* this attr is supported */ 1527 case NFS4ATTR_GETIT: 1528 na->homogeneous = TRUE; /* XXX - need a VOP extension */ 1529 break; 1530 case NFS4ATTR_SETIT: 1531 /* 1532 * read-only attr 1533 */ 1534 error = EINVAL; 1535 break; 1536 case NFS4ATTR_VERIT: 1537 if (!na->homogeneous) 1538 error = -1; /* no match */ 1539 break; 1540 case NFS4ATTR_FREEIT: 1541 break; 1542 } 1543 return (error); 1544 } 1545 1546 /* ARGSUSED */ 1547 static int 1548 rfs4_fattr4_maxfilesize(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1549 union nfs4_attr_u *na) 1550 { 1551 int error = 0; 1552 ulong_t val; 1553 fattr4_maxfilesize maxfilesize; 1554 1555 if (RFS4_MANDATTR_ONLY) 1556 return (ENOTSUP); 1557 1558 switch (cmd) { 1559 case NFS4ATTR_SUPPORTED: 1560 if (sarg->op == NFS4ATTR_SETIT) 1561 error = EINVAL; 1562 break; /* this attr is supported */ 1563 case NFS4ATTR_GETIT: 1564 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) { 1565 error = -1; /* may be okay if rdattr_error */ 1566 break; 1567 } 1568 ASSERT(sarg->cs->vp != NULL); 1569 error = VOP_PATHCONF(sarg->cs->vp, _PC_FILESIZEBITS, &val, 1570 sarg->cs->cr, NULL); 1571 if (error) 1572 break; 1573 if (val >= (sizeof (uint64_t) * 8)) 1574 na->maxfilesize = UINT64_MAX; 1575 else 1576 na->maxfilesize = ((1LL << val) - 1); 1577 break; 1578 case NFS4ATTR_SETIT: 1579 /* 1580 * read-only attr 1581 */ 1582 error = EINVAL; 1583 break; 1584 case NFS4ATTR_VERIT: 1585 ASSERT(sarg->cs->vp != NULL); 1586 error = VOP_PATHCONF(sarg->cs->vp, _PC_FILESIZEBITS, &val, 1587 sarg->cs->cr, NULL); 1588 if (error) 1589 break; 1590 if (val >= (sizeof (uint64_t) * 8)) 1591 maxfilesize = UINT64_MAX; 1592 else 1593 maxfilesize = ((1LL << val) - 1); 1594 if (na->maxfilesize != maxfilesize) 1595 error = -1; /* no match */ 1596 break; 1597 case NFS4ATTR_FREEIT: 1598 break; 1599 } 1600 return (error); 1601 } 1602 1603 /* ARGSUSED */ 1604 static int 1605 rfs4_fattr4_maxlink(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1606 union nfs4_attr_u *na) 1607 { 1608 int error = 0; 1609 ulong_t val; 1610 1611 if (RFS4_MANDATTR_ONLY) 1612 return (ENOTSUP); 1613 1614 switch (cmd) { 1615 case NFS4ATTR_SUPPORTED: 1616 if (sarg->op == NFS4ATTR_SETIT) 1617 error = EINVAL; 1618 break; /* this attr is supported */ 1619 case NFS4ATTR_GETIT: 1620 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) { 1621 error = -1; /* may be okay if rdattr_error */ 1622 break; 1623 } 1624 ASSERT(sarg->cs->vp != NULL); 1625 error = VOP_PATHCONF(sarg->cs->vp, _PC_LINK_MAX, &val, 1626 sarg->cs->cr, NULL); 1627 if (error == 0) { 1628 na->maxlink = val; 1629 } 1630 break; 1631 case NFS4ATTR_SETIT: 1632 /* 1633 * read-only attr 1634 */ 1635 error = EINVAL; 1636 break; 1637 case NFS4ATTR_VERIT: 1638 ASSERT(sarg->cs->vp != NULL); 1639 error = VOP_PATHCONF(sarg->cs->vp, _PC_LINK_MAX, &val, 1640 sarg->cs->cr, NULL); 1641 if (!error && (na->maxlink != (uint32_t)val)) 1642 error = -1; /* no match */ 1643 break; 1644 case NFS4ATTR_FREEIT: 1645 break; 1646 } 1647 return (error); 1648 } 1649 1650 /* ARGSUSED */ 1651 static int 1652 rfs4_fattr4_maxname(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1653 union nfs4_attr_u *na) 1654 { 1655 int error = 0; 1656 ulong_t val; 1657 1658 if (RFS4_MANDATTR_ONLY) 1659 return (ENOTSUP); 1660 1661 switch (cmd) { 1662 case NFS4ATTR_SUPPORTED: 1663 if (sarg->op == NFS4ATTR_SETIT) 1664 error = EINVAL; 1665 break; /* this attr is supported */ 1666 case NFS4ATTR_GETIT: 1667 if (sarg->rdattr_error && (sarg->cs->vp == NULL)) { 1668 error = -1; /* may be okay if rdattr_error */ 1669 break; 1670 } 1671 ASSERT(sarg->cs->vp != NULL); 1672 error = VOP_PATHCONF(sarg->cs->vp, _PC_NAME_MAX, &val, 1673 sarg->cs->cr, NULL); 1674 if (error == 0) { 1675 na->maxname = val; 1676 } 1677 break; 1678 case NFS4ATTR_SETIT: 1679 /* 1680 * read-only attr 1681 */ 1682 error = EINVAL; 1683 break; 1684 case NFS4ATTR_VERIT: 1685 ASSERT(sarg->cs->vp != NULL); 1686 error = VOP_PATHCONF(sarg->cs->vp, _PC_NAME_MAX, &val, 1687 sarg->cs->cr, NULL); 1688 if (!error && (na->maxname != val)) 1689 error = -1; /* no match */ 1690 break; 1691 case NFS4ATTR_FREEIT: 1692 break; 1693 } 1694 return (error); 1695 } 1696 1697 /* ARGSUSED */ 1698 static int 1699 rfs4_fattr4_maxread(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1700 union nfs4_attr_u *na) 1701 { 1702 int error = 0; 1703 1704 if (RFS4_MANDATTR_ONLY) 1705 return (ENOTSUP); 1706 1707 switch (cmd) { 1708 case NFS4ATTR_SUPPORTED: 1709 if (sarg->op == NFS4ATTR_SETIT) 1710 error = EINVAL; 1711 break; /* this attr is supported */ 1712 case NFS4ATTR_GETIT: 1713 na->maxread = rfs4_tsize(sarg->cs->req); 1714 break; 1715 case NFS4ATTR_SETIT: 1716 /* 1717 * read-only attr 1718 */ 1719 error = EINVAL; 1720 break; 1721 case NFS4ATTR_VERIT: 1722 if (na->maxread != rfs4_tsize(sarg->cs->req)) 1723 error = -1; /* no match */ 1724 break; 1725 case NFS4ATTR_FREEIT: 1726 break; 1727 } 1728 return (error); 1729 } 1730 1731 /* ARGSUSED */ 1732 static int 1733 rfs4_fattr4_maxwrite(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1734 union nfs4_attr_u *na) 1735 { 1736 int error = 0; 1737 1738 if (RFS4_MANDATTR_ONLY) 1739 return (ENOTSUP); 1740 1741 switch (cmd) { 1742 case NFS4ATTR_SUPPORTED: 1743 if (sarg->op == NFS4ATTR_SETIT) 1744 error = EINVAL; 1745 break; /* this attr is supported */ 1746 case NFS4ATTR_GETIT: 1747 na->maxwrite = rfs4_tsize(sarg->cs->req); 1748 break; 1749 case NFS4ATTR_SETIT: 1750 /* 1751 * read-only attr 1752 */ 1753 error = EINVAL; 1754 break; 1755 case NFS4ATTR_VERIT: 1756 if (na->maxwrite != rfs4_tsize(sarg->cs->req)) 1757 error = -1; /* no match */ 1758 break; 1759 case NFS4ATTR_FREEIT: 1760 break; 1761 } 1762 return (error); 1763 } 1764 1765 /* ARGSUSED */ 1766 static int 1767 rfs4_fattr4_mimetype(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1768 union nfs4_attr_u *na) 1769 { 1770 return (ENOTSUP); 1771 } 1772 1773 /* ARGSUSED */ 1774 static int 1775 rfs4_fattr4_mode(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1776 union nfs4_attr_u *na) 1777 { 1778 int error = 0; 1779 1780 if (RFS4_MANDATTR_ONLY) 1781 return (ENOTSUP); 1782 1783 switch (cmd) { 1784 case NFS4ATTR_SUPPORTED: 1785 break; /* this attr is supported */ 1786 case NFS4ATTR_GETIT: 1787 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_MODE)) { 1788 error = -1; /* may be okay if rdattr_error */ 1789 break; 1790 } 1791 ASSERT(sarg->vap->va_mask & AT_MODE); 1792 na->mode = sarg->vap->va_mode; 1793 break; 1794 case NFS4ATTR_SETIT: 1795 ASSERT(sarg->vap->va_mask & AT_MODE); 1796 sarg->vap->va_mode = na->mode; 1797 /* 1798 * If the filesystem is exported with nosuid, then mask off 1799 * the setuid and setgid bits. 1800 */ 1801 if (sarg->cs->vp->v_type == VREG && 1802 (sarg->cs->exi->exi_export.ex_flags & EX_NOSUID)) 1803 sarg->vap->va_mode &= ~(VSUID | VSGID); 1804 break; 1805 case NFS4ATTR_VERIT: 1806 ASSERT(sarg->vap->va_mask & AT_MODE); 1807 if (sarg->vap->va_mode != na->mode) 1808 error = -1; /* no match */ 1809 break; 1810 case NFS4ATTR_FREEIT: 1811 break; 1812 } 1813 return (error); 1814 } 1815 1816 /* ARGSUSED */ 1817 static int 1818 rfs4_fattr4_no_trunc(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1819 union nfs4_attr_u *na) 1820 { 1821 int error = 0; 1822 1823 if (RFS4_MANDATTR_ONLY) 1824 return (ENOTSUP); 1825 1826 switch (cmd) { 1827 case NFS4ATTR_SUPPORTED: 1828 if (sarg->op == NFS4ATTR_SETIT) 1829 error = EINVAL; 1830 break; /* this attr is supported */ 1831 case NFS4ATTR_GETIT: 1832 na->no_trunc = TRUE; 1833 break; 1834 case NFS4ATTR_SETIT: 1835 /* 1836 * read-only attr 1837 */ 1838 error = EINVAL; 1839 break; 1840 case NFS4ATTR_VERIT: 1841 if (!na->no_trunc) 1842 error = -1; /* no match */ 1843 break; 1844 case NFS4ATTR_FREEIT: 1845 break; 1846 } 1847 return (error); 1848 } 1849 1850 /* ARGSUSED */ 1851 static int 1852 rfs4_fattr4_numlinks(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1853 union nfs4_attr_u *na) 1854 { 1855 int error = 0; 1856 1857 if (RFS4_MANDATTR_ONLY) 1858 return (ENOTSUP); 1859 1860 switch (cmd) { 1861 case NFS4ATTR_SUPPORTED: 1862 if (sarg->op == NFS4ATTR_SETIT) 1863 error = EINVAL; 1864 break; /* this attr is supported */ 1865 case NFS4ATTR_GETIT: 1866 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_NLINK)) { 1867 error = -1; /* may be okay if rdattr_error */ 1868 break; 1869 } 1870 ASSERT(sarg->vap->va_mask & AT_NLINK); 1871 na->numlinks = sarg->vap->va_nlink; 1872 break; 1873 case NFS4ATTR_SETIT: 1874 /* 1875 * read-only attr 1876 */ 1877 error = EINVAL; 1878 break; 1879 case NFS4ATTR_VERIT: 1880 ASSERT(sarg->vap->va_mask & AT_NLINK); 1881 if (sarg->vap->va_nlink != na->numlinks) 1882 error = -1; /* no match */ 1883 break; 1884 case NFS4ATTR_FREEIT: 1885 break; 1886 } 1887 return (error); 1888 } 1889 1890 /* ARGSUSED */ 1891 static int 1892 rfs4_fattr4_owner(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 1893 union nfs4_attr_u *na) 1894 { 1895 int error = 0; 1896 uid_t uid; 1897 1898 if (RFS4_MANDATTR_ONLY) 1899 return (ENOTSUP); 1900 1901 switch (cmd) { 1902 case NFS4ATTR_SUPPORTED: 1903 break; /* this attr is supported */ 1904 case NFS4ATTR_GETIT: 1905 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_UID)) { 1906 error = -1; /* may be okay if rdattr_error */ 1907 break; 1908 } 1909 ASSERT(sarg->vap->va_mask & AT_UID); 1910 1911 /* 1912 * There are well defined polices for what happens on server- 1913 * side GETATTR when uid to attribute string conversion cannot 1914 * occur. Please refer to nfs4_idmap.c for details. 1915 */ 1916 error = nfs_idmap_uid_str(sarg->vap->va_uid, &na->owner, TRUE); 1917 switch (error) { 1918 case ECONNREFUSED: 1919 error = NFS4ERR_DELAY; 1920 break; 1921 default: 1922 break; 1923 } 1924 break; 1925 1926 case NFS4ATTR_SETIT: 1927 ASSERT(sarg->vap->va_mask & AT_UID); 1928 1929 /* 1930 * There are well defined policies for what happens on server- 1931 * side SETATTR of 'owner' when a "user@domain" mapping cannot 1932 * occur. Please refer to nfs4_idmap.c for details. 1933 * 1934 * Any other errors, such as the mapping not being found by 1935 * nfsmapid(1m), and interrupted clnt_call, etc, will result 1936 * in NFS4ERR_BADOWNER. 1937 * 1938 * XXX need to return consistent errors, perhaps all 1939 * server side attribute routines should return NFS4ERR*. 1940 */ 1941 error = nfs_idmap_str_uid(&na->owner, &sarg->vap->va_uid, TRUE); 1942 switch (error) { 1943 case NFS4_OK: 1944 case ENOTSUP: 1945 /* 1946 * Ignore warning that we are the 1947 * nfsmapid (can't happen on srv) 1948 */ 1949 error = 0; 1950 MSG_PRT_DEBUG = FALSE; 1951 break; 1952 1953 case ECOMM: 1954 case ECONNREFUSED: 1955 if (!MSG_PRT_DEBUG) { 1956 /* 1957 * printed just once per daemon death, 1958 * inform the user and then stay silent 1959 */ 1960 cmn_err(CE_WARN, "!Unable to contact " 1961 "nfsmapid"); 1962 MSG_PRT_DEBUG = TRUE; 1963 } 1964 error = NFS4ERR_DELAY; 1965 break; 1966 1967 case EINVAL: 1968 error = NFS4ERR_INVAL; 1969 break; 1970 1971 default: 1972 error = NFS4ERR_BADOWNER; 1973 break; 1974 } 1975 break; 1976 1977 case NFS4ATTR_VERIT: 1978 ASSERT(sarg->vap->va_mask & AT_UID); 1979 error = nfs_idmap_str_uid(&na->owner, &uid, TRUE); 1980 /* 1981 * Ignore warning that we are the nfsmapid (can't happen on srv) 1982 */ 1983 if (error == ENOTSUP) 1984 error = 0; 1985 if (error) 1986 error = -1; /* no match */ 1987 else if (sarg->vap->va_uid != uid) 1988 error = -1; /* no match */ 1989 break; 1990 case NFS4ATTR_FREEIT: 1991 if (sarg->op == NFS4ATTR_GETIT) { 1992 if (na->owner.utf8string_val) { 1993 UTF8STRING_FREE(na->owner) 1994 bzero(&na->owner, sizeof (na->owner)); 1995 } 1996 } 1997 break; 1998 } 1999 return (error); 2000 } 2001 2002 /* ARGSUSED */ 2003 static int 2004 rfs4_fattr4_owner_group(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2005 union nfs4_attr_u *na) 2006 { 2007 int error = 0; 2008 gid_t gid; 2009 2010 if (RFS4_MANDATTR_ONLY) 2011 return (ENOTSUP); 2012 2013 switch (cmd) { 2014 case NFS4ATTR_SUPPORTED: 2015 break; /* this attr is supported */ 2016 case NFS4ATTR_GETIT: 2017 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_GID)) { 2018 error = -1; /* may be okay if rdattr_error */ 2019 break; 2020 } 2021 ASSERT(sarg->vap->va_mask & AT_GID); 2022 2023 /* 2024 * There are well defined polices for what happens on server- 2025 * side GETATTR when gid to attribute string conversion cannot 2026 * occur. Please refer to nfs4_idmap.c for details. 2027 */ 2028 error = nfs_idmap_gid_str(sarg->vap->va_gid, &na->owner_group, 2029 TRUE); 2030 switch (error) { 2031 case ECONNREFUSED: 2032 error = NFS4ERR_DELAY; 2033 break; 2034 default: 2035 break; 2036 } 2037 break; 2038 2039 case NFS4ATTR_SETIT: 2040 ASSERT(sarg->vap->va_mask & AT_GID); 2041 2042 /* 2043 * There are well defined policies for what happens on server- 2044 * side SETATTR of 'owner_group' when a "group@domain" mapping 2045 * cannot occur. Please refer to nfs4_idmap.c for details. 2046 * 2047 * Any other errors, such as the mapping not being found by 2048 * nfsmapid(1m), and interrupted clnt_call, etc, will result 2049 * in NFS4ERR_BADOWNER. 2050 * 2051 * XXX need to return consistent errors, perhaps all 2052 * server side attribute routines should return NFS4ERR*. 2053 */ 2054 error = nfs_idmap_str_gid(&na->owner_group, &sarg->vap->va_gid, 2055 TRUE); 2056 switch (error) { 2057 case NFS4_OK: 2058 case ENOTSUP: 2059 /* 2060 * Ignore warning that we are the 2061 * nfsmapid (can't happen on srv) 2062 */ 2063 error = 0; 2064 MSG_PRT_DEBUG = FALSE; 2065 break; 2066 2067 case ECOMM: 2068 case ECONNREFUSED: 2069 if (!MSG_PRT_DEBUG) { 2070 /* 2071 * printed just once per daemon death, 2072 * inform the user and then stay silent 2073 */ 2074 cmn_err(CE_WARN, "!Unable to contact " 2075 "nfsmapid"); 2076 MSG_PRT_DEBUG = TRUE; 2077 } 2078 error = NFS4ERR_DELAY; 2079 break; 2080 2081 case EINVAL: 2082 error = NFS4ERR_INVAL; 2083 break; 2084 2085 default: 2086 error = NFS4ERR_BADOWNER; 2087 break; 2088 } 2089 break; 2090 2091 case NFS4ATTR_VERIT: 2092 ASSERT(sarg->vap->va_mask & AT_GID); 2093 error = nfs_idmap_str_gid(&na->owner_group, &gid, TRUE); 2094 /* 2095 * Ignore warning that we are the nfsmapid (can't happen on srv) 2096 */ 2097 if (error == ENOTSUP) 2098 error = 0; 2099 if (error) 2100 error = -1; /* no match */ 2101 else if (sarg->vap->va_gid != gid) 2102 error = -1; /* no match */ 2103 break; 2104 case NFS4ATTR_FREEIT: 2105 if (sarg->op == NFS4ATTR_GETIT) { 2106 if (na->owner_group.utf8string_val) { 2107 UTF8STRING_FREE(na->owner_group) 2108 bzero(&na->owner_group, 2109 sizeof (na->owner_group)); 2110 } 2111 } 2112 break; 2113 } 2114 return (error); 2115 } 2116 2117 /* XXX - quota attributes should be supportable on Solaris 2 */ 2118 /* ARGSUSED */ 2119 static int 2120 rfs4_fattr4_quota_avail_hard(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_avail_soft(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_quota_used(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2137 union nfs4_attr_u *na) 2138 { 2139 return (ENOTSUP); 2140 } 2141 2142 /* ARGSUSED */ 2143 static int 2144 rfs4_fattr4_rawdev(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2145 union nfs4_attr_u *na) 2146 { 2147 int error = 0; 2148 2149 if (RFS4_MANDATTR_ONLY) 2150 return (ENOTSUP); 2151 2152 switch (cmd) { 2153 case NFS4ATTR_SUPPORTED: 2154 if (sarg->op == NFS4ATTR_SETIT) 2155 error = EINVAL; 2156 break; /* this attr is supported */ 2157 case NFS4ATTR_GETIT: 2158 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_RDEV)) { 2159 error = -1; /* may be okay if rdattr_error */ 2160 break; 2161 } 2162 ASSERT(sarg->vap->va_mask & AT_RDEV); 2163 na->rawdev.specdata1 = (uint32)getmajor(sarg->vap->va_rdev); 2164 na->rawdev.specdata2 = (uint32)getminor(sarg->vap->va_rdev); 2165 break; 2166 case NFS4ATTR_SETIT: 2167 /* 2168 * read-only attr 2169 */ 2170 error = EINVAL; 2171 break; 2172 case NFS4ATTR_VERIT: 2173 ASSERT(sarg->vap->va_mask & AT_RDEV); 2174 if ((na->rawdev.specdata1 != 2175 (uint32)getmajor(sarg->vap->va_rdev)) || 2176 (na->rawdev.specdata2 != 2177 (uint32)getminor(sarg->vap->va_rdev))) 2178 error = -1; /* no match */ 2179 break; 2180 case NFS4ATTR_FREEIT: 2181 break; 2182 } 2183 return (error); 2184 } 2185 2186 /* ARGSUSED */ 2187 static int 2188 rfs4_fattr4_space_avail(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2189 union nfs4_attr_u *na) 2190 { 2191 int error = 0; 2192 2193 if (RFS4_MANDATTR_ONLY) 2194 return (ENOTSUP); 2195 2196 switch (cmd) { 2197 case NFS4ATTR_SUPPORTED: 2198 if (sarg->op == NFS4ATTR_SETIT) 2199 error = EINVAL; 2200 break; /* this attr is supported */ 2201 case NFS4ATTR_GETIT: 2202 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 2203 error = -1; /* may be okay if rdattr_error */ 2204 break; 2205 } 2206 ASSERT(sarg->sbp != NULL); 2207 if (sarg->sbp->f_bavail != (fsblkcnt64_t)-1) { 2208 na->space_avail = 2209 (fattr4_space_avail) sarg->sbp->f_frsize * 2210 (fattr4_space_avail) sarg->sbp->f_bavail; 2211 } else { 2212 na->space_avail = 2213 (fattr4_space_avail) sarg->sbp->f_bavail; 2214 } 2215 break; 2216 case NFS4ATTR_SETIT: 2217 /* 2218 * read-only attr 2219 */ 2220 error = EINVAL; 2221 break; 2222 case NFS4ATTR_VERIT: 2223 ASSERT(sarg->sbp != NULL); 2224 if (sarg->sbp->f_bavail != na->space_avail) 2225 error = -1; /* no match */ 2226 break; 2227 case NFS4ATTR_FREEIT: 2228 break; 2229 } 2230 return (error); 2231 } 2232 2233 /* ARGSUSED */ 2234 static int 2235 rfs4_fattr4_space_free(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2236 union nfs4_attr_u *na) 2237 { 2238 int error = 0; 2239 2240 if (RFS4_MANDATTR_ONLY) 2241 return (ENOTSUP); 2242 2243 switch (cmd) { 2244 case NFS4ATTR_SUPPORTED: 2245 if (sarg->op == NFS4ATTR_SETIT) 2246 error = EINVAL; 2247 break; /* this attr is supported */ 2248 case NFS4ATTR_GETIT: 2249 if (sarg->rdattr_error && (sarg->sbp == NULL)) { 2250 error = -1; /* may be okay if rdattr_error */ 2251 break; 2252 } 2253 ASSERT(sarg->sbp != NULL); 2254 if (sarg->sbp->f_bfree != (fsblkcnt64_t)-1) { 2255 na->space_free = 2256 (fattr4_space_free) sarg->sbp->f_frsize * 2257 (fattr4_space_free) sarg->sbp->f_bfree; 2258 } else { 2259 na->space_free = 2260 (fattr4_space_free) sarg->sbp->f_bfree; 2261 } 2262 break; 2263 case NFS4ATTR_SETIT: 2264 /* 2265 * read-only attr 2266 */ 2267 error = EINVAL; 2268 break; 2269 case NFS4ATTR_VERIT: 2270 ASSERT(sarg->sbp != NULL); 2271 if (sarg->sbp->f_bfree != na->space_free) 2272 error = -1; /* no match */ 2273 break; 2274 case NFS4ATTR_FREEIT: 2275 break; 2276 } 2277 return (error); 2278 } 2279 2280 /* ARGSUSED */ 2281 static int 2282 rfs4_fattr4_space_total(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2283 union nfs4_attr_u *na) 2284 { 2285 int error = 0; 2286 2287 if (RFS4_MANDATTR_ONLY) 2288 return (ENOTSUP); 2289 2290 switch (cmd) { 2291 case NFS4ATTR_SUPPORTED: 2292 if (sarg->op == NFS4ATTR_SETIT) 2293 error = EINVAL; 2294 break; /* this attr is supported */ 2295 case NFS4ATTR_GETIT: 2296 if (sarg->rdattr_error_req && (sarg->sbp == NULL)) { 2297 error = -1; /* may be okay if rdattr_error */ 2298 break; 2299 } 2300 ASSERT(sarg->sbp != NULL); 2301 if (sarg->sbp->f_blocks != (fsblkcnt64_t)-1) { 2302 na->space_total = 2303 (fattr4_space_total) sarg->sbp->f_frsize * 2304 (fattr4_space_total) sarg->sbp->f_blocks; 2305 } else { 2306 na->space_total = 2307 (fattr4_space_total) sarg->sbp->f_blocks; 2308 } 2309 break; 2310 case NFS4ATTR_SETIT: 2311 /* 2312 * read-only attr 2313 */ 2314 error = EINVAL; 2315 break; 2316 case NFS4ATTR_VERIT: 2317 ASSERT(sarg->sbp != NULL); 2318 if (sarg->sbp->f_blocks != na->space_total) 2319 error = -1; /* no match */ 2320 break; 2321 case NFS4ATTR_FREEIT: 2322 break; 2323 } 2324 return (error); 2325 } 2326 2327 /* ARGSUSED */ 2328 static int 2329 rfs4_fattr4_space_used(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2330 union nfs4_attr_u *na) 2331 { 2332 int error = 0; 2333 2334 if (RFS4_MANDATTR_ONLY) 2335 return (ENOTSUP); 2336 2337 switch (cmd) { 2338 case NFS4ATTR_SUPPORTED: 2339 if (sarg->op == NFS4ATTR_SETIT) 2340 error = EINVAL; 2341 break; /* this attr is supported */ 2342 case NFS4ATTR_GETIT: 2343 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_NBLOCKS)) { 2344 error = -1; /* may be okay if rdattr_error */ 2345 break; 2346 } 2347 ASSERT(sarg->vap->va_mask & AT_NBLOCKS); 2348 na->space_used = (fattr4_space_used) DEV_BSIZE * 2349 (fattr4_space_used) sarg->vap->va_nblocks; 2350 break; 2351 case NFS4ATTR_SETIT: 2352 /* 2353 * read-only attr 2354 */ 2355 error = EINVAL; 2356 break; 2357 case NFS4ATTR_VERIT: 2358 ASSERT(sarg->vap->va_mask & AT_NBLOCKS); 2359 if (sarg->vap->va_nblocks != na->space_used) 2360 error = -1; /* no match */ 2361 break; 2362 case NFS4ATTR_FREEIT: 2363 break; 2364 } 2365 return (error); 2366 } 2367 2368 /* ARGSUSED */ 2369 static int 2370 rfs4_fattr4_system(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2371 union nfs4_attr_u *na) 2372 { 2373 return (ENOTSUP); 2374 } 2375 2376 /* ARGSUSED */ 2377 static int 2378 rfs4_fattr4_time_access(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2379 union nfs4_attr_u *na) 2380 { 2381 int error = 0; 2382 timestruc_t atime; 2383 2384 if (RFS4_MANDATTR_ONLY) 2385 return (ENOTSUP); 2386 2387 switch (cmd) { 2388 case NFS4ATTR_SUPPORTED: 2389 if (sarg->op == NFS4ATTR_SETIT) 2390 error = EINVAL; 2391 break; /* this attr is supported */ 2392 case NFS4ATTR_GETIT: 2393 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_ATIME)) { 2394 error = -1; /* may be okay if rdattr_error */ 2395 break; 2396 } 2397 ASSERT(sarg->vap->va_mask & AT_ATIME); 2398 error = nfs4_time_vton(&sarg->vap->va_atime, &na->time_access); 2399 break; 2400 case NFS4ATTR_SETIT: 2401 /* 2402 * read-only attr 2403 */ 2404 error = EINVAL; 2405 break; 2406 case NFS4ATTR_VERIT: 2407 ASSERT(sarg->vap->va_mask & AT_ATIME); 2408 error = nfs4_time_ntov(&na->time_access, &atime); 2409 if (error) 2410 break; 2411 if (bcmp(&atime, &sarg->vap->va_atime, sizeof (atime))) 2412 error = -1; /* no match */ 2413 break; 2414 case NFS4ATTR_FREEIT: 2415 break; 2416 } 2417 return (error); 2418 } 2419 2420 /* 2421 * XXX - need to support the setting of access time 2422 */ 2423 /* ARGSUSED */ 2424 static int 2425 rfs4_fattr4_time_access_set(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2426 union nfs4_attr_u *na) 2427 { 2428 int error = 0; 2429 settime4 *ta; 2430 2431 if (RFS4_MANDATTR_ONLY) 2432 return (ENOTSUP); 2433 2434 switch (cmd) { 2435 case NFS4ATTR_SUPPORTED: 2436 if ((sarg->op == NFS4ATTR_GETIT) || 2437 (sarg->op == NFS4ATTR_VERIT)) 2438 error = EINVAL; 2439 break; /* this attr is supported */ 2440 case NFS4ATTR_GETIT: 2441 case NFS4ATTR_VERIT: 2442 /* 2443 * write only attr 2444 */ 2445 error = EINVAL; 2446 break; 2447 case NFS4ATTR_SETIT: 2448 ASSERT(sarg->vap->va_mask & AT_ATIME); 2449 /* 2450 * Set access time (by server or by client) 2451 */ 2452 ta = &na->time_access_set; 2453 if (ta->set_it == SET_TO_CLIENT_TIME4) { 2454 error = nfs4_time_ntov(&ta->time, &sarg->vap->va_atime); 2455 } else if (ta->set_it == SET_TO_SERVER_TIME4) { 2456 gethrestime(&sarg->vap->va_atime); 2457 } else { 2458 error = EINVAL; 2459 } 2460 break; 2461 case NFS4ATTR_FREEIT: 2462 break; 2463 } 2464 return (error); 2465 } 2466 2467 /* ARGSUSED */ 2468 static int 2469 rfs4_fattr4_time_backup(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_create(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2478 union nfs4_attr_u *na) 2479 { 2480 return (ENOTSUP); 2481 } 2482 2483 /* ARGSUSED */ 2484 static int 2485 rfs4_fattr4_time_delta(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2486 union nfs4_attr_u *na) 2487 { 2488 int error = 0; 2489 2490 if (RFS4_MANDATTR_ONLY) 2491 return (ENOTSUP); 2492 2493 switch (cmd) { 2494 case NFS4ATTR_SUPPORTED: 2495 if (sarg->op == NFS4ATTR_SETIT) 2496 error = EINVAL; 2497 break; /* this attr is supported */ 2498 case NFS4ATTR_GETIT: 2499 na->time_delta.seconds = 0; 2500 na->time_delta.nseconds = 1000; 2501 break; 2502 case NFS4ATTR_SETIT: 2503 /* 2504 * write only attr 2505 */ 2506 error = EINVAL; 2507 break; 2508 case NFS4ATTR_VERIT: 2509 if ((na->time_delta.seconds != 0) || 2510 (na->time_delta.nseconds != 1000)) 2511 error = -1; /* no match */ 2512 break; 2513 case NFS4ATTR_FREEIT: 2514 break; 2515 } 2516 return (error); 2517 } 2518 2519 /* ARGSUSED */ 2520 static int 2521 rfs4_fattr4_time_metadata(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2522 union nfs4_attr_u *na) 2523 { 2524 int error = 0; 2525 timestruc_t ctime; 2526 2527 if (RFS4_MANDATTR_ONLY) 2528 return (ENOTSUP); 2529 2530 switch (cmd) { 2531 case NFS4ATTR_SUPPORTED: 2532 if (sarg->op == NFS4ATTR_SETIT) 2533 error = EINVAL; 2534 break; /* this attr is supported */ 2535 case NFS4ATTR_GETIT: 2536 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_CTIME)) { 2537 error = -1; /* may be okay if rdattr_error */ 2538 break; 2539 } 2540 ASSERT(sarg->vap->va_mask & AT_CTIME); 2541 error = nfs4_time_vton(&sarg->vap->va_ctime, 2542 &na->time_metadata); 2543 break; 2544 case NFS4ATTR_SETIT: 2545 /* 2546 * read-only attr 2547 */ 2548 error = EINVAL; 2549 break; 2550 case NFS4ATTR_VERIT: 2551 ASSERT(sarg->vap->va_mask & AT_CTIME); 2552 error = nfs4_time_ntov(&na->time_metadata, &ctime); 2553 if (error) 2554 break; 2555 if (bcmp(&ctime, &sarg->vap->va_ctime, sizeof (ctime))) 2556 error = -1; /* no match */ 2557 break; 2558 case NFS4ATTR_FREEIT: 2559 break; 2560 } 2561 return (error); 2562 } 2563 2564 /* ARGSUSED */ 2565 static int 2566 rfs4_fattr4_time_modify(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2567 union nfs4_attr_u *na) 2568 { 2569 int error = 0; 2570 timestruc_t mtime; 2571 2572 if (RFS4_MANDATTR_ONLY) 2573 return (ENOTSUP); 2574 2575 switch (cmd) { 2576 case NFS4ATTR_SUPPORTED: 2577 if (sarg->op == NFS4ATTR_SETIT) 2578 error = EINVAL; 2579 break; /* this attr is supported */ 2580 case NFS4ATTR_GETIT: 2581 if (sarg->rdattr_error && !(sarg->vap->va_mask & AT_MTIME)) { 2582 error = -1; /* may be okay if rdattr_error */ 2583 break; 2584 } 2585 ASSERT(sarg->vap->va_mask & AT_MTIME); 2586 error = nfs4_time_vton(&sarg->vap->va_mtime, &na->time_modify); 2587 break; 2588 case NFS4ATTR_SETIT: 2589 /* 2590 * read-only attr 2591 */ 2592 error = EINVAL; 2593 break; 2594 case NFS4ATTR_VERIT: 2595 ASSERT(sarg->vap->va_mask & AT_MTIME); 2596 error = nfs4_time_ntov(&na->time_modify, &mtime); 2597 if (error) 2598 break; 2599 if (bcmp(&mtime, &sarg->vap->va_mtime, sizeof (mtime))) 2600 error = -1; /* no match */ 2601 break; 2602 case NFS4ATTR_FREEIT: 2603 break; 2604 } 2605 return (error); 2606 } 2607 2608 /* 2609 * XXX - need to add support for setting modify time 2610 */ 2611 /* ARGSUSED */ 2612 static int 2613 rfs4_fattr4_time_modify_set(nfs4_attr_cmd_t cmd, struct nfs4_svgetit_arg *sarg, 2614 union nfs4_attr_u *na) 2615 { 2616 int error = 0; 2617 settime4 *tm; 2618 2619 if (RFS4_MANDATTR_ONLY) 2620 return (ENOTSUP); 2621 2622 switch (cmd) { 2623 case NFS4ATTR_SUPPORTED: 2624 if ((sarg->op == NFS4ATTR_GETIT) || 2625 (sarg->op == NFS4ATTR_VERIT)) 2626 error = EINVAL; 2627 break; /* this attr is supported */ 2628 case NFS4ATTR_GETIT: 2629 case NFS4ATTR_VERIT: 2630 /* 2631 * write only attr 2632 */ 2633 error = EINVAL; 2634 break; 2635 case NFS4ATTR_SETIT: 2636 ASSERT(sarg->vap->va_mask & AT_MTIME); 2637 /* 2638 * Set modify time (by server or by client) 2639 */ 2640 tm = &na->time_modify_set; 2641 if (tm->set_it == SET_TO_CLIENT_TIME4) { 2642 error = nfs4_time_ntov(&tm->time, &sarg->vap->va_mtime); 2643 sarg->flag = ATTR_UTIME; 2644 } else if (tm->set_it == SET_TO_SERVER_TIME4) { 2645 gethrestime(&sarg->vap->va_mtime); 2646 } else { 2647 error = EINVAL; 2648 } 2649 break; 2650 case NFS4ATTR_FREEIT: 2651 break; 2652 } 2653 return (error); 2654 } 2655 2656 2657 static void 2658 rfs4_ntov_init(void) 2659 { 2660 /* index must be same as corresponding FATTR4_* define */ 2661 nfs4_ntov_map[0].sv_getit = rfs4_fattr4_supported_attrs; 2662 nfs4_ntov_map[1].sv_getit = rfs4_fattr4_type; 2663 nfs4_ntov_map[2].sv_getit = rfs4_fattr4_fh_expire_type; 2664 nfs4_ntov_map[3].sv_getit = rfs4_fattr4_change; 2665 nfs4_ntov_map[4].sv_getit = rfs4_fattr4_size; 2666 nfs4_ntov_map[5].sv_getit = rfs4_fattr4_link_support; 2667 nfs4_ntov_map[6].sv_getit = rfs4_fattr4_symlink_support; 2668 nfs4_ntov_map[7].sv_getit = rfs4_fattr4_named_attr; 2669 nfs4_ntov_map[8].sv_getit = rfs4_fattr4_fsid; 2670 nfs4_ntov_map[9].sv_getit = rfs4_fattr4_unique_handles; 2671 nfs4_ntov_map[10].sv_getit = rfs4_fattr4_lease_time; 2672 nfs4_ntov_map[11].sv_getit = rfs4_fattr4_rdattr_error; 2673 nfs4_ntov_map[12].sv_getit = rfs4_fattr4_acl; 2674 nfs4_ntov_map[13].sv_getit = rfs4_fattr4_aclsupport; 2675 nfs4_ntov_map[14].sv_getit = rfs4_fattr4_archive; 2676 nfs4_ntov_map[15].sv_getit = rfs4_fattr4_cansettime; 2677 nfs4_ntov_map[16].sv_getit = rfs4_fattr4_case_insensitive; 2678 nfs4_ntov_map[17].sv_getit = rfs4_fattr4_case_preserving; 2679 nfs4_ntov_map[18].sv_getit = rfs4_fattr4_chown_restricted; 2680 nfs4_ntov_map[19].sv_getit = rfs4_fattr4_filehandle; 2681 nfs4_ntov_map[20].sv_getit = rfs4_fattr4_fileid; 2682 nfs4_ntov_map[21].sv_getit = rfs4_fattr4_files_avail; 2683 nfs4_ntov_map[22].sv_getit = rfs4_fattr4_files_free; 2684 nfs4_ntov_map[23].sv_getit = rfs4_fattr4_files_total; 2685 nfs4_ntov_map[24].sv_getit = rfs4_fattr4_fs_locations; 2686 nfs4_ntov_map[25].sv_getit = rfs4_fattr4_hidden; 2687 nfs4_ntov_map[26].sv_getit = rfs4_fattr4_homogeneous; 2688 nfs4_ntov_map[27].sv_getit = rfs4_fattr4_maxfilesize; 2689 nfs4_ntov_map[28].sv_getit = rfs4_fattr4_maxlink; 2690 nfs4_ntov_map[29].sv_getit = rfs4_fattr4_maxname; 2691 nfs4_ntov_map[30].sv_getit = rfs4_fattr4_maxread; 2692 nfs4_ntov_map[31].sv_getit = rfs4_fattr4_maxwrite; 2693 nfs4_ntov_map[32].sv_getit = rfs4_fattr4_mimetype; 2694 nfs4_ntov_map[33].sv_getit = rfs4_fattr4_mode; 2695 nfs4_ntov_map[34].sv_getit = rfs4_fattr4_no_trunc; 2696 nfs4_ntov_map[35].sv_getit = rfs4_fattr4_numlinks; 2697 nfs4_ntov_map[36].sv_getit = rfs4_fattr4_owner; 2698 nfs4_ntov_map[37].sv_getit = rfs4_fattr4_owner_group; 2699 nfs4_ntov_map[38].sv_getit = rfs4_fattr4_quota_avail_hard; 2700 nfs4_ntov_map[39].sv_getit = rfs4_fattr4_quota_avail_soft; 2701 nfs4_ntov_map[40].sv_getit = rfs4_fattr4_quota_used; 2702 nfs4_ntov_map[41].sv_getit = rfs4_fattr4_rawdev; 2703 nfs4_ntov_map[42].sv_getit = rfs4_fattr4_space_avail; 2704 nfs4_ntov_map[43].sv_getit = rfs4_fattr4_space_free; 2705 nfs4_ntov_map[44].sv_getit = rfs4_fattr4_space_total; 2706 nfs4_ntov_map[45].sv_getit = rfs4_fattr4_space_used; 2707 nfs4_ntov_map[46].sv_getit = rfs4_fattr4_system; 2708 nfs4_ntov_map[47].sv_getit = rfs4_fattr4_time_access; 2709 nfs4_ntov_map[48].sv_getit = rfs4_fattr4_time_access_set; 2710 nfs4_ntov_map[49].sv_getit = rfs4_fattr4_time_backup; 2711 nfs4_ntov_map[50].sv_getit = rfs4_fattr4_time_create; 2712 nfs4_ntov_map[51].sv_getit = rfs4_fattr4_time_delta; 2713 nfs4_ntov_map[52].sv_getit = rfs4_fattr4_time_metadata; 2714 nfs4_ntov_map[53].sv_getit = rfs4_fattr4_time_modify; 2715 nfs4_ntov_map[54].sv_getit = rfs4_fattr4_time_modify_set; 2716 nfs4_ntov_map[55].sv_getit = rfs4_fattr4_mounted_on_fileid; 2717 } 2718