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).
*/