aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-05-09 22:28:02 +0000
committerSteve French <sfrench@us.ibm.com>2008-05-11 17:45:43 +0000
commit67750fb9e07940c078d1edb16fd736ccc92a4a4e (patch)
treee0f2f224e6b06f02fc7961f7e0e64263a826e8fa /fs/cifs/dir.c
parent02eadeffda169a45946c79270ec19f45eeafb8e7 (diff)
downloadlinux-67750fb9e07940c078d1edb16fd736ccc92a4a4e.tar.gz
[CIFS] when not using unix extensions, check for and set ATTR_READONLY on create and mkdir
When creating a directory on a CIFS share without POSIX extensions, and the given mode has no write bits set, set the ATTR_READONLY bit. When creating a file, set ATTR_READONLY if the create mode has no write bits set and we're not using unix extensions. There are some comments about this being problematic due to the VFS splitting creates into 2 parts. I'm not sure what that's actually talking about, but I'm assuming that it has something to do with how mknod is implemented. In the simple case where we have no unix extensions and we're just creating a regular file, there's no reason we can't set ATTR_READONLY. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 6ed775986be993..e4e0078a0526c9 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -119,6 +119,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
{
int rc = -ENOENT;
int xid;
+ int create_options = CREATE_NOT_DIR;
int oplock = 0;
int desiredAccess = GENERIC_READ | GENERIC_WRITE;
__u16 fileHandle;
@@ -176,9 +177,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
FreeXid(xid);
return -ENOMEM;
}
+
+ mode &= ~current->fs->umask;
+
+ /*
+ * if we're not using unix extensions, see if we need to set
+ * ATTR_READONLY on the create call
+ */
+ if (!pTcon->unix_ext && (mode & S_IWUGO) == 0)
+ create_options |= CREATE_OPTION_READONLY;
+
if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
- desiredAccess, CREATE_NOT_DIR,
+ desiredAccess, create_options,
&fileHandle, &oplock, buf, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
else
@@ -187,7 +198,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
if (rc == -EIO) {
/* old server, retry the open legacy style */
rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
- desiredAccess, CREATE_NOT_DIR,
+ desiredAccess, create_options,
&fileHandle, &oplock, buf, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
}
@@ -197,7 +208,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
/* If Open reported that we actually created a file
then we now have to set the mode if possible */
if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
- mode &= ~current->fs->umask;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
(__u64)current->fsuid,