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

*** 112,121 **** --- 112,122 ---- static int smbfssetattr(vnode_t *, struct vattr *, int, cred_t *); static int smbfs_accessx(void *, int, cred_t *); static int smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp, caller_context_t *); static void smbfs_rele_fid(smbnode_t *, struct smb_cred *); + static uint32_t xvattr_to_dosattr(smbnode_t *, struct vattr *); /* * These are the vnode ops routines which implement the vnode interface to * the networked file system. These routines just take their parameters, * make them look networkish by putting the right info into interface structs,
*** 836,849 **** /* * Return either cached or remote attributes. If get remote attr * use them to check and invalidate caches, then cache the new attributes. - * - * XXX - * This op should eventually support PSARC 2007/315, Extensible Attribute - * Interfaces, for richer metadata. */ /* ARGSUSED */ static int smbfs_getattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr, caller_context_t *ct) --- 837,846 ----
*** 887,901 **** return (smbfsgetattr(vp, vap, cr)); } /* smbfsgetattr() in smbfs_client.c */ - /* - * XXX - * This op should eventually support PSARC 2007/315, Extensible Attribute - * Interfaces, for richer metadata. - */ /*ARGSUSED4*/ static int smbfs_setattr(vnode_t *vp, struct vattr *vap, int flags, cred_t *cr, caller_context_t *ct) { --- 884,893 ----
*** 977,986 **** --- 969,979 ---- struct smb_cred scred; int cerror, modified = 0; unsigned short fid; int have_fid = 0; uint32_t rights = 0; + uint32_t dosattr = 0; ASSERT(curproc->p_zone == VTOSMI(vp)->smi_zone_ref.zref_zone); /* * There are no settable attributes on the XATTR dir,
*** 1007,1020 **** if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp))) return (EINTR); smb_credinit(&scred, cr); /* * Will we need an open handle for this setattr? * If so, what rights will we need? */ ! if (mask & (AT_ATIME | AT_MTIME)) { rights |= SA_RIGHT_FILE_WRITE_ATTRIBUTES; } if (mask & AT_SIZE) { rights |= --- 1000,1021 ---- if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp))) return (EINTR); smb_credinit(&scred, cr); /* + * If the caller has provided extensible attributes, + * map those into DOS attributes supported by SMB. + * Note: zero means "no change". + */ + if (mask & AT_XVATTR) + dosattr = xvattr_to_dosattr(np, vap); + + /* * Will we need an open handle for this setattr? * If so, what rights will we need? */ ! if (dosattr || (mask & (AT_ATIME | AT_MTIME))) { rights |= SA_RIGHT_FILE_WRITE_ATTRIBUTES; } if (mask & AT_SIZE) { rights |=
*** 1026,1036 **** * Only SIZE really requires a handle, but it's * simpler and more reliable to set via a handle. * Some servers like NT4 won't set times by path. * Also, we're usually setting everything anyway. */ ! if (mask & (AT_SIZE | AT_ATIME | AT_MTIME)) { error = smbfs_smb_tmpopen(np, rights, &scred, &fid); if (error) { SMBVDEBUG("error %d opening %s\n", error, np->n_rpath); goto out; --- 1027,1037 ---- * Only SIZE really requires a handle, but it's * simpler and more reliable to set via a handle. * Some servers like NT4 won't set times by path. * Also, we're usually setting everything anyway. */ ! if (rights != 0) { error = smbfs_smb_tmpopen(np, rights, &scred, &fid); if (error) { SMBVDEBUG("error %d opening %s\n", error, np->n_rpath); goto out;
*** 1083,1100 **** * Note: create_time is different from ctime. */ mtime = ((mask & AT_MTIME) ? &vap->va_mtime : 0); atime = ((mask & AT_ATIME) ? &vap->va_atime : 0); ! if (mtime || atime) { /* * Always use the handle-based set attr call now. * Not trying to set DOS attributes here so pass zero. */ ASSERT(have_fid); error = smbfs_smb_setfattr(np, fid, ! 0, mtime, atime, &scred); if (error) { SMBVDEBUG("set times error %d file %s\n", error, np->n_rpath); } else { modified = 1; --- 1084,1101 ---- * Note: create_time is different from ctime. */ mtime = ((mask & AT_MTIME) ? &vap->va_mtime : 0); atime = ((mask & AT_ATIME) ? &vap->va_atime : 0); ! if (dosattr || mtime || atime) { /* * Always use the handle-based set attr call now. * Not trying to set DOS attributes here so pass zero. */ ASSERT(have_fid); error = smbfs_smb_setfattr(np, fid, ! dosattr, mtime, atime, &scred); if (error) { SMBVDEBUG("set times error %d file %s\n", error, np->n_rpath); } else { modified = 1;
*** 1122,1131 **** --- 1123,1190 ---- return (error); } /* + * Helper function for extensible system attributes (PSARC 2007/315) + * Compute the DOS attribute word to pass to _setfattr (see above). + * This returns zero IFF no change is being made to attributes. + * Otherwise return the new attributes or SMB_EFA_NORMAL. + */ + static uint32_t + xvattr_to_dosattr(smbnode_t *np, struct vattr *vap) + { + xvattr_t *xvap = (xvattr_t *)vap; + xoptattr_t *xoap = NULL; + uint32_t attr = np->r_attr.fa_attr; + boolean_t anyset = B_FALSE; + + if ((xoap = xva_getxoptattr(xvap)) == NULL) + return (0); + + if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) { + if (xoap->xoa_archive) + attr |= SMB_FA_ARCHIVE; + else + attr &= ~SMB_FA_ARCHIVE; + XVA_SET_RTN(xvap, XAT_ARCHIVE); + anyset = B_TRUE; + } + if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) { + if (xoap->xoa_system) + attr |= SMB_FA_SYSTEM; + else + attr &= ~SMB_FA_SYSTEM; + XVA_SET_RTN(xvap, XAT_SYSTEM); + anyset = B_TRUE; + } + if (XVA_ISSET_REQ(xvap, XAT_READONLY)) { + if (xoap->xoa_readonly) + attr |= SMB_FA_RDONLY; + else + attr &= ~SMB_FA_RDONLY; + XVA_SET_RTN(xvap, XAT_READONLY); + anyset = B_TRUE; + } + if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) { + if (xoap->xoa_hidden) + attr |= SMB_FA_HIDDEN; + else + attr &= ~SMB_FA_HIDDEN; + XVA_SET_RTN(xvap, XAT_HIDDEN); + anyset = B_TRUE; + } + + if (anyset == B_FALSE) + return (0); /* no change */ + if (attr == 0) + attr = SMB_EFA_NORMAL; + + return (attr); + } + + /* * smbfs_access_rwx() * Common function for smbfs_access, etc. * * The security model implemented by the FS is unusual * due to the current "single user mounts" restriction:
*** 2990,2999 **** --- 3049,3063 ---- *valp = smbfs_xa_exists(vp, cr); break; } return (EINVAL); + case _PC_SATTR_ENABLED: + case _PC_SATTR_EXISTS: + *valp = 1; + break; + case _PC_TIMESTAMP_RESOLUTION: /* * Windows times are tenths of microseconds * (multiples of 100 nanoseconds). */