Print this page
6879933 Let SMBFS support extensible attributes per. PSARC 2007/315


  97 /*
  98  * Turning this on causes nodes to be created in the cache
  99  * during directory listings, normally avoiding a second
 100  * OtW attribute fetch just after a readdir.
 101  */
 102 int smbfs_fastlookup = 1;
 103 
 104 /* local static function defines */
 105 
 106 static int      smbfslookup_cache(vnode_t *, char *, int, vnode_t **,
 107                         cred_t *);
 108 static int      smbfslookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr,
 109                         int cache_ok, caller_context_t *);
 110 static int      smbfsrename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm,
 111                         cred_t *cr, caller_context_t *);
 112 static int      smbfssetattr(vnode_t *, struct vattr *, int, cred_t *);
 113 static int      smbfs_accessx(void *, int, cred_t *);
 114 static int      smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
 115                         caller_context_t *);
 116 static void     smbfs_rele_fid(smbnode_t *, struct smb_cred *);

 117 
 118 /*
 119  * These are the vnode ops routines which implement the vnode interface to
 120  * the networked file system.  These routines just take their parameters,
 121  * make them look networkish by putting the right info into interface structs,
 122  * and then calling the appropriate remote routine(s) to do the work.
 123  *
 124  * Note on directory name lookup cacheing:  If we detect a stale fhandle,
 125  * we purge the directory cache relative to that vnode.  This way, the
 126  * user won't get burned by the cache repeatedly.  See <smbfs/smbnode.h> for
 127  * more details on smbnode locking.
 128  */
 129 
 130 static int      smbfs_open(vnode_t **, int, cred_t *, caller_context_t *);
 131 static int      smbfs_close(vnode_t *, int, int, offset_t, cred_t *,
 132                         caller_context_t *);
 133 static int      smbfs_read(vnode_t *, struct uio *, int, cred_t *,
 134                         caller_context_t *);
 135 static int      smbfs_write(vnode_t *, struct uio *, int, cred_t *,
 136                         caller_context_t *);


 821         case SMBFSIO_GETSD:
 822                 error = smbfs_acl_iocget(vp, arg, flag, cr);
 823                 break;
 824 
 825         case SMBFSIO_SETSD:
 826                 error = smbfs_acl_iocset(vp, arg, flag, cr);
 827                 break;
 828 
 829         default:
 830                 error = ENOTTY;
 831                 break;
 832         }
 833 
 834         return (error);
 835 }
 836 
 837 
 838 /*
 839  * Return either cached or remote attributes. If get remote attr
 840  * use them to check and invalidate caches, then cache the new attributes.
 841  *
 842  * XXX
 843  * This op should eventually support PSARC 2007/315, Extensible Attribute
 844  * Interfaces, for richer metadata.
 845  */
 846 /* ARGSUSED */
 847 static int
 848 smbfs_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
 849         caller_context_t *ct)
 850 {
 851         smbnode_t *np;
 852         smbmntinfo_t *smi;
 853 
 854         smi = VTOSMI(vp);
 855 
 856         if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
 857                 return (EIO);
 858 
 859         if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
 860                 return (EIO);
 861 
 862         /*
 863          * If it has been specified that the return value will
 864          * just be used as a hint, and we are only being asked


 872         if (flags & ATTR_HINT) {
 873                 if (vap->va_mask ==
 874                     (vap->va_mask & (AT_SIZE | AT_FSID | AT_RDEV))) {
 875                         mutex_enter(&np->r_statelock);
 876                         if (vap->va_mask | AT_SIZE)
 877                                 vap->va_size = np->r_size;
 878                         if (vap->va_mask | AT_FSID)
 879                                 vap->va_fsid = vp->v_vfsp->vfs_dev;
 880                         if (vap->va_mask | AT_RDEV)
 881                                 vap->va_rdev = vp->v_rdev;
 882                         mutex_exit(&np->r_statelock);
 883                         return (0);
 884                 }
 885         }
 886 
 887         return (smbfsgetattr(vp, vap, cr));
 888 }
 889 
 890 /* smbfsgetattr() in smbfs_client.c */
 891 
 892 /*
 893  * XXX
 894  * This op should eventually support PSARC 2007/315, Extensible Attribute
 895  * Interfaces, for richer metadata.
 896  */
 897 /*ARGSUSED4*/
 898 static int
 899 smbfs_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
 900                 caller_context_t *ct)
 901 {
 902         vfs_t           *vfsp;
 903         smbmntinfo_t    *smi;
 904         int             error;
 905         uint_t          mask;
 906         struct vattr    oldva;
 907 
 908         vfsp = vp->v_vfsp;
 909         smi = VFTOSMI(vfsp);
 910 
 911         if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
 912                 return (EIO);
 913 
 914         if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED)
 915                 return (EIO);
 916 


 962         return (smbfssetattr(vp, vap, flags, cr));
 963 }
 964 
 965 /*
 966  * Mostly from Darwin smbfs_setattr()
 967  * but then modified a lot.
 968  */
 969 /* ARGSUSED */
 970 static int
 971 smbfssetattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
 972 {
 973         int             error = 0;
 974         smbnode_t       *np = VTOSMB(vp);
 975         uint_t          mask = vap->va_mask;
 976         struct timespec *mtime, *atime;
 977         struct smb_cred scred;
 978         int             cerror, modified = 0;
 979         unsigned short  fid;
 980         int have_fid = 0;
 981         uint32_t rights = 0;

 982 
 983         ASSERT(curproc->p_zone == VTOSMI(vp)->smi_zone_ref.zref_zone);
 984 
 985         /*
 986          * There are no settable attributes on the XATTR dir,
 987          * so just silently ignore these.  On XATTR files,
 988          * you can set the size but nothing else.
 989          */
 990         if (vp->v_flag & V_XATTRDIR)
 991                 return (0);
 992         if (np->n_flag & N_XATTR) {
 993                 if (mask & AT_TIMES)
 994                         SMBVDEBUG("ignore set time on xattr\n");
 995                 mask &= AT_SIZE;
 996         }
 997 
 998         /*
 999          * If our caller is trying to set multiple attributes, they
1000          * can make no assumption about what order they are done in.
1001          * Here we try to do them in order of decreasing likelihood
1002          * of failure, just to minimize the chance we'll wind up
1003          * with a partially complete request.
1004          */
1005 
1006         /* Shared lock for (possible) n_fid use. */
1007         if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
1008                 return (EINTR);
1009         smb_credinit(&scred, cr);
1010 
1011         /*








1012          * Will we need an open handle for this setattr?
1013          * If so, what rights will we need?
1014          */
1015         if (mask & (AT_ATIME | AT_MTIME)) {
1016                 rights |=
1017                     SA_RIGHT_FILE_WRITE_ATTRIBUTES;
1018         }
1019         if (mask & AT_SIZE) {
1020                 rights |=
1021                     SA_RIGHT_FILE_WRITE_DATA |
1022                     SA_RIGHT_FILE_APPEND_DATA;
1023         }
1024 
1025         /*
1026          * Only SIZE really requires a handle, but it's
1027          * simpler and more reliable to set via a handle.
1028          * Some servers like NT4 won't set times by path.
1029          * Also, we're usually setting everything anyway.
1030          */
1031         if (mask & (AT_SIZE | AT_ATIME | AT_MTIME)) {
1032                 error = smbfs_smb_tmpopen(np, rights, &scred, &fid);
1033                 if (error) {
1034                         SMBVDEBUG("error %d opening %s\n",
1035                             error, np->n_rpath);
1036                         goto out;
1037                 }
1038                 have_fid = 1;
1039         }
1040 
1041         /*
1042          * If the server supports the UNIX extensions, right here is where
1043          * we'd support changes to uid, gid, mode, and possibly va_flags.
1044          * For now we claim to have made any such changes.
1045          */
1046 
1047         if (mask & AT_SIZE) {
1048                 /*
1049                  * If the new file size is less than what the client sees as
1050                  * the file size, then just change the size and invalidate
1051                  * the pages.


1068                          * so looks like we don't need to do this.
1069                          * Good thing, as this could take forever.
1070                          *
1071                          * XXX: Reportedly, writing one byte of zero
1072                          * at the end offset avoids problems here.
1073                          */
1074                         mutex_enter(&np->r_statelock);
1075                         np->r_size = vap->va_size;
1076                         mutex_exit(&np->r_statelock);
1077                         modified = 1;
1078                 }
1079         }
1080 
1081         /*
1082          * XXX: When Solaris has create_time, set that too.
1083          * Note: create_time is different from ctime.
1084          */
1085         mtime = ((mask & AT_MTIME) ? &vap->va_mtime : 0);
1086         atime = ((mask & AT_ATIME) ? &vap->va_atime : 0);
1087 
1088         if (mtime || atime) {
1089                 /*
1090                  * Always use the handle-based set attr call now.
1091                  * Not trying to set DOS attributes here so pass zero.
1092                  */
1093                 ASSERT(have_fid);
1094                 error = smbfs_smb_setfattr(np, fid,
1095                     0, mtime, atime, &scred);
1096                 if (error) {
1097                         SMBVDEBUG("set times error %d file %s\n",
1098                             error, np->n_rpath);
1099                 } else {
1100                         modified = 1;
1101                 }
1102         }
1103 
1104 out:
1105         if (modified) {
1106                 /*
1107                  * Invalidate attribute cache in case the server
1108                  * doesn't set exactly the attributes we asked.
1109                  */
1110                 smbfs_attrcache_remove(np);
1111         }
1112 
1113         if (have_fid) {
1114                 cerror = smbfs_smb_tmpclose(np, fid, &scred);
1115                 if (cerror)
1116                         SMBVDEBUG("error %d closing %s\n",
1117                             cerror, np->n_rpath);
1118         }
1119 
1120         smb_credrele(&scred);
1121         smbfs_rw_exit(&np->r_lkserlock);
1122 
1123         return (error);
1124 }
1125 
1126 /*


























































1127  * smbfs_access_rwx()
1128  * Common function for smbfs_access, etc.
1129  *
1130  * The security model implemented by the FS is unusual
1131  * due to the current "single user mounts" restriction:
1132  * All access under a given mount point uses the CIFS
1133  * credentials established by the owner of the mount.
1134  *
1135  * Most access checking is handled by the CIFS server,
1136  * but we need sufficient Unix access checks here to
1137  * prevent other local Unix users from having access
1138  * to objects under this mount that the uid/gid/mode
1139  * settings in the mount would not allow.
1140  *
1141  * With this model, there is a case where we need the
1142  * ability to do an access check before we have the
1143  * vnode for an object.  This function takes advantage
1144  * of the fact that the uid/gid/mode is per mount, and
1145  * avoids the need for a vnode.
1146  *


2975                 /*
2976                  * Always indicate that ACLs are enabled and
2977                  * that we support ACE_T format, otherwise
2978                  * libsec will ask for ACLENT_T format data
2979                  * which we don't support.
2980                  */
2981                 *valp = _ACL_ACE_ENABLED;
2982                 break;
2983 
2984         case _PC_SYMLINK_MAX:   /* No symlinks until we do Unix extensions */
2985                 *valp = 0;
2986                 break;
2987 
2988         case _PC_XATTR_EXISTS:
2989                 if (vfs->vfs_flag & VFS_XATTR) {
2990                         *valp = smbfs_xa_exists(vp, cr);
2991                         break;
2992                 }
2993                 return (EINVAL);
2994 





