diff options
author | Steve French <sfrench@us.ibm.com> | 2007-03-22 20:45:08 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2007-03-22 20:45:08 -0400 |
commit | 066fcb06d3e27c258bc229bb688ced2b16daa6c2 (patch) | |
tree | 9e2dd78b4821f57f5727ec8ea05e3d95d9819ca6 /fs/cifs/inode.c | |
parent | 38e2aff670b681b6cc267aca307633cbcb48864b (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.c | 15 |
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 */ |