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