[CIFS] Allow reset of file to ATTR_NORMAL when archive bit not set
authorSteve French <sfrench@us.ibm.com>
Fri, 23 Mar 2007 00:45:08 +0000 (00:45 +0000)
committerSteve French <sfrench@us.ibm.com>
Fri, 23 Mar 2007 00:45:08 +0000 (00:45 +0000)
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>
fs/cifs/CHANGES
fs/cifs/inode.c

index 1cbe5615993c527bf1dc99f2e8b94d485471fbe0..5d1f4873d7016543623d9f990ee1fd1a3471fc74 100644 (file)
@@ -6,7 +6,10 @@ on smp system corrupts sequence number. Do not reread unnecessarily partial page
 (which we are about to overwrite anyway) when writing out file opened rw.
 When DOS attribute of file on non-Unix server's file changes on the server side
 from read-only back to read-write, reflect this change in default file mode
-(we had been leaving a file's mode read-only until the inode were reloaded)
+(we had been leaving a file's mode read-only until the inode were reloaded).
+Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute
+when archive dos attribute not set and we are changing mode back to writeable
+on server which does not support the Unix Extensions).
 
 Version 1.47
 ------------
index e75a844accd7b5d58060d4d2159730a7650dac96..f414526e476ab85221dbb79be24c64bf34fa76cd 100644 (file)
@@ -1196,6 +1196,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        struct cifsFileInfo *open_file = NULL;
        FILE_BASIC_INFO time_buf;
        int set_time = FALSE;
+       int set_dosattr = FALSE;
        __u64 mode = 0xFFFFFFFFFFFFFFFFULL;
        __u64 uid = 0xFFFFFFFFFFFFFFFFULL;
        __u64 gid = 0xFFFFFFFFFFFFFFFFULL;
@@ -1332,15 +1333,23 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        else if (attrs->ia_valid & ATTR_MODE) {
                rc = 0;
                if ((mode & S_IWUGO) == 0) /* not writeable */ {
-                       if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0)
+                       if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
+                               set_dosattr = TRUE;
                                time_buf.Attributes =
                                        cpu_to_le32(cifsInode->cifsAttrs |
                                                    ATTR_READONLY);
+                       }
                } else if ((mode & S_IWUGO) == S_IWUGO) {
-                       if (cifsInode->cifsAttrs & ATTR_READONLY)
+                       if (cifsInode->cifsAttrs & ATTR_READONLY) {
+                               set_dosattr = TRUE;
                                time_buf.Attributes =
                                        cpu_to_le32(cifsInode->cifsAttrs &
                                                    (~ATTR_READONLY));
+                               /* Windows ignores set to zero */
+                               if(time_buf.Attributes == 0)
+                                       time_buf.Attributes |= 
+                                               cpu_to_le32(ATTR_NORMAL);
+                       }
                }
                /* BB to be implemented -
                   via Windows security descriptors or streams */
@@ -1378,7 +1387,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
        } else
                time_buf.ChangeTime = 0;
 
-       if (set_time || time_buf.Attributes) {
+       if (set_time || set_dosattr) {
                time_buf.CreationTime = 0;      /* do not change */
                /* In the future we should experiment - try setting timestamps
                   via Handle (SetFileInfo) instead of by path */