2995         case _PC_TIMESTAMP_RESOLUTION:
2996                 /*
2997                  * Windows times are tenths of microseconds
2998                  * (multiples of 100 nanoseconds).
2999                  */
3000                 *valp = 100L;
3001                 break;
3002 
3003         default:
3004                 return (fs_pathconf(vp, cmd, valp, cr, ct));
3005         }
3006         return (0);
3007 }
3008 
3009 /* ARGSUSED */
3010 static int
3011 smbfs_getsecattr(vnode_t *vp, vsecattr_t *vsa, int flag, cred_t *cr,
3012         caller_context_t *ct)
3013 {
3014         vfs_t *vfsp;




  97 /*
  98  * Turning this on causes nodes to be created in the cache
  99  * during directory listings, normally avoiding a second
 100  * OtW attribute fetch just after a readdir.
 101  */
 102 int smbfs_fastlookup = 1;
 103 
 104 /* local static function defines */
 105 
 106 static int      smbfslookup_cache(vnode_t *, char *, int, vnode_t **,
 107                         cred_t *);
 108 static int      smbfslookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr,
 109                         int cache_ok, caller_context_t *);
 110 static int      smbfsrename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm,
 111                         cred_t *cr, caller_context_t *);
 112 static int      smbfssetattr(vnode_t *, struct vattr *, int, cred_t *);
 113 static int      smbfs_accessx(void *, int, cred_t *);
 114 static int      smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
 115                         caller_context_t *);
 116 static void     smbfs_rele_fid(smbnode_t *, struct smb_cred *);
 117 static uint32_t xvattr_to_dosattr(smbnode_t *, struct vattr *);
 118 
 119 /*
 120  * These are the vnode ops routines which implement the vnode interface to
 121  * the networked file system.  These routines just take their parameters,
 122  * make them look networkish by putting the right info into interface structs,
 123  * and then calling the appropriate remote routine(s) to do the work.
 124  *
 125  * Note on directory name lookup cacheing:  If we detect a stale fhandle,
 126  * we purge the directory cache relative to that vnode.  This way, the
 127  * user won't get burned by the cache repeatedly.  See <smbfs/smbnode.h> for
 128  * more details on smbnode locking.
 129  */
 130 
 131 static int      smbfs_open(vnode_t **, int, cred_t *, caller_context_t *);
 132 static int      smbfs_close(vnode_t *, int, int, offset_t, cred_t *,
 133                         caller_context_t *);
 134 static int      smbfs_read(vnode_t *, struct uio *, int, cred_t *,
 135                         caller_context_t *);
 136 static int      smbfs_write(vnode_t *, struct uio *, int, cred_t *,
 137                         caller_context_t *);


 822         case SMBFSIO_GETSD:
 823                 error = smbfs_acl_iocget(vp, arg, flag, cr);
 824                 break;
 825 
 826         case SMBFSIO_SETSD:
 827                 error = smbfs_acl_iocset(vp, arg, flag, cr);
 828                 break;
 829 
 830         default:
 831                 error = ENOTTY;
 832                 break;
 833         }
 834 
 835         return (error);
 836 }
 837 
 838 
 839 /*
 840  * Return either cached or remote attributes. If get remote attr
 841  * use them to check and invalidate caches, then cache the new attributes.




 842  */
 843 /* ARGSUSED */
 844 static int
 845 smbfs_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
 846         caller_context_t *ct)
 847 {
 848         smbnode_t *np;
 849         smbmntinfo_t *smi;
 850 
 851         smi = VTOSMI(vp);
 852 
 853         if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
 854                 return (EIO);
 855 
 856         if (smi->smi_flags & SMI_DEAD || vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
 857                 return (EIO);
 858 
 859         /*
 860          * If it has been specified that the return value will
 861          * just be used as a hint, and we are only being asked


 869         if (flags & ATTR_HINT) {
 870                 if (vap->va_mask ==
 871                     (vap->va_mask & (AT_SIZE | AT_FSID | AT_RDEV))) {
 872                         mutex_enter(&np->r_statelock);
 873                         if (vap->va_mask | AT_SIZE)
 874                                 vap->va_size = np->r_size;
 875                         if (vap->va_mask | AT_FSID)
 876                                 vap->va_fsid = vp->v_vfsp->vfs_dev;
 877                         if (vap->va_mask | AT_RDEV)
 878                                 vap->va_rdev = vp->v_rdev;
 879                         mutex_exit(&np->r_statelock);
 880                         return (0);
 881                 }
 882         }
 883 
 884         return (smbfsgetattr(vp, vap, cr));
 885 }
 886 
 887 /* smbfsgetattr() in smbfs_client.c */
 888 





 889 /*ARGSUSED4*/
 890 static int
 891 smbfs_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
 892                 caller_context_t *ct)
 893 {
 894         vfs_t           *vfsp;
 895         smbmntinfo_t    *smi;
 896         int             error;
 897         uint_t          mask;
 898         struct vattr    oldva;
 899 
 900         vfsp = vp->v_vfsp;
 901         smi = VFTOSMI(vfsp);
 902 
 903         if (curproc->p_zone != smi->smi_zone_ref.zref_zone)
 904                 return (EIO);
 905 
 906         if (smi->smi_flags & SMI_DEAD || vfsp->vfs_flag & VFS_UNMOUNTED)
 907                 return (EIO);
 908 


 954         return (smbfssetattr(vp, vap, flags, cr));
 955 }
 956 
 957 /*
 958  * Mostly from Darwin smbfs_setattr()
 959  * but then modified a lot.
 960  */
 961 /* ARGSUSED */
 962 static int
 963 smbfssetattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr)
 964 {
 965         int             error = 0;
 966         smbnode_t       *np = VTOSMB(vp);
 967         uint_t          mask = vap->va_mask;
 968         struct timespec *mtime, *atime;
 969         struct smb_cred scred;
 970         int             cerror, modified = 0;
 971         unsigned short  fid;
 972         int have_fid = 0;
 973         uint32_t rights = 0;
 974         uint32_t dosattr = 0;
 975 
 976         ASSERT(curproc->p_zone == VTOSMI(vp)->smi_zone_ref.zref_zone);
 977 
 978         /*
 979          * There are no settable attributes on the XATTR dir,
 980          * so just silently ignore these.  On XATTR files,
 981          * you can set the size but nothing else.
 982          */
 983         if (vp->v_flag & V_XATTRDIR)
 984                 return (0);
 985         if (np->n_flag & N_XATTR) {
 986                 if (mask & AT_TIMES)
 987                         SMBVDEBUG("ignore set time on xattr\n");
 988                 mask &= AT_SIZE;
 989         }
 990 
 991         /*
 992          * If our caller is trying to set multiple attributes, they
 993          * can make no assumption about what order they are done in.
 994          * Here we try to do them in order of decreasing likelihood
 995          * of failure, just to minimize the chance we'll wind up
 996          * with a partially complete request.
 997          */
 998 
 999         /* Shared lock for (possible) n_fid use. */
1000         if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
1001                 return (EINTR);
1002         smb_credinit(&scred, cr);
1003 
1004         /*
1005          * If the caller has provided extensible attributes,
1006          * map those into DOS attributes supported by SMB.
1007          * Note: zero means "no change".
1008          */
1009         if (mask & AT_XVATTR)
1010                 dosattr = xvattr_to_dosattr(np, vap);
1011 
1012         /*
1013          * Will we need an open handle for this setattr?
1014          * If so, what rights will we need?
1015          */
1016         if (dosattr || (mask & (AT_ATIME | AT_MTIME))) {
1017                 rights |=
1018                     SA_RIGHT_FILE_WRITE_ATTRIBUTES;
1019         }
1020         if (mask & AT_SIZE) {
1021                 rights |=
1022                     SA_RIGHT_FILE_WRITE_DATA |
1023                     SA_RIGHT_FILE_APPEND_DATA;
1024         }
1025 
1026         /*
1027          * Only SIZE really requires a handle, but it's
1028          * simpler and more reliable to set via a handle.
1029          * Some servers like NT4 won't set times by path.
1030          * Also, we're usually setting everything anyway.
1031          */
1032         if (rights != 0) {
1033                 error = smbfs_smb_tmpopen(np, rights, &scred, &fid);
1034                 if (error) {
1035                         SMBVDEBUG("error %d opening %s\n",
1036                             error, np->n_rpath);
1037                         goto out;
1038                 }
1039                 have_fid = 1;
1040         }
1041 
1042         /*
1043          * If the server supports the UNIX extensions, right here is where
1044          * we'd support changes to uid, gid, mode, and possibly va_flags.
1045          * For now we claim to have made any such changes.
1046          */
1047 
1048         if (mask & AT_SIZE) {
1049                 /*
1050                  * If the new file size is less than what the client sees as
1051                  * the file size, then just change the size and invalidate
1052                  * the pages.


1069                          * so looks like we don't need to do this.
1070                          * Good thing, as this could take forever.
1071                          *
1072                          * XXX: Reportedly, writing one byte of zero
1073                          * at the end offset avoids problems here.
1074                          */
1075                         mutex_enter(&np->r_statelock);
1076                         np->r_size = vap->va_size;
1077                         mutex_exit(&np->r_statelock);
1078                         modified = 1;
1079                 }
1080         }
1081 
1082         /*
1083          * XXX: When Solaris has create_time, set that too.
1084          * Note: create_time is different from ctime.
1085          */
1086         mtime = ((mask & AT_MTIME) ? &vap->va_mtime : 0);
1087         atime = ((mask & AT_ATIME) ? &vap->va_atime : 0);
1088 
1089         if (dosattr || mtime || atime) {
1090                 /*
1091                  * Always use the handle-based set attr call now.
1092                  * Not trying to set DOS attributes here so pass zero.
1093                  */
1094                 ASSERT(have_fid);
1095                 error = smbfs_smb_setfattr(np, fid,
1096                     dosattr, mtime, atime, &scred);
1097                 if (error) {
1098                         SMBVDEBUG("set times error %d file %s\n",
1099                             error, np->n_rpath);
1100                 } else {
1101                         modified = 1;
1102                 }
1103         }
1104 
1105 out:
1106         if (modified) {
1107                 /*
1108                  * Invalidate attribute cache in case the server
1109                  * doesn't set exactly the attributes we asked.
1110                  */
1111                 smbfs_attrcache_remove(np);
1112         }
1113 
1114         if (have_fid) {
1115                 cerror = smbfs_smb_tmpclose(np, fid, &scred);
1116                 if (cerror)
1117                         SMBVDEBUG("error %d closing %s\n",
1118                             cerror, np->n_rpath);
1119         }
1120 
1121         smb_credrele(&scred);
1122         smbfs_rw_exit(&np->r_lkserlock);
1123 
1124         return (error);
1125 }
1126 
1127 /*
1128  * Helper function for extensible system attributes (PSARC 2007/315)
1129  * Compute the DOS attribute word to pass to _setfattr (see above).
1130  * This returns zero IFF no change is being made to attributes.
1131  * Otherwise return the new attributes or SMB_EFA_NORMAL.
1132  */
1133 static uint32_t
1134 xvattr_to_dosattr(smbnode_t *np, struct vattr *vap)
1135 {
1136         xvattr_t *xvap = (xvattr_t *)vap;
1137         xoptattr_t *xoap = NULL;
1138         uint32_t attr = np->r_attr.fa_attr;
1139         boolean_t anyset = B_FALSE;
1140 
1141         if ((xoap = xva_getxoptattr(xvap)) == NULL)
1142                 return (0);
1143 
1144         if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) {
1145                 if (xoap->xoa_archive)
1146                         attr |= SMB_FA_ARCHIVE;
1147                 else
1148                         attr &= ~SMB_FA_ARCHIVE;
1149                 XVA_SET_RTN(xvap, XAT_ARCHIVE);
1150                 anyset = B_TRUE;
1151         }
1152         if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) {
1153                 if (xoap->xoa_system)
1154                         attr |= SMB_FA_SYSTEM;
1155                 else
1156                         attr &= ~SMB_FA_SYSTEM;
1157                 XVA_SET_RTN(xvap, XAT_SYSTEM);
1158                 anyset = B_TRUE;
1159         }
1160         if (XVA_ISSET_REQ(xvap, XAT_READONLY)) {
1161                 if (xoap->xoa_readonly)
1162                         attr |= SMB_FA_RDONLY;
1163                 else
1164                         attr &= ~SMB_FA_RDONLY;
1165                 XVA_SET_RTN(xvap, XAT_READONLY);
1166                 anyset = B_TRUE;
1167         }
1168         if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) {
1169                 if (xoap->xoa_hidden)
1170                         attr |= SMB_FA_HIDDEN;
1171                 else
1172                         attr &= ~SMB_FA_HIDDEN;
1173                 XVA_SET_RTN(xvap, XAT_HIDDEN);
1174                 anyset = B_TRUE;
1175         }
1176 
1177         if (anyset == B_FALSE)
1178                 return (0);     /* no change */
1179         if (attr == 0)
1180                 attr = SMB_EFA_NORMAL;
1181 
1182         return (attr);
1183 }
1184 
1185 /*
1186  * smbfs_access_rwx()
1187  * Common function for smbfs_access, etc.
1188  *
1189  * The security model implemented by the FS is unusual
1190  * due to the current "single user mounts" restriction:
1191  * All access under a given mount point uses the CIFS
1192  * credentials established by the owner of the mount.
1193  *
1194  * Most access checking is handled by the CIFS server,
1195  * but we need sufficient Unix access checks here to
1196  * prevent other local Unix users from having access
1197  * to objects under this mount that the uid/gid/mode
1198  * settings in the mount would not allow.
1199  *
1200  * With this model, there is a case where we need the
1201  * ability to do an access check before we have the
1202  * vnode for an object.  This function takes advantage
1203  * of the fact that the uid/gid/mode is per mount, and
1204  * avoids the need for a vnode.
1205  *


3034                 /*
3035                  * Always indicate that ACLs are enabled and
3036                  * that we support ACE_T format, otherwise
3037                  * libsec will ask for ACLENT_T format data
3038                  * which we don't support.
3039                  */
3040                 *valp = _ACL_ACE_ENABLED;
3041                 break;
3042 
3043         case _PC_SYMLINK_MAX:   /* No symlinks until we do Unix extensions */
3044                 *valp = 0;
3045                 break;
3046 
3047         case _PC_XATTR_EXISTS:
3048                 if (vfs->vfs_flag & VFS_XATTR) {
3049                         *valp = smbfs_xa_exists(vp, cr);
3050                         break;
3051                 }
3052                 return (EINVAL);
3053 
3054         case _PC_SATTR_ENABLED:
3055         case _PC_SATTR_EXISTS:
3056                 *valp = 1;
3057                 break;
3058 
3059         case _PC_TIMESTAMP_RESOLUTION:
3060                 /*
3061                  * Windows times are tenths of microseconds
3062                  * (multiples of 100 nanoseconds).
3063                  */
3064                 *valp = 100L;
3065                 break;
3066 
3067         default:
3068                 return (fs_pathconf(vp, cmd, valp, cr, ct));
3069         }
3070         return (0);
3071 }
3072 
3073 /* ARGSUSED */
3074 static int
3075 smbfs_getsecattr(vnode_t *vp, vsecattr_t *vsa, int flag, cred_t *cr,
3076         caller_context_t *ct)
3077 {
3078         vfs_t *vfsp;