aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2008-05-09 18:28:02 -0400
committerSteve French <sfrench@us.ibm.com>2008-05-11 13:45:43 -0400
commit67750fb9e07940c078d1edb16fd736ccc92a4a4e (patch)
treee0f2f224e6b06f02fc7961f7e0e64263a826e8fa /fs/cifs/dir.c
parent02eadeffda169a45946c79270ec19f45eeafb8e7 (diff)
[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 6ed775986be9..e4e0078a0526 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,
119{ 119{
120 int rc = -ENOENT; 120 int rc = -ENOENT;
121 int xid; 121 int xid;
122 int create_options = CREATE_NOT_DIR;
122 int oplock = 0; 123 int oplock = 0;
123 int desiredAccess = GENERIC_READ | GENERIC_WRITE; 124 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
124 __u16 fileHandle; 125 __u16 fileHandle;
@@ -176,9 +177,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
176 FreeXid(xid); 177 FreeXid(xid);
177 return -ENOMEM; 178 return -ENOMEM;
178 } 179 }
180
181 mode &= ~current->fs->umask;
182
183 /*
184 * if we're not using unix extensions, see if we need to set
185 * ATTR_READONLY on the create call
186 */
187 if (!pTcon->unix_ext && (mode & S_IWUGO) == 0)
188 create_options |= CREATE_OPTION_READONLY;
189
179 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) 190 if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
180 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, 191 rc = CIFSSMBOpen(xid, pTcon, full_path, disposition,
181 desiredAccess, CREATE_NOT_DIR, 192 desiredAccess, create_options,
182 &fileHandle, &oplock, buf, cifs_sb->local_nls, 193 &fileHandle, &oplock, buf, cifs_sb->local_nls,
183 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 194 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
184 else 195 else
@@ -187,7 +198,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
187 if (rc == -EIO) { 198 if (rc == -EIO) {
188 /* old server, retry the open legacy style */ 199 /* old server, retry the open legacy style */
189 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, 200 rc = SMBLegacyOpen(xid, pTcon, full_path, disposition,
190 desiredAccess, CREATE_NOT_DIR, 201 desiredAccess, create_options,
191 &fileHandle, &oplock, buf, cifs_sb->local_nls, 202 &fileHandle, &oplock, buf, cifs_sb->local_nls,
192 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 203 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
193 } 204 }
@@ -197,7 +208,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
197 /* If Open reported that we actually created a file 208 /* If Open reported that we actually created a file
198 then we now have to set the mode if possible */ 209 then we now have to set the mode if possible */
199 if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { 210 if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
200 mode &= ~current->fs->umask;
201 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 211 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
202 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, 212 CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
203 (__u64)current->fsuid, 213 (__u64)current->fsuid,