diff options
Diffstat (limited to 'sys/fs/smbfs/smbfs_vnops.c')
-rw-r--r-- | sys/fs/smbfs/smbfs_vnops.c | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c index ef1dc65..8ea1198 100644 --- a/sys/fs/smbfs/smbfs_vnops.c +++ b/sys/fs/smbfs/smbfs_vnops.c @@ -305,16 +305,30 @@ smbfs_setattr(ap) int old_n_dosattr; SMBVDEBUG("\n"); - if (vap->va_flags != VNOVAL) - return EOPNOTSUPP; isreadonly = (vp->v_mount->mnt_flag & MNT_RDONLY); /* * Disallow write attempts if the filesystem is mounted read-only. */ if ((vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL || - vap->va_mode != (mode_t)VNOVAL) && isreadonly) + vap->va_mode != (mode_t)VNOVAL || vap->va_flags != VNOVAL) && + isreadonly) return EROFS; + + /* + * We only support setting four flags. Don't allow setting others. + * + * We map UF_READONLY to SMB_FA_RDONLY, unlike the MacOS X version + * of this code, which maps both UF_IMMUTABLE AND SF_IMMUTABLE to + * SMB_FA_RDONLY. The immutable flags have different semantics + * than readonly, which is the reason for the difference. + */ + if (vap->va_flags != VNOVAL) { + if (vap->va_flags & ~(UF_HIDDEN|UF_SYSTEM|UF_ARCHIVE| + UF_READONLY)) + return EINVAL; + } + scred = smbfs_malloc_scred(); smb_makescred(scred, td, ap->a_cred); if (vap->va_size != VNOVAL) { @@ -353,12 +367,47 @@ smbfs_setattr(ap) goto out; } } - if (vap->va_mode != (mode_t)VNOVAL) { + if ((vap->va_flags != VNOVAL) || (vap->va_mode != (mode_t)VNOVAL)) { old_n_dosattr = np->n_dosattr; - if (vap->va_mode & S_IWUSR) - np->n_dosattr &= ~SMB_FA_RDONLY; - else - np->n_dosattr |= SMB_FA_RDONLY; + + if (vap->va_mode != (mode_t)VNOVAL) { + if (vap->va_mode & S_IWUSR) + np->n_dosattr &= ~SMB_FA_RDONLY; + else + np->n_dosattr |= SMB_FA_RDONLY; + } + + if (vap->va_flags != VNOVAL) { + if (vap->va_flags & UF_HIDDEN) + np->n_dosattr |= SMB_FA_HIDDEN; + else + np->n_dosattr &= ~SMB_FA_HIDDEN; + + if (vap->va_flags & UF_SYSTEM) + np->n_dosattr |= SMB_FA_SYSTEM; + else + np->n_dosattr &= ~SMB_FA_SYSTEM; + + if (vap->va_flags & UF_ARCHIVE) + np->n_dosattr |= SMB_FA_ARCHIVE; + else + np->n_dosattr &= ~SMB_FA_ARCHIVE; + + /* + * We only support setting the immutable / readonly + * bit for regular files. According to comments in + * the MacOS X version of this code, supporting the + * readonly bit on directories doesn't do the same + * thing in Windows as in Unix. + */ + if (vp->v_type == VREG) { + if (vap->va_flags & UF_READONLY) + np->n_dosattr |= SMB_FA_RDONLY; + else + np->n_dosattr &= ~SMB_FA_RDONLY; + } + } + if (np->n_dosattr != old_n_dosattr) { error = smbfs_smb_setpattr(np, np->n_dosattr, NULL, scred); if (error) |