aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2007-03-22 20:45:08 -0400
committerSteve French <sfrench@us.ibm.com>2007-03-22 20:45:08 -0400
commit066fcb06d3e27c258bc229bb688ced2b16daa6c2 (patch)
tree9e2dd78b4821f57f5727ec8ea05e3d95d9819ca6 /fs/cifs/inode.c
parent38e2aff670b681b6cc267aca307633cbcb48864b (diff)
[CIFS] Allow reset of file to ATTR_NORMAL when archive bit not set
When a file had a dos attribute of 0x1 (readonly - but dos attribute of archive was not set) - doing chmod 0777 or equivalent would try to set a dos attribute of 0 (which some servers ignore) rather than ATTR_NORMAL (0x20) which most servers accept. Does not affect servers which support the CIFS Unix Extensions. Acked-by: Prasad Potluri <pvp@us.ibm.com> Acked-by: Shirish Pargaonkar <shirishp@us.ibm.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index e75a844accd7..f414526e476a 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1196,6 +1196,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1196 struct cifsFileInfo *open_file = NULL; 1196 struct cifsFileInfo *open_file = NULL;
1197 FILE_BASIC_INFO time_buf; 1197 FILE_BASIC_INFO time_buf;
1198 int set_time = FALSE; 1198 int set_time = FALSE;
1199 int set_dosattr = FALSE;
1199 __u64 mode = 0xFFFFFFFFFFFFFFFFULL; 1200 __u64 mode = 0xFFFFFFFFFFFFFFFFULL;
1200 __u64 uid = 0xFFFFFFFFFFFFFFFFULL; 1201 __u64 uid = 0xFFFFFFFFFFFFFFFFULL;
1201 __u64 gid = 0xFFFFFFFFFFFFFFFFULL; 1202 __u64 gid = 0xFFFFFFFFFFFFFFFFULL;
@@ -1332,15 +1333,23 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1332 else if (attrs->ia_valid & ATTR_MODE) { 1333 else if (attrs->ia_valid & ATTR_MODE) {
1333 rc = 0; 1334 rc = 0;
1334 if ((mode & S_IWUGO) == 0) /* not writeable */ { 1335 if ((mode & S_IWUGO) == 0) /* not writeable */ {
1335 if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) 1336 if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1337 set_dosattr = TRUE;
1336 time_buf.Attributes = 1338 time_buf.Attributes =
1337 cpu_to_le32(cifsInode->cifsAttrs | 1339 cpu_to_le32(cifsInode->cifsAttrs |
1338 ATTR_READONLY); 1340 ATTR_READONLY);
1341 }
1339 } else if ((mode & S_IWUGO) == S_IWUGO) { 1342 } else if ((mode & S_IWUGO) == S_IWUGO) {
1340 if (cifsInode->cifsAttrs & ATTR_READONLY) 1343 if (cifsInode->cifsAttrs & ATTR_READONLY) {
1344 set_dosattr = TRUE;
1341 time_buf.Attributes = 1345 time_buf.Attributes =
1342 cpu_to_le32(cifsInode->cifsAttrs & 1346 cpu_to_le32(cifsInode->cifsAttrs &
1343 (~ATTR_READONLY)); 1347 (~ATTR_READONLY));
1348 /* Windows ignores set to zero */
1349 if(time_buf.Attributes == 0)
1350 time_buf.Attributes |=
1351 cpu_to_le32(ATTR_NORMAL);
1352 }
1344 } 1353 }
1345 /* BB to be implemented - 1354 /* BB to be implemented -
1346 via Windows security descriptors or streams */ 1355 via Windows security descriptors or streams */
@@ -1378,7 +1387,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1378 } else 1387 } else
1379 time_buf.ChangeTime = 0; 1388 time_buf.ChangeTime = 0;
1380 1389
1381 if (set_time || time_buf.Attributes) { 1390 if (set_time || set_dosattr) {
1382 time_buf.CreationTime = 0; /* do not change */ 1391 time_buf.CreationTime = 0; /* do not change */
1383 /* In the future we should experiment - try setting timestamps 1392 /* In the future we should experiment - try setting timestamps
1384 via Handle (SetFileInfo) instead of by path */ 1393 via Handle (SetFileInfo) instead of by path */