summaryrefslogtreecommitdiff
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 0d9d2e6d7af6..fcbdbb6ad7bf 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -974,8 +974,8 @@ mkdir_get_info:
* failed to get it from the server or was set bogus */
if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
direntry->d_inode->i_nlink = 2;
+ mode &= ~current->fs->umask;
if (pTcon->unix_ext) {
- mode &= ~current->fs->umask;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
CIFSSMBUnixSetPerms(xid, pTcon, full_path,
mode,
@@ -994,9 +994,16 @@ mkdir_get_info:
CIFS_MOUNT_MAP_SPECIAL_CHR);
}
} else {
- /* BB to be implemented via Windows secrty descriptors
- eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
- -1, -1, local_nls); */
+ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
+ (mode & S_IWUGO) == 0) {
+ FILE_BASIC_INFO pInfo;
+ memset(&pInfo, 0, sizeof(pInfo));
+ pInfo.Attributes = cpu_to_le32(ATTR_READONLY);
+ CIFSSMBSetTimes(xid, pTcon, full_path,
+ &pInfo, cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ }
if (direntry->d_inode) {
direntry->d_inode->i_mode = mode;
direntry->d_inode->i_mode |= S_IFDIR;
@@ -1408,18 +1415,19 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
struct cifsInodeInfo *cifsInode;
+ struct inode *inode = direntry->d_inode;
xid = GetXid();
cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
direntry->d_name.name, attrs->ia_valid));
- cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
+ cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
/* check if we have permission to change attrs */
- rc = inode_change_ok(direntry->d_inode, attrs);
+ rc = inode_change_ok(inode, attrs);
if (rc < 0) {
FreeXid(xid);
return rc;
@@ -1432,7 +1440,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
FreeXid(xid);
return -ENOMEM;
}
- cifsInode = CIFS_I(direntry->d_inode);
+ cifsInode = CIFS_I(inode);
if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
/*
@@ -1443,9 +1451,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
will be truncated anyway? Also, should we error out here if
the flush returns error?
*/
- rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
+ rc = filemap_write_and_wait(inode->i_mapping);
if (rc != 0) {
- CIFS_I(direntry->d_inode)->write_behind_rc = rc;
+ cifsInode->write_behind_rc = rc;
rc = 0;
}
}
@@ -1521,9 +1529,8 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
*/
if (rc == 0) {
- rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
- cifs_truncate_page(direntry->d_inode->i_mapping,
- direntry->d_inode->i_size);
+ rc = cifs_vmtruncate(inode, attrs->ia_size);
+ cifs_truncate_page(inode->i_mapping, inode->i_size);
} else
goto cifs_setattr_exit;
}
@@ -1557,7 +1564,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
rc = 0;
#ifdef CONFIG_CIFS_EXPERIMENTAL
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
- rc = mode_to_acl(direntry->d_inode, full_path, mode);
+ rc = mode_to_acl(inode, full_path, mode);
else if ((mode & S_IWUGO) == 0) {
#else
if ((mode & S_IWUGO) == 0) {
@@ -1665,7 +1672,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
/* do not need local check to inode_check_ok since the server does
that */
if (!rc)
- rc = inode_setattr(direntry->d_inode, attrs);
+ rc = inode_setattr(inode, attrs);
cifs_setattr_exit:
kfree(full_path);
FreeXid(xid);