Print this page
6879933 Let SMBFS support extensible attributes per. PSARC 2007/315
@@ -112,10 +112,11 @@
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,14 +837,10 @@
/*
* 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)
@@ -887,15 +884,10 @@
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)
{
@@ -977,10 +969,11 @@
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,14 +1000,22 @@
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 (mask & (AT_ATIME | AT_MTIME)) {
+ if (dosattr || (mask & (AT_ATIME | AT_MTIME))) {
rights |=
SA_RIGHT_FILE_WRITE_ATTRIBUTES;
}
if (mask & AT_SIZE) {
rights |=
@@ -1026,11 +1027,11 @@
* 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)) {
+ 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,18 +1084,18 @@
* 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) {
+ 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,
- 0, mtime, atime, &scred);
+ dosattr, mtime, atime, &scred);
if (error) {
SMBVDEBUG("set times error %d file %s\n",
error, np->n_rpath);
} else {
modified = 1;
@@ -1122,10 +1123,68 @@
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,10 +3049,15 @@
*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).
*/