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.
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.
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]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
29 #include <sys/systm.h>
30 #include <sys/cmn_err.h>
32 #include <nfs/export.h>
37 #include <nfs/nfssys.h>
39 void rfs4_init_compound_state(struct compound_state
*);
41 bitmap4 rfs4_supported_attrs
;
42 int MSG_PRT_DEBUG
= FALSE
;
44 /* If building with DEBUG enabled, enable mandattr tunable by default */
46 #ifndef RFS4_SUPPORT_MANDATTR_ONLY
47 #define RFS4_SUPPORT_MANDATTR_ONLY
52 * If building with mandattr only code, disable it by default.
53 * To enable, set rfs4_mandattr_only in /etc/system and reboot.
54 * When building without mandattr ifdef, the compiler should
55 * optimize away the the comparisons because RFS4_MANDATTR_ONLY
58 #ifdef RFS4_SUPPORT_MANDATTR_ONLY
59 #define NFS4_LAST_MANDATTR FATTR4_RDATTR_ERROR
60 #define RFS4_MANDATTR_ONLY rfs4_mandattr_only
61 int rfs4_mandattr_only
= 0;
63 #define RFS4_MANDATTR_ONLY 0
67 static void rfs4_ntov_init(void);
68 static int rfs4_fattr4_supported_attrs();
69 static int rfs4_fattr4_type();
70 static int rfs4_fattr4_fh_expire_type();
71 static int rfs4_fattr4_change();
72 static int rfs4_fattr4_size();
73 static int rfs4_fattr4_link_support();
74 static int rfs4_fattr4_symlink_support();
75 static int rfs4_fattr4_named_attr();
76 static int rfs4_fattr4_fsid();
77 static int rfs4_fattr4_unique_handles();
78 static int rfs4_fattr4_lease_time();
79 static int rfs4_fattr4_rdattr_error();
80 static int rfs4_fattr4_acl();
81 static int rfs4_fattr4_aclsupport();
82 static int rfs4_fattr4_archive();
83 static int rfs4_fattr4_cansettime();
84 static int rfs4_fattr4_case_insensitive();
85 static int rfs4_fattr4_case_preserving();
86 static int rfs4_fattr4_chown_restricted();
87 static int rfs4_fattr4_filehandle();
88 static int rfs4_fattr4_fileid();
89 static int rfs4_fattr4_files_avail();
90 static int rfs4_fattr4_files_free();
91 static int rfs4_fattr4_files_total();
92 static int rfs4_fattr4_fs_locations();
93 static int rfs4_fattr4_hidden();
94 static int rfs4_fattr4_homogeneous();
95 static int rfs4_fattr4_maxfilesize();
96 static int rfs4_fattr4_maxlink();
97 static int rfs4_fattr4_maxname();
98 static int rfs4_fattr4_maxread();
99 static int rfs4_fattr4_maxwrite();
100 static int rfs4_fattr4_mimetype();
101 static int rfs4_fattr4_mode();
102 static int rfs4_fattr4_no_trunc();
103 static int rfs4_fattr4_numlinks();
104 static int rfs4_fattr4_owner();
105 static int rfs4_fattr4_owner_group();
106 static int rfs4_fattr4_quota_avail_hard();
107 static int rfs4_fattr4_quota_avail_soft();
108 static int rfs4_fattr4_quota_used();
109 static int rfs4_fattr4_rawdev();
110 static int rfs4_fattr4_space_avail();
111 static int rfs4_fattr4_space_free();
112 static int rfs4_fattr4_space_total();
113 static int rfs4_fattr4_space_used();
114 static int rfs4_fattr4_system();
115 static int rfs4_fattr4_time_access();
116 static int rfs4_fattr4_time_access_set();
117 static int rfs4_fattr4_time_backup();
118 static int rfs4_fattr4_time_create();
119 static int rfs4_fattr4_time_delta();
120 static int rfs4_fattr4_time_metadata();
121 static int rfs4_fattr4_time_modify();
122 static int rfs4_fattr4_time_modify_set();
125 * Initialize the supported attributes
131 struct nfs4_svgetit_arg sarg
;
132 struct compound_state cs
;
135 rfs4_init_compound_state(&cs
);
137 cs
.fh
.nfs_fh4_val
= NULL
;
141 * Get all the supported attributes
143 sarg
.op
= NFS4ATTR_SUPPORTED
;
145 sarg
.vap
->va_mask
= VATTR_ALL
;
148 sarg
.rdattr_error
= NFS4_OK
;
149 sarg
.rdattr_error_req
= FALSE
;
150 sarg
.is_referral
= B_FALSE
;
154 rfs4_supported_attrs
= 0;
155 for (i
= 0; i
< NFS4_MAXNUM_ATTRS
; i
++) {
156 #ifdef RFS4_SUPPORT_MANDATTR_ONLY
157 if (rfs4_mandattr_only
== TRUE
&& i
> NFS4_LAST_MANDATTR
)
160 if ((*nfs4_ntov_map
[i
].sv_getit
)(NFS4ATTR_SUPPORTED
,
162 rfs4_supported_attrs
|= nfs4_ntov_map
[i
].fbit
;
168 * The following rfs4_fattr4_* functions convert between the fattr4
169 * arguments/attributes and the system (e.g. vattr) values. The following
170 * commands are currently in use:
172 * NFS4ATTR_SUPPORTED: checks if the attribute in question is supported:
173 * sarg.op = SUPPORTED - all supported attrs
174 * sarg.op = GETIT - only supported readable attrs
175 * sarg.op = SETIT - only supported writable attrs
177 * NFS4ATTR_GETIT: getattr type conversion - convert system values
178 * (e.g. vattr struct) to fattr4 type values to be returned to the
179 * user - usually in response to nfsv4 getattr request.
181 * NFS4ATTR_SETIT: convert fattr4 type values to system values to use by
182 * setattr. Allows only read/write and write attributes,
183 * even if not supported by the filesystem. Note that ufs only allows setattr
184 * of owner/group, mode, size, atime/mtime.
186 * NFS4ATTR_VERIT: convert fattr4 type values to system values to use by
187 * verify/nverify. Implemented to allow
188 * almost everything that can be returned by getattr into known structs
189 * (like vfsstat64 or vattr_t), that is, both read only and read/write attrs.
190 * The function will return -1 if it found that the arguments don't match.
191 * This applies to system-wide values that don't require a fop_getattr
192 * or other further checks to verify. It will return no error if they
193 * either match or were retrieved successfully for later checking.
195 * NFS4ATTR_FREEIT: free up any space allocated by either of the above.
196 * The sargp->op should be either NFS4ATTR_GETIT or NFS4ATTR_SETIT
197 * to indicate which op was used to allocate the space.
199 * XXX Note: these functions are currently used by the server only. A
200 * XXX different method of conversion is used on the client side.
201 * XXX Eventually combining the two (possibly by adding NFS4ATTR_CLNT_GETIT
202 * XXX and SETIT) may be a cleaner approach.
206 * Mandatory attributes
211 rfs4_fattr4_supported_attrs(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
212 union nfs4_attr_u
*na
)
217 case NFS4ATTR_SUPPORTED
:
218 if (sarg
->op
== NFS4ATTR_SETIT
)
220 break; /* this attr is supported */
222 na
->supported_attrs
= rfs4_supported_attrs
;
232 * Compare the input bitmap to the server's bitmap
234 if (na
->supported_attrs
!= rfs4_supported_attrs
) {
235 error
= -1; /* no match */
238 case NFS4ATTR_FREEIT
:
245 * Translate vnode vtype to nfsv4_ftype.
247 static nfs_ftype4 vt_to_nf4
[] = {
248 0, NF4REG
, NF4DIR
, NF4BLK
, NF4CHR
, NF4LNK
, NF4FIFO
, 0, 0, NF4SOCK
, 0
253 rfs4_fattr4_type(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
254 union nfs4_attr_u
*na
)
259 case NFS4ATTR_SUPPORTED
:
260 if (sarg
->op
== NFS4ATTR_SETIT
)
262 break; /* this attr is supported */
264 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_TYPE
)) {
265 error
= -1; /* may be okay if rdattr_error */
268 ASSERT(sarg
->vap
->va_mask
& VATTR_TYPE
);
271 * if xattr flag not set, use v4_to_nf4 mapping;
272 * otherwise verify xattr flag is in sync with va_type
273 * and set xattr types.
275 if (! (sarg
->xattr
& (FH4_NAMEDATTR
| FH4_ATTRDIR
)))
276 na
->type
= vt_to_nf4
[sarg
->vap
->va_type
];
279 * FH4 flag was set. Dir type maps to attrdir,
280 * and all other types map to namedattr.
282 if (sarg
->vap
->va_type
== VDIR
)
283 na
->type
= NF4ATTRDIR
;
285 na
->type
= NF4NAMEDATTR
;
296 * Compare the input type to the object type on server
298 ASSERT(sarg
->vap
->va_mask
& VATTR_TYPE
);
299 if (sarg
->vap
->va_type
!= nf4_to_vt
[na
->type
])
300 error
= -1; /* no match */
302 case NFS4ATTR_FREEIT
:
310 fattr4_get_fh_expire_type(struct exportinfo
*exi
, uint32_t *fh_expire_typep
)
312 #ifdef VOLATILE_FH_TEST
317 ex_flags
= exi
->exi_export
.ex_flags
;
318 if ((ex_flags
& (EX_VOLFH
| EX_VOLRNM
| EX_VOLMIG
| EX_NOEXPOPEN
))
320 *fh_expire_typep
= FH4_PERSISTENT
;
323 *fh_expire_typep
= 0;
325 if (ex_flags
& EX_NOEXPOPEN
) {
326 /* file handles should not expire with open - not used */
327 *fh_expire_typep
= FH4_NOEXPIRE_WITH_OPEN
;
329 if (ex_flags
& EX_VOLFH
) {
331 * file handles may expire any time - on share here.
332 * If volatile any, no need to check other flags.
334 *fh_expire_typep
|= FH4_VOLATILE_ANY
;
337 if (ex_flags
& EX_VOLRNM
) {
338 /* file handles may expire on rename */
339 *fh_expire_typep
|= FH4_VOL_RENAME
;
341 if (ex_flags
& EX_VOLMIG
) {
342 /* file handles may expire on migration - not used */
343 *fh_expire_typep
|= FH4_VOL_MIGRATION
;
345 #else /* not VOLATILE_FH_TEST */
346 *fh_expire_typep
= FH4_PERSISTENT
;
347 #endif /* VOLATILE_FH_TEST */
353 * At this point the only volatile filehandles we allow (for test purposes
354 * only) are either fh's that expire when the filesystem is shared (reshared),
355 * fh's that expire on a rename and persistent ones.
359 rfs4_fattr4_fh_expire_type(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
360 union nfs4_attr_u
*na
)
362 uint32_t fh_expire_type
;
366 case NFS4ATTR_SUPPORTED
:
367 if (sarg
->op
== NFS4ATTR_SETIT
)
369 break; /* this attr is supported */
371 error
= fattr4_get_fh_expire_type(sarg
->cs
->exi
,
372 &na
->fh_expire_type
);
381 error
= fattr4_get_fh_expire_type(sarg
->cs
->exi
,
383 if (!error
&& (na
->fh_expire_type
!= fh_expire_type
))
384 error
= -1; /* no match */
386 case NFS4ATTR_FREEIT
:
393 fattr4_get_change(struct nfs4_svgetit_arg
*sarg
, fattr4_change
*changep
)
395 vattr_t vap2
[1], *vap
= sarg
->vap
;
396 struct compound_state
*cs
= sarg
->cs
;
397 vnode_t
*vp
= cs
->vp
;
399 timespec_t vis_change
;
401 if ((vap
->va_mask
& VATTR_CTIME
) == 0) {
402 if (sarg
->rdattr_error
&& (vp
== NULL
)) {
403 return (-1); /* may be okay if rdattr_error */
407 vap
->va_mask
= VATTR_CTIME
;
408 status
= rfs4_vop_getattr(vp
, vap
, 0, cs
->cr
);
409 if (status
!= NFS4_OK
)
410 return (geterrno4(status
));
412 NFS4_SET_FATTR4_CHANGE(*changep
, vap
->va_ctime
);
414 if (nfs_visible_change(cs
->exi
, vp
, &vis_change
)) {
416 NFS4_SET_FATTR4_CHANGE(visch
, vis_change
);
417 if (visch
> *changep
)
426 rfs4_fattr4_change(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
427 union nfs4_attr_u
*na
)
430 fattr4_change change
;
432 vattr_t
*vap
= sarg
->vap
;
435 case NFS4ATTR_SUPPORTED
:
436 if (sarg
->op
== NFS4ATTR_SETIT
)
438 break; /* this attr is supported */
440 error
= fattr4_get_change(sarg
, &na
->change
);
450 vap
->va_mask
&= ~VATTR_CTIME
; /* force a fop_getattr */
451 error
= fattr4_get_change(sarg
, &change
);
453 if (!error
&& (na
->change
!= change
))
456 case NFS4ATTR_FREEIT
:
464 rfs4_fattr4_size(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
465 union nfs4_attr_u
*na
)
470 case NFS4ATTR_SUPPORTED
:
471 break; /* this attr is supported */
473 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_SIZE
)) {
474 error
= -1; /* may be okay if rdattr_error */
477 ASSERT(sarg
->vap
->va_mask
& VATTR_SIZE
);
478 na
->size
= sarg
->vap
->va_size
;
481 ASSERT(sarg
->vap
->va_mask
& VATTR_SIZE
);
482 sarg
->vap
->va_size
= na
->size
;
485 ASSERT(sarg
->vap
->va_mask
& VATTR_SIZE
);
486 if (sarg
->vap
->va_size
!= na
->size
)
487 error
= -1; /* no match */
489 case NFS4ATTR_FREEIT
:
496 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports
501 rfs4_fattr4_link_support(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
502 union nfs4_attr_u
*na
)
507 case NFS4ATTR_SUPPORTED
:
508 if (sarg
->op
== NFS4ATTR_SETIT
)
510 break; /* this attr is supported */
512 na
->link_support
= TRUE
;
521 if (!na
->link_support
)
522 error
= -1; /* no match */
524 case NFS4ATTR_FREEIT
:
531 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports
536 rfs4_fattr4_symlink_support(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
537 union nfs4_attr_u
*na
)
542 case NFS4ATTR_SUPPORTED
:
543 if (sarg
->op
== NFS4ATTR_SETIT
)
545 break; /* this attr is supported */
547 na
->symlink_support
= TRUE
;
556 if (!na
->symlink_support
)
557 error
= -1; /* no match */
559 case NFS4ATTR_FREEIT
:
567 rfs4_fattr4_named_attr(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
568 union nfs4_attr_u
*na
)
574 case NFS4ATTR_SUPPORTED
:
575 if (sarg
->op
== NFS4ATTR_SETIT
)
577 break; /* this attr is supported */
579 if (sarg
->rdattr_error
&& (sarg
->cs
->vp
== NULL
)) {
580 error
= -1; /* may be okay if rdattr_error */
583 ASSERT(sarg
->cs
->vp
!= NULL
);
586 * Solaris xattr model requires that VFS_XATTR is set
587 * in file systems enabled for generic xattr. If VFS_XATTR
588 * not set, no need to call pathconf for _PC_XATTR_EXISTS..
590 * However the VFS_XATTR flag doesn't indicate sysattr support
591 * so always check for sysattrs and then only do the
592 * _PC_XATTR_EXISTS pathconf if needed.
596 error
= fop_pathconf(sarg
->cs
->vp
, _PC_SATTR_EXISTS
,
597 &val
, sarg
->cs
->cr
, NULL
);
598 if ((error
|| val
== 0) &&
599 sarg
->cs
->vp
->v_vfsp
->vfs_flag
& VFS_XATTR
) {
600 error
= fop_pathconf(sarg
->cs
->vp
,
601 _PC_XATTR_EXISTS
, &val
, sarg
->cs
->cr
, NULL
);
605 na
->named_attr
= (val
? TRUE
: FALSE
);
614 ASSERT(sarg
->cs
->vp
!= NULL
);
615 if (sarg
->cs
->vp
->v_vfsp
->vfs_flag
& VFS_XATTR
) {
616 error
= fop_pathconf(sarg
->cs
->vp
, _PC_SATTR_EXISTS
,
617 &val
, sarg
->cs
->cr
, NULL
);
618 if (error
|| val
== 0)
619 error
= fop_pathconf(sarg
->cs
->vp
,
620 _PC_XATTR_EXISTS
, &val
,
626 if (na
->named_attr
!= (val
? TRUE
: FALSE
))
627 error
= -1; /* no match */
629 case NFS4ATTR_FREEIT
:
637 rfs4_fattr4_fsid(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
638 union nfs4_attr_u
*na
)
641 int *pmaj
= (int *)&na
->fsid
.major
;
644 * fsid_t is 64bits so it fits completely in fattr4_fsid.major.
645 * fattr4_fsid.minor is always set to 0 since it isn't needed (yet).
648 case NFS4ATTR_SUPPORTED
:
649 if (sarg
->op
== NFS4ATTR_SETIT
)
651 break; /* this attr is supported */
653 if (sarg
->is_referral
) {
656 } else if (sarg
->cs
->exi
->exi_volatile_dev
) {
657 pmaj
[0] = sarg
->cs
->exi
->exi_fsid
.val
[0];
658 pmaj
[1] = sarg
->cs
->exi
->exi_fsid
.val
[1];
661 na
->fsid
.major
= getmajor(sarg
->vap
->va_fsid
);
662 na
->fsid
.minor
= getminor(sarg
->vap
->va_fsid
);
669 if (sarg
->is_referral
) {
670 if (na
->fsid
.major
!= 1 ||
673 } else if (sarg
->cs
->exi
->exi_volatile_dev
) {
674 if (pmaj
[0] != sarg
->cs
->exi
->exi_fsid
.val
[0] ||
675 pmaj
[1] != sarg
->cs
->exi
->exi_fsid
.val
[1] ||
679 if (na
->fsid
.major
!= getmajor(sarg
->vap
->va_fsid
) ||
680 na
->fsid
.minor
!= getminor(sarg
->vap
->va_fsid
))
684 case NFS4ATTR_FREEIT
:
692 rfs4_fattr4_unique_handles(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
693 union nfs4_attr_u
*na
)
697 * For now, we can't support this. Problem of /export, beinging
698 * a file system, /export/a and /export/b shared separately,
699 * and /export/a/l and /export/b/l are ahrd links of each other.
704 case NFS4ATTR_SUPPORTED
:
705 if (sarg
->op
== NFS4ATTR_SETIT
)
707 break; /* this attr is supported */
709 na
->unique_handles
= FALSE
;
718 if (na
->unique_handles
)
719 error
= -1; /* no match */
721 case NFS4ATTR_FREEIT
:
729 rfs4_fattr4_lease_time(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
730 union nfs4_attr_u
*na
)
735 case NFS4ATTR_SUPPORTED
:
736 if (sarg
->op
== NFS4ATTR_SETIT
)
738 break; /* this attr is supported */
740 na
->lease_time
= rfs4_lease_time
;
749 if (na
->lease_time
!= rfs4_lease_time
)
750 error
= -1; /* no match */
752 case NFS4ATTR_FREEIT
:
760 rfs4_fattr4_rdattr_error(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
761 union nfs4_attr_u
*na
)
766 case NFS4ATTR_SUPPORTED
:
767 if ((sarg
->op
== NFS4ATTR_SETIT
) ||
768 (sarg
->op
== NFS4ATTR_VERIT
))
770 break; /* this attr is supported */
772 ASSERT(sarg
->rdattr_error_req
);
773 na
->rdattr_error
= sarg
->rdattr_error
;
782 case NFS4ATTR_FREEIT
:
789 * Server side compare of a filehandle from the wire to a native
793 rfs4fhcmp(nfs_fh4
*wirefh
, nfs_fh4
*srvfh
)
797 ASSERT(IS_P2ALIGNED(wirefh
->nfs_fh4_val
, sizeof (uint32_t)));
799 bzero(&fh
, sizeof (nfs_fh4_fmt_t
));
800 if (!xdr_inline_decode_nfs_fh4((uint32_t *)wirefh
->nfs_fh4_val
, &fh
,
801 wirefh
->nfs_fh4_len
))
804 return (bcmp(srvfh
->nfs_fh4_val
, &fh
, srvfh
->nfs_fh4_len
));
809 rfs4_fattr4_filehandle(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
810 union nfs4_attr_u
*na
)
815 case NFS4ATTR_SUPPORTED
:
816 if (sarg
->op
== NFS4ATTR_SETIT
)
818 return (0); /* this attr is supported */
821 * If sarg->cs->fh is all zeros then should makefh a new
822 * one, otherwise, copy that one over.
825 if (sarg
->cs
->fh
.nfs_fh4_len
== 0) {
826 if (sarg
->rdattr_error
&& (sarg
->cs
->vp
== NULL
))
827 return (-1); /* okay if rdattr_error */
828 ASSERT(sarg
->cs
->vp
!= NULL
);
829 na
->filehandle
.nfs_fh4_val
=
830 kmem_alloc(NFS_FH4_LEN
, KM_SLEEP
);
831 return (makefh4(&na
->filehandle
, sarg
->cs
->vp
,
834 na
->filehandle
.nfs_fh4_val
=
835 kmem_alloc(fh
->nfs_fh4_len
, KM_SLEEP
);
836 nfs_fh4_copy(fh
, &na
->filehandle
);
845 * A verify of a filehandle will have the client sending
846 * the raw format which needs to be compared to the
849 if (rfs4fhcmp(&na
->filehandle
, &sarg
->cs
->fh
) == 1)
850 return (-1); /* no match */
852 case NFS4ATTR_FREEIT
:
853 if (sarg
->op
!= NFS4ATTR_GETIT
)
855 if (na
->filehandle
.nfs_fh4_val
== NULL
)
857 kmem_free(na
->filehandle
.nfs_fh4_val
,
858 na
->filehandle
.nfs_fh4_len
);
859 na
->filehandle
.nfs_fh4_val
= NULL
;
860 na
->filehandle
.nfs_fh4_len
= 0;
867 * Recommended attributes
872 rfs4_fattr4_acl(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
873 union nfs4_attr_u
*na
)
876 vsecattr_t vs_native
, vs_ace4
;
879 vattr_t va
, *vap
= sarg
->vap
;
880 vnode_t
*vp
= sarg
->cs
->vp
;
882 if (RFS4_MANDATTR_ONLY
)
886 case NFS4ATTR_SUPPORTED
:
891 if (sarg
->rdattr_error
&& (vp
== NULL
)) {
895 bzero(&vs_native
, sizeof (vs_native
));
897 /* see which ACLs fs supports */
898 error
= fop_pathconf(vp
, _PC_ACL_ENABLED
, &whichacl
,
902 * If we got an error, then the filesystem
903 * likely does not understand the _PC_ACL_ENABLED
904 * pathconf. In this case, we fall back to trying
905 * POSIX-draft (aka UFS-style) ACLs, since that's
906 * the behavior used by earlier version of NFS.
909 whichacl
= _ACL_ACLENT_ENABLED
;
912 if (!(whichacl
& (_ACL_ACE_ENABLED
| _ACL_ACLENT_ENABLED
))) {
914 * If the file system supports neither ACE nor
915 * ACLENT ACLs we will fall back to UFS-style ACLs
916 * like we did above if there was an error upon
917 * calling fop_pathconf.
919 * ACE and ACLENT type ACLs are the only interfaces
920 * supported thus far. If any other bits are set on
921 * 'whichacl' upon return from fop_pathconf, we will
924 whichacl
= _ACL_ACLENT_ENABLED
;
927 if (whichacl
& _ACL_ACE_ENABLED
)
928 vs_native
.vsa_mask
= VSA_ACE
| VSA_ACECNT
;
929 else if (whichacl
& _ACL_ACLENT_ENABLED
)
930 vs_native
.vsa_mask
= VSA_ACL
| VSA_ACLCNT
|
931 VSA_DFACL
| VSA_DFACLCNT
;
936 /* get the ACL, and translate it into nfsace4 style */
937 error
= fop_getsecattr(vp
, &vs_native
,
938 0, sarg
->cs
->cr
, NULL
);
941 if (whichacl
& _ACL_ACE_ENABLED
) {
942 error
= vs_acet_to_ace4(&vs_native
, &vs_ace4
, TRUE
);
943 vs_acet_destroy(&vs_native
);
945 error
= vs_aent_to_ace4(&vs_native
, &vs_ace4
,
946 vp
->v_type
== VDIR
, TRUE
);
947 vs_aent_destroy(&vs_native
);
952 if (cmd
== NFS4ATTR_GETIT
) {
953 na
->acl
.fattr4_acl_len
= vs_ace4
.vsa_aclcnt
;
954 /* see case NFS4ATTR_FREEIT for this being freed */
955 na
->acl
.fattr4_acl_val
= vs_ace4
.vsa_aclentp
;
957 if (na
->acl
.fattr4_acl_len
!= vs_ace4
.vsa_aclcnt
)
958 error
= -1; /* no match */
959 else if (ln_ace4_cmp(na
->acl
.fattr4_acl_val
,
961 vs_ace4
.vsa_aclcnt
) != 0)
962 error
= -1; /* no match */
968 if (sarg
->rdattr_error
&& (vp
== NULL
)) {
973 /* prepare vs_ace4 from fattr4 data */
974 bzero(&vs_ace4
, sizeof (vs_ace4
));
975 vs_ace4
.vsa_mask
= VSA_ACE
| VSA_ACECNT
;
976 vs_ace4
.vsa_aclcnt
= na
->acl
.fattr4_acl_len
;
977 vs_ace4
.vsa_aclentp
= na
->acl
.fattr4_acl_val
;
978 vs_ace4
.vsa_aclentsz
= vs_ace4
.vsa_aclcnt
* sizeof (ace_t
);
979 /* make sure we have correct owner/group */
980 if ((vap
->va_mask
& (VATTR_UID
| VATTR_GID
)) !=
981 (VATTR_UID
| VATTR_GID
)) {
983 vap
->va_mask
= VATTR_UID
| VATTR_GID
;
984 status
= rfs4_vop_getattr(vp
,
985 vap
, 0, sarg
->cs
->cr
);
986 if (status
!= NFS4_OK
)
987 return (geterrno4(status
));
990 /* see which ACLs the fs supports */
991 error
= fop_pathconf(vp
, _PC_ACL_ENABLED
, &whichacl
,
995 * If we got an error, then the filesystem
996 * likely does not understand the _PC_ACL_ENABLED
997 * pathconf. In this case, we fall back to trying
998 * POSIX-draft (aka UFS-style) ACLs, since that's
999 * the behavior used by earlier version of NFS.
1002 whichacl
= _ACL_ACLENT_ENABLED
;
1005 if (!(whichacl
& (_ACL_ACLENT_ENABLED
| _ACL_ACE_ENABLED
))) {
1007 * If the file system supports neither ACE nor
1008 * ACLENT ACLs we will fall back to UFS-style ACLs
1009 * like we did above if there was an error upon
1010 * calling fop_pathconf.
1012 * ACE and ACLENT type ACLs are the only interfaces
1013 * supported thus far. If any other bits are set on
1014 * 'whichacl' upon return from fop_pathconf, we will
1017 whichacl
= _ACL_ACLENT_ENABLED
;
1020 if (whichacl
& _ACL_ACE_ENABLED
) {
1021 error
= vs_ace4_to_acet(&vs_ace4
, &vs_native
,
1022 vap
->va_uid
, vap
->va_gid
, TRUE
);
1025 (void) fop_rwlock(vp
, V_WRITELOCK_TRUE
, NULL
);
1026 error
= fop_setsecattr(vp
, &vs_native
,
1027 0, sarg
->cs
->cr
, NULL
);
1028 fop_rwunlock(vp
, V_WRITELOCK_TRUE
, NULL
);
1029 vs_acet_destroy(&vs_native
);
1030 } else if (whichacl
& _ACL_ACLENT_ENABLED
) {
1031 error
= vs_ace4_to_aent(&vs_ace4
, &vs_native
,
1032 vap
->va_uid
, vap
->va_gid
, vp
->v_type
== VDIR
, TRUE
);
1035 (void) fop_rwlock(vp
, V_WRITELOCK_TRUE
, NULL
);
1036 error
= fop_setsecattr(vp
, &vs_native
,
1037 0, sarg
->cs
->cr
, NULL
);
1038 fop_rwunlock(vp
, V_WRITELOCK_TRUE
, NULL
);
1039 vs_aent_destroy(&vs_native
);
1043 case NFS4ATTR_FREEIT
:
1044 if (sarg
->op
== NFS4ATTR_GETIT
) {
1045 vs_ace4
.vsa_mask
= VSA_ACE
| VSA_ACECNT
;
1046 vs_ace4
.vsa_aclcnt
= na
->acl
.fattr4_acl_len
;
1047 vs_ace4
.vsa_aclentp
= na
->acl
.fattr4_acl_val
;
1048 vs_ace4_destroy(&vs_ace4
);
1058 rfs4_fattr4_aclsupport(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1059 union nfs4_attr_u
*na
)
1063 if (RFS4_MANDATTR_ONLY
)
1067 case NFS4ATTR_SUPPORTED
:
1068 if (sarg
->op
== NFS4ATTR_SETIT
)
1070 break; /* supported */
1071 case NFS4ATTR_GETIT
:
1072 na
->aclsupport
= ACL4_SUPPORT_ALLOW_ACL
|
1073 ACL4_SUPPORT_DENY_ACL
;
1075 case NFS4ATTR_SETIT
:
1078 case NFS4ATTR_VERIT
:
1079 if (na
->aclsupport
!= (ACL4_SUPPORT_ALLOW_ACL
|
1080 ACL4_SUPPORT_DENY_ACL
))
1081 error
= -1; /* no match */
1090 rfs4_fattr4_archive(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1091 union nfs4_attr_u
*na
)
1098 rfs4_fattr4_cansettime(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1099 union nfs4_attr_u
*na
)
1103 if (RFS4_MANDATTR_ONLY
)
1107 case NFS4ATTR_SUPPORTED
:
1108 if (sarg
->op
== NFS4ATTR_SETIT
)
1110 break; /* this attr is supported */
1111 case NFS4ATTR_GETIT
:
1112 na
->cansettime
= TRUE
;
1114 case NFS4ATTR_SETIT
:
1120 case NFS4ATTR_VERIT
:
1121 if (!na
->cansettime
)
1122 error
= -1; /* no match */
1124 case NFS4ATTR_FREEIT
:
1131 * XXX - need VOP extension to ask file system (e.g. pcfs) if it supports
1136 rfs4_fattr4_case_insensitive(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1137 union nfs4_attr_u
*na
)
1141 if (RFS4_MANDATTR_ONLY
)
1145 case NFS4ATTR_SUPPORTED
:
1146 if (sarg
->op
== NFS4ATTR_SETIT
)
1148 break; /* this attr is supported */
1149 case NFS4ATTR_GETIT
:
1150 na
->case_insensitive
= FALSE
;
1152 case NFS4ATTR_SETIT
:
1158 case NFS4ATTR_VERIT
:
1159 if (!na
->case_insensitive
)
1160 error
= -1; /* no match */
1162 case NFS4ATTR_FREEIT
:
1170 rfs4_fattr4_case_preserving(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1171 union nfs4_attr_u
*na
)
1175 if (RFS4_MANDATTR_ONLY
)
1179 case NFS4ATTR_SUPPORTED
:
1180 if (sarg
->op
== NFS4ATTR_SETIT
)
1182 break; /* this attr is supported */
1183 case NFS4ATTR_GETIT
:
1184 na
->case_preserving
= TRUE
;
1186 case NFS4ATTR_SETIT
:
1192 case NFS4ATTR_VERIT
:
1193 if (!na
->case_preserving
)
1194 error
= -1; /* no match */
1196 case NFS4ATTR_FREEIT
:
1202 /* fattr4_chown_restricted should reall be fattr4_chown_allowed */
1205 rfs4_fattr4_chown_restricted(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1206 union nfs4_attr_u
*na
)
1211 if (RFS4_MANDATTR_ONLY
)
1215 case NFS4ATTR_SUPPORTED
:
1216 if (sarg
->op
== NFS4ATTR_SETIT
)
1218 break; /* this attr is supported */
1219 case NFS4ATTR_GETIT
:
1220 if (sarg
->rdattr_error
&& (sarg
->cs
->vp
== NULL
)) {
1221 error
= -1; /* may be okay if rdattr_error */
1224 ASSERT(sarg
->cs
->vp
!= NULL
);
1225 error
= fop_pathconf(sarg
->cs
->vp
,
1226 _PC_CHOWN_RESTRICTED
, &val
, sarg
->cs
->cr
, NULL
);
1230 na
->chown_restricted
= (val
== 1);
1232 case NFS4ATTR_SETIT
:
1238 case NFS4ATTR_VERIT
:
1239 ASSERT(sarg
->cs
->vp
!= NULL
);
1240 error
= fop_pathconf(sarg
->cs
->vp
,
1241 _PC_CHOWN_RESTRICTED
, &val
, sarg
->cs
->cr
, NULL
);
1244 if (na
->chown_restricted
!= (val
== 1))
1245 error
= -1; /* no match */
1247 case NFS4ATTR_FREEIT
:
1255 rfs4_fattr4_fileid(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1256 union nfs4_attr_u
*na
)
1260 if (RFS4_MANDATTR_ONLY
)
1264 case NFS4ATTR_SUPPORTED
:
1265 if (sarg
->op
== NFS4ATTR_SETIT
)
1267 break; /* this attr is supported */
1268 case NFS4ATTR_GETIT
:
1269 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_NODEID
)) {
1270 error
= -1; /* may be okay if rdattr_error */
1273 ASSERT(sarg
->vap
->va_mask
& VATTR_NODEID
);
1274 na
->fileid
= sarg
->vap
->va_nodeid
;
1276 case NFS4ATTR_SETIT
:
1282 case NFS4ATTR_VERIT
:
1283 ASSERT(sarg
->vap
->va_mask
& VATTR_NODEID
);
1284 if (sarg
->vap
->va_nodeid
!= na
->fileid
)
1285 error
= -1; /* no match */
1287 case NFS4ATTR_FREEIT
:
1295 rfs4_get_mntdfileid(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
)
1299 vnode_t
*stubvp
= NULL
, *vp
;
1302 sarg
->mntdfid_set
= FALSE
;
1304 /* VROOT object, must untraverse */
1305 if (vp
->v_flag
& VROOT
) {
1307 /* extra hold for vp since untraverse might rele */
1309 stubvp
= untraverse(vp
);
1312 * If vp/stubvp are same, we must be at system
1313 * root because untraverse returned same vp
1314 * for a VROOT object. sarg->vap was setup
1315 * before we got here, so there's no need to do
1316 * another getattr -- just use the one in sarg.
1318 if (VN_CMP(vp
, stubvp
)) {
1319 ASSERT(VN_CMP(vp
, rootdir
));
1322 va
.va_mask
= VATTR_NODEID
;
1324 error
= rfs4_vop_getattr(stubvp
, vap
, 0, sarg
->cs
->cr
);
1328 * Done with stub, time to rele. If vp and stubvp
1329 * were the same, then we need to rele either vp or
1330 * stubvp. If they weren't the same, then untraverse()
1331 * already took case of the extra hold on vp, and only
1332 * the stub needs to be rele'd. Both cases are handled
1333 * by unconditionally rele'ing the stub.
1340 * At this point, vap should contain "correct" VATTR_NODEID --
1341 * (for V_ROOT case, nodeid of stub, for non-VROOT case,
1342 * nodeid of vp). If error or VATTR_NODEID not available, then
1343 * make the obligatory (yet mysterious) rdattr_error
1344 * check that is so common in the attr code.
1346 if (!error
&& (vap
->va_mask
& VATTR_NODEID
)) {
1347 sarg
->mounted_on_fileid
= vap
->va_nodeid
;
1348 sarg
->mntdfid_set
= TRUE
;
1349 } else if (sarg
->rdattr_error
)
1353 * error describes these cases:
1355 * -1: failure due to previous attr processing error (rddir only).
1356 * * : new attr failure (if rddir, caller will set rdattr_error)
1363 rfs4_fattr4_mounted_on_fileid(nfs4_attr_cmd_t cmd
,
1364 struct nfs4_svgetit_arg
*sarg
, union nfs4_attr_u
*na
)
1368 if (RFS4_MANDATTR_ONLY
)
1372 case NFS4ATTR_SUPPORTED
:
1373 if (sarg
->op
== NFS4ATTR_SETIT
)
1375 break; /* this attr is supported */
1376 case NFS4ATTR_GETIT
:
1377 case NFS4ATTR_VERIT
:
1378 if (! sarg
->mntdfid_set
)
1379 error
= rfs4_get_mntdfileid(cmd
, sarg
);
1381 if (! error
&& sarg
->mntdfid_set
) {
1382 if (cmd
== NFS4ATTR_GETIT
)
1383 na
->mounted_on_fileid
= sarg
->mounted_on_fileid
;
1385 if (na
->mounted_on_fileid
!=
1386 sarg
->mounted_on_fileid
)
1390 case NFS4ATTR_SETIT
:
1391 /* read-only attr */
1394 case NFS4ATTR_FREEIT
:
1402 rfs4_fattr4_files_avail(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1403 union nfs4_attr_u
*na
)
1407 if (RFS4_MANDATTR_ONLY
)
1411 case NFS4ATTR_SUPPORTED
:
1412 if (sarg
->op
== NFS4ATTR_SETIT
)
1414 break; /* this attr is supported */
1415 case NFS4ATTR_GETIT
:
1416 if (sarg
->rdattr_error
&& (sarg
->sbp
== NULL
)) {
1417 error
= -1; /* may be okay if rdattr_error */
1420 ASSERT(sarg
->sbp
!= NULL
);
1421 na
->files_avail
= sarg
->sbp
->f_favail
;
1423 case NFS4ATTR_SETIT
:
1429 case NFS4ATTR_VERIT
:
1430 ASSERT(sarg
->sbp
!= NULL
);
1431 if (sarg
->sbp
->f_favail
!= na
->files_avail
)
1432 error
= -1; /* no match */
1434 case NFS4ATTR_FREEIT
:
1442 rfs4_fattr4_files_free(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1443 union nfs4_attr_u
*na
)
1447 if (RFS4_MANDATTR_ONLY
)
1451 case NFS4ATTR_SUPPORTED
:
1452 if (sarg
->op
== NFS4ATTR_SETIT
)
1454 break; /* this attr is supported */
1455 case NFS4ATTR_GETIT
:
1456 if (sarg
->rdattr_error
&& (sarg
->sbp
== NULL
)) {
1457 error
= -1; /* may be okay if rdattr_error */
1460 ASSERT(sarg
->sbp
!= NULL
);
1461 na
->files_free
= sarg
->sbp
->f_ffree
;
1463 case NFS4ATTR_SETIT
:
1469 case NFS4ATTR_VERIT
:
1470 ASSERT(sarg
->sbp
!= NULL
);
1471 if (sarg
->sbp
->f_ffree
!= na
->files_free
)
1472 error
= -1; /* no match */
1474 case NFS4ATTR_FREEIT
:
1482 rfs4_fattr4_files_total(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1483 union nfs4_attr_u
*na
)
1487 if (RFS4_MANDATTR_ONLY
)
1491 case NFS4ATTR_SUPPORTED
:
1492 if (sarg
->op
== NFS4ATTR_SETIT
)
1494 break; /* this attr is supported */
1495 case NFS4ATTR_GETIT
:
1496 if (sarg
->rdattr_error
&& (sarg
->sbp
== NULL
)) {
1497 error
= -1; /* may be okay if rdattr_error */
1500 ASSERT(sarg
->sbp
!= NULL
);
1501 na
->files_total
= sarg
->sbp
->f_files
;
1503 case NFS4ATTR_SETIT
:
1509 case NFS4ATTR_VERIT
:
1510 ASSERT(sarg
->sbp
!= NULL
);
1511 if (sarg
->sbp
->f_files
!= na
->files_total
)
1512 error
= -1; /* no match */
1514 case NFS4ATTR_FREEIT
:
1521 rfs4_free_pathname4(pathname4
*pn4
)
1526 if (pn4
== NULL
|| (len
= pn4
->pathname4_len
) == 0 ||
1527 (utf8s
= pn4
->pathname4_val
) == NULL
)
1530 for (i
= 0; i
< len
; i
++, utf8s
++) {
1531 if (utf8s
->utf8string_val
== NULL
||
1532 utf8s
->utf8string_len
== 0)
1535 kmem_free(utf8s
->utf8string_val
, utf8s
->utf8string_len
);
1536 utf8s
->utf8string_val
= NULL
;
1539 kmem_free(pn4
->pathname4_val
,
1540 sizeof (utf8string
) * pn4
->pathname4_len
);
1541 pn4
->pathname4_val
= 0;
1545 rfs4_free_fs_location4(fs_location4
*fsl4
)
1550 rfs4_free_pathname4((pathname4
*)&fsl4
->server_len
);
1551 rfs4_free_pathname4(&fsl4
->rootpath
);
1555 rfs4_free_fs_locations4(fs_locations4
*fsls4
)
1564 rfs4_free_pathname4(&fsls4
->fs_root
);
1566 if ((len
= fsls4
->locations_len
) == 0 ||
1567 (fsl4
= fsls4
->locations_val
) == NULL
)
1570 /* free fs_location4 */
1571 for (i
= 0; i
< len
; i
++) {
1572 rfs4_free_fs_location4(fsl4
);
1576 kmem_free(fsls4
->locations_val
, sizeof (fs_location4
) * len
);
1577 fsls4
->locations_val
= NULL
;
1582 rfs4_fattr4_fs_locations(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1583 union nfs4_attr_u
*na
)
1588 if (RFS4_MANDATTR_ONLY
)
1592 case NFS4ATTR_SUPPORTED
:
1593 if (sarg
->op
== NFS4ATTR_SETIT
|| sarg
->op
== NFS4ATTR_VERIT
)
1595 break; /* this attr is supported */
1597 case NFS4ATTR_GETIT
:
1598 fsl
= fetch_referral(sarg
->cs
->vp
, sarg
->cs
->cr
);
1600 (void) memset(&(na
->fs_locations
), 0,
1601 sizeof (fs_locations4
));
1603 na
->fs_locations
= *fsl
;
1604 kmem_free(fsl
, sizeof (fs_locations4
));
1606 global_svstat_ptr
[4][NFS_REFERRALS
].value
.ui64
++;
1609 case NFS4ATTR_FREEIT
:
1610 if (sarg
->op
== NFS4ATTR_SETIT
|| sarg
->op
== NFS4ATTR_VERIT
)
1612 rfs4_free_fs_locations4(&na
->fs_locations
);
1615 case NFS4ATTR_SETIT
:
1616 case NFS4ATTR_VERIT
:
1628 rfs4_fattr4_hidden(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1629 union nfs4_attr_u
*na
)
1636 rfs4_fattr4_homogeneous(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1637 union nfs4_attr_u
*na
)
1641 if (RFS4_MANDATTR_ONLY
)
1645 case NFS4ATTR_SUPPORTED
:
1646 if (sarg
->op
== NFS4ATTR_SETIT
)
1648 break; /* this attr is supported */
1649 case NFS4ATTR_GETIT
:
1650 na
->homogeneous
= TRUE
; /* XXX - need a VOP extension */
1652 case NFS4ATTR_SETIT
:
1658 case NFS4ATTR_VERIT
:
1659 if (!na
->homogeneous
)
1660 error
= -1; /* no match */
1662 case NFS4ATTR_FREEIT
:
1670 rfs4_fattr4_maxfilesize(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1671 union nfs4_attr_u
*na
)
1675 fattr4_maxfilesize maxfilesize
;
1677 if (RFS4_MANDATTR_ONLY
)
1681 case NFS4ATTR_SUPPORTED
:
1682 if (sarg
->op
== NFS4ATTR_SETIT
)
1684 break; /* this attr is supported */
1685 case NFS4ATTR_GETIT
:
1686 if (sarg
->rdattr_error
&& (sarg
->cs
->vp
== NULL
)) {
1687 error
= -1; /* may be okay if rdattr_error */
1690 ASSERT(sarg
->cs
->vp
!= NULL
);
1691 error
= fop_pathconf(sarg
->cs
->vp
, _PC_FILESIZEBITS
, &val
,
1692 sarg
->cs
->cr
, NULL
);
1697 * If the underlying file system does not support
1698 * _PC_FILESIZEBITS, return a reasonable default. Note that
1699 * error code on fop_pathconf will be 0, even if the underlying
1700 * file system does not support _PC_FILESIZEBITS.
1702 if (val
== (ulong_t
)-1) {
1703 na
->maxfilesize
= MAXOFF_T
;
1705 if (val
>= (sizeof (uint64_t) * 8))
1706 na
->maxfilesize
= INT64_MAX
;
1708 na
->maxfilesize
= ((1LL << (val
- 1)) - 1);
1711 case NFS4ATTR_SETIT
:
1717 case NFS4ATTR_VERIT
:
1718 ASSERT(sarg
->cs
->vp
!= NULL
);
1719 error
= fop_pathconf(sarg
->cs
->vp
, _PC_FILESIZEBITS
, &val
,
1720 sarg
->cs
->cr
, NULL
);
1724 * If the underlying file system does not support
1725 * _PC_FILESIZEBITS, return a reasonable default. Note that
1726 * error code on fop_pathconf will be 0, even if the underlying
1727 * file system does not support _PC_FILESIZEBITS.
1729 if (val
== (ulong_t
)-1) {
1730 maxfilesize
= MAXOFF_T
;
1732 if (val
>= (sizeof (uint64_t) * 8))
1733 maxfilesize
= INT64_MAX
;
1735 maxfilesize
= ((1LL << (val
- 1)) - 1);
1737 if (na
->maxfilesize
!= maxfilesize
)
1738 error
= -1; /* no match */
1740 case NFS4ATTR_FREEIT
:
1748 rfs4_fattr4_maxlink(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1749 union nfs4_attr_u
*na
)
1754 if (RFS4_MANDATTR_ONLY
)
1758 case NFS4ATTR_SUPPORTED
:
1759 if (sarg
->op
== NFS4ATTR_SETIT
)
1761 break; /* this attr is supported */
1762 case NFS4ATTR_GETIT
:
1763 if (sarg
->rdattr_error
&& (sarg
->cs
->vp
== NULL
)) {
1764 error
= -1; /* may be okay if rdattr_error */
1767 ASSERT(sarg
->cs
->vp
!= NULL
);
1768 error
= fop_pathconf(sarg
->cs
->vp
, _PC_LINK_MAX
, &val
,
1769 sarg
->cs
->cr
, NULL
);
1774 case NFS4ATTR_SETIT
:
1780 case NFS4ATTR_VERIT
:
1781 ASSERT(sarg
->cs
->vp
!= NULL
);
1782 error
= fop_pathconf(sarg
->cs
->vp
, _PC_LINK_MAX
, &val
,
1783 sarg
->cs
->cr
, NULL
);
1784 if (!error
&& (na
->maxlink
!= (uint32_t)val
))
1785 error
= -1; /* no match */
1787 case NFS4ATTR_FREEIT
:
1795 rfs4_fattr4_maxname(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1796 union nfs4_attr_u
*na
)
1801 if (RFS4_MANDATTR_ONLY
)
1805 case NFS4ATTR_SUPPORTED
:
1806 if (sarg
->op
== NFS4ATTR_SETIT
)
1808 break; /* this attr is supported */
1809 case NFS4ATTR_GETIT
:
1810 if (sarg
->rdattr_error
&& (sarg
->cs
->vp
== NULL
)) {
1811 error
= -1; /* may be okay if rdattr_error */
1814 ASSERT(sarg
->cs
->vp
!= NULL
);
1815 error
= fop_pathconf(sarg
->cs
->vp
, _PC_NAME_MAX
, &val
,
1816 sarg
->cs
->cr
, NULL
);
1821 case NFS4ATTR_SETIT
:
1827 case NFS4ATTR_VERIT
:
1828 ASSERT(sarg
->cs
->vp
!= NULL
);
1829 error
= fop_pathconf(sarg
->cs
->vp
, _PC_NAME_MAX
, &val
,
1830 sarg
->cs
->cr
, NULL
);
1831 if (!error
&& (na
->maxname
!= val
))
1832 error
= -1; /* no match */
1834 case NFS4ATTR_FREEIT
:
1842 rfs4_fattr4_maxread(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1843 union nfs4_attr_u
*na
)
1847 if (RFS4_MANDATTR_ONLY
)
1851 case NFS4ATTR_SUPPORTED
:
1852 if (sarg
->op
== NFS4ATTR_SETIT
)
1854 break; /* this attr is supported */
1855 case NFS4ATTR_GETIT
:
1856 na
->maxread
= rfs4_tsize(sarg
->cs
->req
);
1858 case NFS4ATTR_SETIT
:
1864 case NFS4ATTR_VERIT
:
1865 if (na
->maxread
!= rfs4_tsize(sarg
->cs
->req
))
1866 error
= -1; /* no match */
1868 case NFS4ATTR_FREEIT
:
1876 rfs4_fattr4_maxwrite(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1877 union nfs4_attr_u
*na
)
1881 if (RFS4_MANDATTR_ONLY
)
1885 case NFS4ATTR_SUPPORTED
:
1886 if (sarg
->op
== NFS4ATTR_SETIT
)
1888 break; /* this attr is supported */
1889 case NFS4ATTR_GETIT
:
1890 na
->maxwrite
= rfs4_tsize(sarg
->cs
->req
);
1892 case NFS4ATTR_SETIT
:
1898 case NFS4ATTR_VERIT
:
1899 if (na
->maxwrite
!= rfs4_tsize(sarg
->cs
->req
))
1900 error
= -1; /* no match */
1902 case NFS4ATTR_FREEIT
:
1910 rfs4_fattr4_mimetype(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1911 union nfs4_attr_u
*na
)
1918 rfs4_fattr4_mode(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1919 union nfs4_attr_u
*na
)
1923 if (RFS4_MANDATTR_ONLY
)
1927 case NFS4ATTR_SUPPORTED
:
1928 break; /* this attr is supported */
1929 case NFS4ATTR_GETIT
:
1930 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_MODE
)) {
1931 error
= -1; /* may be okay if rdattr_error */
1934 ASSERT(sarg
->vap
->va_mask
& VATTR_MODE
);
1935 na
->mode
= sarg
->vap
->va_mode
;
1937 case NFS4ATTR_SETIT
:
1938 ASSERT(sarg
->vap
->va_mask
& VATTR_MODE
);
1939 sarg
->vap
->va_mode
= na
->mode
;
1941 * If the filesystem is exported with nosuid, then mask off
1942 * the setuid and setgid bits.
1944 if (sarg
->cs
->vp
->v_type
== VREG
&&
1945 (sarg
->cs
->exi
->exi_export
.ex_flags
& EX_NOSUID
))
1946 sarg
->vap
->va_mode
&= ~(VSUID
| VSGID
);
1948 case NFS4ATTR_VERIT
:
1949 ASSERT(sarg
->vap
->va_mask
& VATTR_MODE
);
1950 if (sarg
->vap
->va_mode
!= na
->mode
)
1951 error
= -1; /* no match */
1953 case NFS4ATTR_FREEIT
:
1961 rfs4_fattr4_no_trunc(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1962 union nfs4_attr_u
*na
)
1966 if (RFS4_MANDATTR_ONLY
)
1970 case NFS4ATTR_SUPPORTED
:
1971 if (sarg
->op
== NFS4ATTR_SETIT
)
1973 break; /* this attr is supported */
1974 case NFS4ATTR_GETIT
:
1975 na
->no_trunc
= TRUE
;
1977 case NFS4ATTR_SETIT
:
1983 case NFS4ATTR_VERIT
:
1985 error
= -1; /* no match */
1987 case NFS4ATTR_FREEIT
:
1995 rfs4_fattr4_numlinks(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
1996 union nfs4_attr_u
*na
)
2000 if (RFS4_MANDATTR_ONLY
)
2004 case NFS4ATTR_SUPPORTED
:
2005 if (sarg
->op
== NFS4ATTR_SETIT
)
2007 break; /* this attr is supported */
2008 case NFS4ATTR_GETIT
:
2009 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_NLINK
)) {
2010 error
= -1; /* may be okay if rdattr_error */
2013 ASSERT(sarg
->vap
->va_mask
& VATTR_NLINK
);
2014 na
->numlinks
= sarg
->vap
->va_nlink
;
2016 case NFS4ATTR_SETIT
:
2022 case NFS4ATTR_VERIT
:
2023 ASSERT(sarg
->vap
->va_mask
& VATTR_NLINK
);
2024 if (sarg
->vap
->va_nlink
!= na
->numlinks
)
2025 error
= -1; /* no match */
2027 case NFS4ATTR_FREEIT
:
2035 rfs4_fattr4_owner(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2036 union nfs4_attr_u
*na
)
2041 if (RFS4_MANDATTR_ONLY
)
2045 case NFS4ATTR_SUPPORTED
:
2046 break; /* this attr is supported */
2047 case NFS4ATTR_GETIT
:
2048 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_UID
)) {
2049 error
= -1; /* may be okay if rdattr_error */
2052 ASSERT(sarg
->vap
->va_mask
& VATTR_UID
);
2055 * There are well defined polices for what happens on server-
2056 * side GETATTR when uid to attribute string conversion cannot
2057 * occur. Please refer to nfs4_idmap.c for details.
2059 error
= nfs_idmap_uid_str(sarg
->vap
->va_uid
, &na
->owner
, TRUE
);
2062 error
= NFS4ERR_DELAY
;
2069 case NFS4ATTR_SETIT
:
2070 ASSERT(sarg
->vap
->va_mask
& VATTR_UID
);
2073 * There are well defined policies for what happens on server-
2074 * side SETATTR of 'owner' when a "user@domain" mapping cannot
2075 * occur. Please refer to nfs4_idmap.c for details.
2077 * Any other errors, such as the mapping not being found by
2078 * nfsmapid(1m), and interrupted clnt_call, etc, will result
2079 * in NFS4ERR_BADOWNER.
2081 * XXX need to return consistent errors, perhaps all
2082 * server side attribute routines should return NFS4ERR*.
2084 error
= nfs_idmap_str_uid(&na
->owner
, &sarg
->vap
->va_uid
, TRUE
);
2089 * Ignore warning that we are the
2090 * nfsmapid (can't happen on srv)
2093 MSG_PRT_DEBUG
= FALSE
;
2098 if (!MSG_PRT_DEBUG
) {
2100 * printed just once per daemon death,
2101 * inform the user and then stay silent
2103 cmn_err(CE_WARN
, "!Unable to contact "
2105 MSG_PRT_DEBUG
= TRUE
;
2107 error
= NFS4ERR_DELAY
;
2111 error
= NFS4ERR_INVAL
;
2115 error
= NFS4ERR_BADOWNER
;
2120 case NFS4ATTR_VERIT
:
2121 ASSERT(sarg
->vap
->va_mask
& VATTR_UID
);
2122 error
= nfs_idmap_str_uid(&na
->owner
, &uid
, TRUE
);
2124 * Ignore warning that we are the nfsmapid (can't happen on srv)
2126 if (error
== ENOTSUP
)
2129 error
= -1; /* no match */
2130 else if (sarg
->vap
->va_uid
!= uid
)
2131 error
= -1; /* no match */
2133 case NFS4ATTR_FREEIT
:
2134 if (sarg
->op
== NFS4ATTR_GETIT
) {
2135 if (na
->owner
.utf8string_val
) {
2136 UTF8STRING_FREE(na
->owner
)
2137 bzero(&na
->owner
, sizeof (na
->owner
));
2147 rfs4_fattr4_owner_group(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2148 union nfs4_attr_u
*na
)
2153 if (RFS4_MANDATTR_ONLY
)
2157 case NFS4ATTR_SUPPORTED
:
2158 break; /* this attr is supported */
2159 case NFS4ATTR_GETIT
:
2160 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_GID
)) {
2161 error
= -1; /* may be okay if rdattr_error */
2164 ASSERT(sarg
->vap
->va_mask
& VATTR_GID
);
2167 * There are well defined polices for what happens on server-
2168 * side GETATTR when gid to attribute string conversion cannot
2169 * occur. Please refer to nfs4_idmap.c for details.
2171 error
= nfs_idmap_gid_str(sarg
->vap
->va_gid
, &na
->owner_group
,
2175 error
= NFS4ERR_DELAY
;
2182 case NFS4ATTR_SETIT
:
2183 ASSERT(sarg
->vap
->va_mask
& VATTR_GID
);
2186 * There are well defined policies for what happens on server-
2187 * side SETATTR of 'owner_group' when a "group@domain" mapping
2188 * cannot occur. Please refer to nfs4_idmap.c for details.
2190 * Any other errors, such as the mapping not being found by
2191 * nfsmapid(1m), and interrupted clnt_call, etc, will result
2192 * in NFS4ERR_BADOWNER.
2194 * XXX need to return consistent errors, perhaps all
2195 * server side attribute routines should return NFS4ERR*.
2197 error
= nfs_idmap_str_gid(&na
->owner_group
, &sarg
->vap
->va_gid
,
2203 * Ignore warning that we are the
2204 * nfsmapid (can't happen on srv)
2207 MSG_PRT_DEBUG
= FALSE
;
2212 if (!MSG_PRT_DEBUG
) {
2214 * printed just once per daemon death,
2215 * inform the user and then stay silent
2217 cmn_err(CE_WARN
, "!Unable to contact "
2219 MSG_PRT_DEBUG
= TRUE
;
2221 error
= NFS4ERR_DELAY
;
2225 error
= NFS4ERR_INVAL
;
2229 error
= NFS4ERR_BADOWNER
;
2234 case NFS4ATTR_VERIT
:
2235 ASSERT(sarg
->vap
->va_mask
& VATTR_GID
);
2236 error
= nfs_idmap_str_gid(&na
->owner_group
, &gid
, TRUE
);
2238 * Ignore warning that we are the nfsmapid (can't happen on srv)
2240 if (error
== ENOTSUP
)
2243 error
= -1; /* no match */
2244 else if (sarg
->vap
->va_gid
!= gid
)
2245 error
= -1; /* no match */
2247 case NFS4ATTR_FREEIT
:
2248 if (sarg
->op
== NFS4ATTR_GETIT
) {
2249 if (na
->owner_group
.utf8string_val
) {
2250 UTF8STRING_FREE(na
->owner_group
)
2251 bzero(&na
->owner_group
,
2252 sizeof (na
->owner_group
));
2260 /* XXX - quota attributes should be supportable on Solaris 2 */
2263 rfs4_fattr4_quota_avail_hard(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2264 union nfs4_attr_u
*na
)
2271 rfs4_fattr4_quota_avail_soft(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2272 union nfs4_attr_u
*na
)
2279 rfs4_fattr4_quota_used(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2280 union nfs4_attr_u
*na
)
2287 rfs4_fattr4_rawdev(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2288 union nfs4_attr_u
*na
)
2292 if (RFS4_MANDATTR_ONLY
)
2296 case NFS4ATTR_SUPPORTED
:
2297 if (sarg
->op
== NFS4ATTR_SETIT
)
2299 break; /* this attr is supported */
2300 case NFS4ATTR_GETIT
:
2301 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_RDEV
)) {
2302 error
= -1; /* may be okay if rdattr_error */
2305 ASSERT(sarg
->vap
->va_mask
& VATTR_RDEV
);
2306 na
->rawdev
.specdata1
= (uint32
)getmajor(sarg
->vap
->va_rdev
);
2307 na
->rawdev
.specdata2
= (uint32
)getminor(sarg
->vap
->va_rdev
);
2309 case NFS4ATTR_SETIT
:
2315 case NFS4ATTR_VERIT
:
2316 ASSERT(sarg
->vap
->va_mask
& VATTR_RDEV
);
2317 if ((na
->rawdev
.specdata1
!=
2318 (uint32
)getmajor(sarg
->vap
->va_rdev
)) ||
2319 (na
->rawdev
.specdata2
!=
2320 (uint32
)getminor(sarg
->vap
->va_rdev
)))
2321 error
= -1; /* no match */
2323 case NFS4ATTR_FREEIT
:
2331 rfs4_fattr4_space_avail(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2332 union nfs4_attr_u
*na
)
2336 if (RFS4_MANDATTR_ONLY
)
2340 case NFS4ATTR_SUPPORTED
:
2341 if (sarg
->op
== NFS4ATTR_SETIT
)
2343 break; /* this attr is supported */
2344 case NFS4ATTR_GETIT
:
2345 if (sarg
->rdattr_error
&& (sarg
->sbp
== NULL
)) {
2346 error
= -1; /* may be okay if rdattr_error */
2349 ASSERT(sarg
->sbp
!= NULL
);
2350 if (sarg
->sbp
->f_bavail
!= (fsblkcnt64_t
)-1) {
2352 (fattr4_space_avail
) sarg
->sbp
->f_frsize
*
2353 (fattr4_space_avail
) sarg
->sbp
->f_bavail
;
2356 (fattr4_space_avail
) sarg
->sbp
->f_bavail
;
2359 case NFS4ATTR_SETIT
:
2365 case NFS4ATTR_VERIT
:
2366 ASSERT(sarg
->sbp
!= NULL
);
2367 if (sarg
->sbp
->f_bavail
!= na
->space_avail
)
2368 error
= -1; /* no match */
2370 case NFS4ATTR_FREEIT
:
2378 rfs4_fattr4_space_free(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2379 union nfs4_attr_u
*na
)
2383 if (RFS4_MANDATTR_ONLY
)
2387 case NFS4ATTR_SUPPORTED
:
2388 if (sarg
->op
== NFS4ATTR_SETIT
)
2390 break; /* this attr is supported */
2391 case NFS4ATTR_GETIT
:
2392 if (sarg
->rdattr_error
&& (sarg
->sbp
== NULL
)) {
2393 error
= -1; /* may be okay if rdattr_error */
2396 ASSERT(sarg
->sbp
!= NULL
);
2397 if (sarg
->sbp
->f_bfree
!= (fsblkcnt64_t
)-1) {
2399 (fattr4_space_free
) sarg
->sbp
->f_frsize
*
2400 (fattr4_space_free
) sarg
->sbp
->f_bfree
;
2403 (fattr4_space_free
) sarg
->sbp
->f_bfree
;
2406 case NFS4ATTR_SETIT
:
2412 case NFS4ATTR_VERIT
:
2413 ASSERT(sarg
->sbp
!= NULL
);
2414 if (sarg
->sbp
->f_bfree
!= na
->space_free
)
2415 error
= -1; /* no match */
2417 case NFS4ATTR_FREEIT
:
2425 rfs4_fattr4_space_total(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2426 union nfs4_attr_u
*na
)
2430 if (RFS4_MANDATTR_ONLY
)
2434 case NFS4ATTR_SUPPORTED
:
2435 if (sarg
->op
== NFS4ATTR_SETIT
)
2437 break; /* this attr is supported */
2438 case NFS4ATTR_GETIT
:
2439 if (sarg
->rdattr_error_req
&& (sarg
->sbp
== NULL
)) {
2440 error
= -1; /* may be okay if rdattr_error */
2443 ASSERT(sarg
->sbp
!= NULL
);
2444 if (sarg
->sbp
->f_blocks
!= (fsblkcnt64_t
)-1) {
2446 (fattr4_space_total
) sarg
->sbp
->f_frsize
*
2447 (fattr4_space_total
) sarg
->sbp
->f_blocks
;
2450 (fattr4_space_total
) sarg
->sbp
->f_blocks
;
2453 case NFS4ATTR_SETIT
:
2459 case NFS4ATTR_VERIT
:
2460 ASSERT(sarg
->sbp
!= NULL
);
2461 if (sarg
->sbp
->f_blocks
!= na
->space_total
)
2462 error
= -1; /* no match */
2464 case NFS4ATTR_FREEIT
:
2472 rfs4_fattr4_space_used(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2473 union nfs4_attr_u
*na
)
2477 if (RFS4_MANDATTR_ONLY
)
2481 case NFS4ATTR_SUPPORTED
:
2482 if (sarg
->op
== NFS4ATTR_SETIT
)
2484 break; /* this attr is supported */
2485 case NFS4ATTR_GETIT
:
2486 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_NBLOCKS
)) {
2487 error
= -1; /* may be okay if rdattr_error */
2490 ASSERT(sarg
->vap
->va_mask
& VATTR_NBLOCKS
);
2491 na
->space_used
= (fattr4_space_used
) DEV_BSIZE
*
2492 (fattr4_space_used
) sarg
->vap
->va_nblocks
;
2494 case NFS4ATTR_SETIT
:
2500 case NFS4ATTR_VERIT
:
2501 ASSERT(sarg
->vap
->va_mask
& VATTR_NBLOCKS
);
2502 if (sarg
->vap
->va_nblocks
!= na
->space_used
)
2503 error
= -1; /* no match */
2505 case NFS4ATTR_FREEIT
:
2513 rfs4_fattr4_system(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2514 union nfs4_attr_u
*na
)
2521 rfs4_fattr4_time_access(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2522 union nfs4_attr_u
*na
)
2527 if (RFS4_MANDATTR_ONLY
)
2531 case NFS4ATTR_SUPPORTED
:
2532 if (sarg
->op
== NFS4ATTR_SETIT
)
2534 break; /* this attr is supported */
2535 case NFS4ATTR_GETIT
:
2536 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_ATIME
)) {
2537 error
= -1; /* may be okay if rdattr_error */
2540 ASSERT(sarg
->vap
->va_mask
& VATTR_ATIME
);
2541 error
= nfs4_time_vton(&sarg
->vap
->va_atime
, &na
->time_access
);
2543 case NFS4ATTR_SETIT
:
2549 case NFS4ATTR_VERIT
:
2550 ASSERT(sarg
->vap
->va_mask
& VATTR_ATIME
);
2551 error
= nfs4_time_ntov(&na
->time_access
, &atime
);
2554 if (bcmp(&atime
, &sarg
->vap
->va_atime
, sizeof (atime
)))
2555 error
= -1; /* no match */
2557 case NFS4ATTR_FREEIT
:
2564 * XXX - need to support the setting of access time
2568 rfs4_fattr4_time_access_set(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2569 union nfs4_attr_u
*na
)
2574 if (RFS4_MANDATTR_ONLY
)
2578 case NFS4ATTR_SUPPORTED
:
2579 if ((sarg
->op
== NFS4ATTR_GETIT
) ||
2580 (sarg
->op
== NFS4ATTR_VERIT
))
2582 break; /* this attr is supported */
2583 case NFS4ATTR_GETIT
:
2584 case NFS4ATTR_VERIT
:
2590 case NFS4ATTR_SETIT
:
2591 ASSERT(sarg
->vap
->va_mask
& VATTR_ATIME
);
2593 * Set access time (by server or by client)
2595 ta
= &na
->time_access_set
;
2596 if (ta
->set_it
== SET_TO_CLIENT_TIME4
) {
2597 error
= nfs4_time_ntov(&ta
->time
, &sarg
->vap
->va_atime
);
2598 } else if (ta
->set_it
== SET_TO_SERVER_TIME4
) {
2599 gethrestime(&sarg
->vap
->va_atime
);
2604 case NFS4ATTR_FREEIT
:
2612 rfs4_fattr4_time_backup(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2613 union nfs4_attr_u
*na
)
2620 rfs4_fattr4_time_create(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2621 union nfs4_attr_u
*na
)
2628 rfs4_fattr4_time_delta(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2629 union nfs4_attr_u
*na
)
2633 if (RFS4_MANDATTR_ONLY
)
2637 case NFS4ATTR_SUPPORTED
:
2638 if (sarg
->op
== NFS4ATTR_SETIT
)
2640 break; /* this attr is supported */
2641 case NFS4ATTR_GETIT
:
2642 na
->time_delta
.seconds
= 0;
2643 na
->time_delta
.nseconds
= 1000;
2645 case NFS4ATTR_SETIT
:
2651 case NFS4ATTR_VERIT
:
2652 if ((na
->time_delta
.seconds
!= 0) ||
2653 (na
->time_delta
.nseconds
!= 1000))
2654 error
= -1; /* no match */
2656 case NFS4ATTR_FREEIT
:
2664 rfs4_fattr4_time_metadata(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2665 union nfs4_attr_u
*na
)
2670 if (RFS4_MANDATTR_ONLY
)
2674 case NFS4ATTR_SUPPORTED
:
2675 if (sarg
->op
== NFS4ATTR_SETIT
)
2677 break; /* this attr is supported */
2678 case NFS4ATTR_GETIT
:
2679 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_CTIME
)) {
2680 error
= -1; /* may be okay if rdattr_error */
2683 ASSERT(sarg
->vap
->va_mask
& VATTR_CTIME
);
2684 error
= nfs4_time_vton(&sarg
->vap
->va_ctime
,
2685 &na
->time_metadata
);
2687 case NFS4ATTR_SETIT
:
2693 case NFS4ATTR_VERIT
:
2694 ASSERT(sarg
->vap
->va_mask
& VATTR_CTIME
);
2695 error
= nfs4_time_ntov(&na
->time_metadata
, &ctime
);
2698 if (bcmp(&ctime
, &sarg
->vap
->va_ctime
, sizeof (ctime
)))
2699 error
= -1; /* no match */
2701 case NFS4ATTR_FREEIT
:
2709 rfs4_fattr4_time_modify(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2710 union nfs4_attr_u
*na
)
2715 if (RFS4_MANDATTR_ONLY
)
2719 case NFS4ATTR_SUPPORTED
:
2720 if (sarg
->op
== NFS4ATTR_SETIT
)
2722 break; /* this attr is supported */
2723 case NFS4ATTR_GETIT
:
2724 if (sarg
->rdattr_error
&& !(sarg
->vap
->va_mask
& VATTR_MTIME
)) {
2725 error
= -1; /* may be okay if rdattr_error */
2728 ASSERT(sarg
->vap
->va_mask
& VATTR_MTIME
);
2729 error
= nfs4_time_vton(&sarg
->vap
->va_mtime
, &na
->time_modify
);
2731 case NFS4ATTR_SETIT
:
2737 case NFS4ATTR_VERIT
:
2738 ASSERT(sarg
->vap
->va_mask
& VATTR_MTIME
);
2739 error
= nfs4_time_ntov(&na
->time_modify
, &mtime
);
2742 if (bcmp(&mtime
, &sarg
->vap
->va_mtime
, sizeof (mtime
)))
2743 error
= -1; /* no match */
2745 case NFS4ATTR_FREEIT
:
2752 * XXX - need to add support for setting modify time
2756 rfs4_fattr4_time_modify_set(nfs4_attr_cmd_t cmd
, struct nfs4_svgetit_arg
*sarg
,
2757 union nfs4_attr_u
*na
)
2762 if (RFS4_MANDATTR_ONLY
)
2766 case NFS4ATTR_SUPPORTED
:
2767 if ((sarg
->op
== NFS4ATTR_GETIT
) ||
2768 (sarg
->op
== NFS4ATTR_VERIT
))
2770 break; /* this attr is supported */
2771 case NFS4ATTR_GETIT
:
2772 case NFS4ATTR_VERIT
:
2778 case NFS4ATTR_SETIT
:
2779 ASSERT(sarg
->vap
->va_mask
& VATTR_MTIME
);
2781 * Set modify time (by server or by client)
2783 tm
= &na
->time_modify_set
;
2784 if (tm
->set_it
== SET_TO_CLIENT_TIME4
) {
2785 error
= nfs4_time_ntov(&tm
->time
, &sarg
->vap
->va_mtime
);
2786 sarg
->flag
= ATTR_UTIME
;
2787 } else if (tm
->set_it
== SET_TO_SERVER_TIME4
) {
2788 gethrestime(&sarg
->vap
->va_mtime
);
2793 case NFS4ATTR_FREEIT
:
2801 rfs4_ntov_init(void)
2803 /* index must be same as corresponding FATTR4_* define */
2804 nfs4_ntov_map
[0].sv_getit
= rfs4_fattr4_supported_attrs
;
2805 nfs4_ntov_map
[1].sv_getit
= rfs4_fattr4_type
;
2806 nfs4_ntov_map
[2].sv_getit
= rfs4_fattr4_fh_expire_type
;
2807 nfs4_ntov_map
[3].sv_getit
= rfs4_fattr4_change
;
2808 nfs4_ntov_map
[4].sv_getit
= rfs4_fattr4_size
;
2809 nfs4_ntov_map
[5].sv_getit
= rfs4_fattr4_link_support
;
2810 nfs4_ntov_map
[6].sv_getit
= rfs4_fattr4_symlink_support
;
2811 nfs4_ntov_map
[7].sv_getit
= rfs4_fattr4_named_attr
;
2812 nfs4_ntov_map
[8].sv_getit
= rfs4_fattr4_fsid
;
2813 nfs4_ntov_map
[9].sv_getit
= rfs4_fattr4_unique_handles
;
2814 nfs4_ntov_map
[10].sv_getit
= rfs4_fattr4_lease_time
;
2815 nfs4_ntov_map
[11].sv_getit
= rfs4_fattr4_rdattr_error
;
2816 nfs4_ntov_map
[12].sv_getit
= rfs4_fattr4_acl
;
2817 nfs4_ntov_map
[13].sv_getit
= rfs4_fattr4_aclsupport
;
2818 nfs4_ntov_map
[14].sv_getit
= rfs4_fattr4_archive
;
2819 nfs4_ntov_map
[15].sv_getit
= rfs4_fattr4_cansettime
;
2820 nfs4_ntov_map
[16].sv_getit
= rfs4_fattr4_case_insensitive
;
2821 nfs4_ntov_map
[17].sv_getit
= rfs4_fattr4_case_preserving
;
2822 nfs4_ntov_map
[18].sv_getit
= rfs4_fattr4_chown_restricted
;
2823 nfs4_ntov_map
[19].sv_getit
= rfs4_fattr4_filehandle
;
2824 nfs4_ntov_map
[20].sv_getit
= rfs4_fattr4_fileid
;
2825 nfs4_ntov_map
[21].sv_getit
= rfs4_fattr4_files_avail
;
2826 nfs4_ntov_map
[22].sv_getit
= rfs4_fattr4_files_free
;
2827 nfs4_ntov_map
[23].sv_getit
= rfs4_fattr4_files_total
;
2828 nfs4_ntov_map
[24].sv_getit
= rfs4_fattr4_fs_locations
;
2829 nfs4_ntov_map
[25].sv_getit
= rfs4_fattr4_hidden
;
2830 nfs4_ntov_map
[26].sv_getit
= rfs4_fattr4_homogeneous
;
2831 nfs4_ntov_map
[27].sv_getit
= rfs4_fattr4_maxfilesize
;
2832 nfs4_ntov_map
[28].sv_getit
= rfs4_fattr4_maxlink
;
2833 nfs4_ntov_map
[29].sv_getit
= rfs4_fattr4_maxname
;
2834 nfs4_ntov_map
[30].sv_getit
= rfs4_fattr4_maxread
;
2835 nfs4_ntov_map
[31].sv_getit
= rfs4_fattr4_maxwrite
;
2836 nfs4_ntov_map
[32].sv_getit
= rfs4_fattr4_mimetype
;
2837 nfs4_ntov_map
[33].sv_getit
= rfs4_fattr4_mode
;
2838 nfs4_ntov_map
[34].sv_getit
= rfs4_fattr4_no_trunc
;
2839 nfs4_ntov_map
[35].sv_getit
= rfs4_fattr4_numlinks
;
2840 nfs4_ntov_map
[36].sv_getit
= rfs4_fattr4_owner
;
2841 nfs4_ntov_map
[37].sv_getit
= rfs4_fattr4_owner_group
;
2842 nfs4_ntov_map
[38].sv_getit
= rfs4_fattr4_quota_avail_hard
;
2843 nfs4_ntov_map
[39].sv_getit
= rfs4_fattr4_quota_avail_soft
;
2844 nfs4_ntov_map
[40].sv_getit
= rfs4_fattr4_quota_used
;
2845 nfs4_ntov_map
[41].sv_getit
= rfs4_fattr4_rawdev
;
2846 nfs4_ntov_map
[42].sv_getit
= rfs4_fattr4_space_avail
;
2847 nfs4_ntov_map
[43].sv_getit
= rfs4_fattr4_space_free
;
2848 nfs4_ntov_map
[44].sv_getit
= rfs4_fattr4_space_total
;
2849 nfs4_ntov_map
[45].sv_getit
= rfs4_fattr4_space_used
;
2850 nfs4_ntov_map
[46].sv_getit
= rfs4_fattr4_system
;
2851 nfs4_ntov_map
[47].sv_getit
= rfs4_fattr4_time_access
;
2852 nfs4_ntov_map
[48].sv_getit
= rfs4_fattr4_time_access_set
;
2853 nfs4_ntov_map
[49].sv_getit
= rfs4_fattr4_time_backup
;
2854 nfs4_ntov_map
[50].sv_getit
= rfs4_fattr4_time_create
;
2855 nfs4_ntov_map
[51].sv_getit
= rfs4_fattr4_time_delta
;
2856 nfs4_ntov_map
[52].sv_getit
= rfs4_fattr4_time_metadata
;
2857 nfs4_ntov_map
[53].sv_getit
= rfs4_fattr4_time_modify
;
2858 nfs4_ntov_map
[54].sv_getit
= rfs4_fattr4_time_modify_set
;
2859 nfs4_ntov_map
[55].sv_getit
= rfs4_fattr4_mounted_on_fileid
;