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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_vnops.c
          +++ new/usr/src/uts/common/fs/smbclnt/smbfs/smbfs_vnops.c
↓ open down ↓ 106 lines elided ↑ open up ↑
 107  107                          cred_t *);
 108  108  static int      smbfslookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr,
 109  109                          int cache_ok, caller_context_t *);
 110  110  static int      smbfsrename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm,
 111  111                          cred_t *cr, caller_context_t *);
 112  112  static int      smbfssetattr(vnode_t *, struct vattr *, int, cred_t *);
 113  113  static int      smbfs_accessx(void *, int, cred_t *);
 114  114  static int      smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
 115  115                          caller_context_t *);
 116  116  static void     smbfs_rele_fid(smbnode_t *, struct smb_cred *);
      117 +static uint32_t xvattr_to_dosattr(smbnode_t *, struct vattr *);
 117  118  
 118  119  /*
 119  120   * These are the vnode ops routines which implement the vnode interface to
 120  121   * the networked file system.  These routines just take their parameters,
 121  122   * make them look networkish by putting the right info into interface structs,
 122  123   * and then calling the appropriate remote routine(s) to do the work.
 123  124   *
 124  125   * Note on directory name lookup cacheing:  If we detect a stale fhandle,
 125  126   * we purge the directory cache relative to that vnode.  This way, the
 126  127   * user won't get burned by the cache repeatedly.  See <smbfs/smbnode.h> for
↓ open down ↓ 704 lines elided ↑ open up ↑
 831  832                  break;
 832  833          }
 833  834  
 834  835          return (error);
 835  836  }
 836  837  
 837  838  
 838  839  /*
 839  840   * Return either cached or remote attributes. If get remote attr
 840  841   * 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  842   */
 846  843  /* ARGSUSED */
 847  844  static int
 848  845  smbfs_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
 849  846          caller_context_t *ct)
 850  847  {
 851  848          smbnode_t *np;
 852  849          smbmntinfo_t *smi;
 853  850  
 854  851          smi = VTOSMI(vp);
↓ open down ↓ 27 lines elided ↑ open up ↑
 882  879                          mutex_exit(&np->r_statelock);
 883  880                          return (0);
 884  881                  }
 885  882          }
 886  883  
 887  884          return (smbfsgetattr(vp, vap, cr));
 888  885  }
 889  886  
 890  887  /* smbfsgetattr() in smbfs_client.c */
 891  888  
 892      -/*
 893      - * XXX
 894      - * This op should eventually support PSARC 2007/315, Extensible Attribute
 895      - * Interfaces, for richer metadata.
 896      - */
 897  889  /*ARGSUSED4*/
 898  890  static int
 899  891  smbfs_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr,
 900  892                  caller_context_t *ct)
 901  893  {
 902  894          vfs_t           *vfsp;
 903  895          smbmntinfo_t    *smi;
 904  896          int             error;
 905  897          uint_t          mask;
 906  898          struct vattr    oldva;
↓ open down ↓ 65 lines elided ↑ open up ↑
 972  964  {
 973  965          int             error = 0;
 974  966          smbnode_t       *np = VTOSMB(vp);
 975  967          uint_t          mask = vap->va_mask;
 976  968          struct timespec *mtime, *atime;
 977  969          struct smb_cred scred;
 978  970          int             cerror, modified = 0;
 979  971          unsigned short  fid;
 980  972          int have_fid = 0;
 981  973          uint32_t rights = 0;
      974 +        uint32_t dosattr = 0;
 982  975  
 983  976          ASSERT(curproc->p_zone == VTOSMI(vp)->smi_zone_ref.zref_zone);
 984  977  
 985  978          /*
 986  979           * There are no settable attributes on the XATTR dir,
 987  980           * so just silently ignore these.  On XATTR files,
 988  981           * you can set the size but nothing else.
 989  982           */
 990  983          if (vp->v_flag & V_XATTRDIR)
 991  984                  return (0);
↓ open down ↓ 10 lines elided ↑ open up ↑
1002  995           * of failure, just to minimize the chance we'll wind up
1003  996           * with a partially complete request.
1004  997           */
1005  998  
1006  999          /* Shared lock for (possible) n_fid use. */
1007 1000          if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
1008 1001                  return (EINTR);
1009 1002          smb_credinit(&scred, cr);
1010 1003  
1011 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 +        /*
1012 1013           * Will we need an open handle for this setattr?
1013 1014           * If so, what rights will we need?
1014 1015           */
1015      -        if (mask & (AT_ATIME | AT_MTIME)) {
     1016 +        if (dosattr || (mask & (AT_ATIME | AT_MTIME))) {
1016 1017                  rights |=
1017 1018                      SA_RIGHT_FILE_WRITE_ATTRIBUTES;
1018 1019          }
1019 1020          if (mask & AT_SIZE) {
1020 1021                  rights |=
1021 1022                      SA_RIGHT_FILE_WRITE_DATA |
1022 1023                      SA_RIGHT_FILE_APPEND_DATA;
1023 1024          }
1024 1025  
1025 1026          /*
1026 1027           * Only SIZE really requires a handle, but it's
1027 1028           * simpler and more reliable to set via a handle.
1028 1029           * Some servers like NT4 won't set times by path.
1029 1030           * Also, we're usually setting everything anyway.
1030 1031           */
1031      -        if (mask & (AT_SIZE | AT_ATIME | AT_MTIME)) {
     1032 +        if (rights != 0) {
1032 1033                  error = smbfs_smb_tmpopen(np, rights, &scred, &fid);
1033 1034                  if (error) {
1034 1035                          SMBVDEBUG("error %d opening %s\n",
1035 1036                              error, np->n_rpath);
1036 1037                          goto out;
1037 1038                  }
1038 1039                  have_fid = 1;
1039 1040          }
1040 1041  
1041 1042          /*
↓ open down ↓ 36 lines elided ↑ open up ↑
1078 1079                  }
1079 1080          }
1080 1081  
1081 1082          /*
1082 1083           * XXX: When Solaris has create_time, set that too.
1083 1084           * Note: create_time is different from ctime.
1084 1085           */
1085 1086          mtime = ((mask & AT_MTIME) ? &vap->va_mtime : 0);
1086 1087          atime = ((mask & AT_ATIME) ? &vap->va_atime : 0);
1087 1088  
1088      -        if (mtime || atime) {
     1089 +        if (dosattr || mtime || atime) {
1089 1090                  /*
1090 1091                   * Always use the handle-based set attr call now.
1091 1092                   * Not trying to set DOS attributes here so pass zero.
1092 1093                   */
1093 1094                  ASSERT(have_fid);
1094 1095                  error = smbfs_smb_setfattr(np, fid,
1095      -                    0, mtime, atime, &scred);
     1096 +                    dosattr, mtime, atime, &scred);
1096 1097                  if (error) {
1097 1098                          SMBVDEBUG("set times error %d file %s\n",
1098 1099                              error, np->n_rpath);
1099 1100                  } else {
1100 1101                          modified = 1;
1101 1102                  }
1102 1103          }
1103 1104  
1104 1105  out:
1105 1106          if (modified) {
↓ open down ↓ 11 lines elided ↑ open up ↑
1117 1118                              cerror, np->n_rpath);
1118 1119          }
1119 1120  
1120 1121          smb_credrele(&scred);
1121 1122          smbfs_rw_exit(&np->r_lkserlock);
1122 1123  
1123 1124          return (error);
1124 1125  }
1125 1126  
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 +/*
1127 1186   * smbfs_access_rwx()
1128 1187   * Common function for smbfs_access, etc.
1129 1188   *
1130 1189   * The security model implemented by the FS is unusual
1131 1190   * due to the current "single user mounts" restriction:
1132 1191   * All access under a given mount point uses the CIFS
1133 1192   * credentials established by the owner of the mount.
1134 1193   *
1135 1194   * Most access checking is handled by the CIFS server,
1136 1195   * but we need sufficient Unix access checks here to
↓ open down ↓ 1848 lines elided ↑ open up ↑
2985 3044                  *valp = 0;
2986 3045                  break;
2987 3046  
2988 3047          case _PC_XATTR_EXISTS:
2989 3048                  if (vfs->vfs_flag & VFS_XATTR) {
2990 3049                          *valp = smbfs_xa_exists(vp, cr);
2991 3050                          break;
2992 3051                  }
2993 3052                  return (EINVAL);
2994 3053  
     3054 +        case _PC_SATTR_ENABLED:
     3055 +        case _PC_SATTR_EXISTS:
     3056 +                *valp = 1;
     3057 +                break;
     3058 +
2995 3059          case _PC_TIMESTAMP_RESOLUTION:
2996 3060                  /*
2997 3061                   * Windows times are tenths of microseconds
2998 3062                   * (multiples of 100 nanoseconds).
2999 3063                   */
3000 3064                  *valp = 100L;
3001 3065                  break;
3002 3066  
3003 3067          default:
3004 3068                  return (fs_pathconf(vp, cmd, valp, cr, ct));
↓ open down ↓ 108 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX