From f5c1e2ea71603bc2962041fef9dd902cb8626a1d Mon Sep 17 00:00:00 2001 From: Alan Tyson Date: Sat, 10 Mar 2007 06:05:14 +0000 Subject: [PATCH 1/3] [CIFS] reset mode when client notices that ATTR_READONLY is no longer set Signed-off-by: Alan Tyso Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/CHANGES | 3 +++ fs/cifs/inode.c | 6 ++++++ fs/cifs/readdir.c | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 6247628bdaed..1cbe5615993c 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -4,6 +4,9 @@ Fix mtime bouncing around from local idea of last write times to remote time. Fix hang (in i_size_read) when simultaneous size update of same remote file 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) Version 1.47 ------------ diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 86b9dbbd8441..e75a844accd7 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -494,6 +494,12 @@ int cifs_get_inode_info(struct inode **pinode, mode e.g. 555 */ if (cifsInfo->cifsAttrs & ATTR_READONLY) inode->i_mode &= ~(S_IWUGO); + else if ((inode->i_mode & S_IWUGO) == 0) + /* the ATTR_READONLY flag may have been */ + /* changed on server -- set any w bits */ + /* allowed by mnt_file_mode */ + inode->i_mode |= (S_IWUGO & + cifs_sb->mnt_file_mode); /* BB add code here - validate if device or weird share or device type? */ } diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 44cfb528797d..2a374d5215ab 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -219,6 +219,10 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, tmp_inode->i_mode |= S_IFREG; if (attr & ATTR_READONLY) tmp_inode->i_mode &= ~(S_IWUGO); + else if ((tmp_inode->i_mode & S_IWUGO) == 0) + /* the ATTR_READONLY flag may have been changed on */ + /* server -- set any w bits allowed by mnt_file_mode */ + tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); } /* could add code here - to validate if device or weird share type? */ /* can not fill in nlink here as in qpathinfo version and Unx search */ From 38e2aff670b681b6cc267aca307633cbcb48864b Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 16 Mar 2007 05:12:53 +0000 Subject: [PATCH 2/3] [CIFS] Do not negotiate new POSIX_PATH_OPERATIONS_CAP yet Samba server now expects that clients which send the new POSIX_PATH_OPERATIONS_CAP send all opens with this new SMB - and expects that clients that could send the new posix open/create but don't as indicating that they really want Windows semantics on that handle (which allows Samba to support clients which want to support both types of behaviors on different handles on the same mount) We will put this capability back in the SetFSInfo negotiation with servers like Samba when the new POSIXCreate (create/open/mkdir) code is finished. Signed-off-by: Steve French --- fs/cifs/cifspdu.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 0efdf35aab2c..e894545f99db 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -1887,7 +1887,13 @@ typedef struct { calls including posix open and posix unlink */ #ifdef CONFIG_CIFS_POSIX -#define CIFS_UNIX_CAP_MASK 0x0000003b +/* Can not set pathnames cap yet until we send new posix create SMB since + otherwise server can treat such handles opened with older ntcreatex + (by a new client which knows how to send posix path ops) + as non-posix handles (can affect write behavior with byte range locks. + We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */ +/* #define CIFS_UNIX_CAP_MASK 0x0000003b */ +#define CIFS_UNIX_CAP_MASK 0x0000001b #else #define CIFS_UNIX_CAP_MASK 0x00000013 #endif /* CONFIG_CIFS_POSIX */ From 066fcb06d3e27c258bc229bb688ced2b16daa6c2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 23 Mar 2007 00:45:08 +0000 Subject: [PATCH 3/3] [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 Acked-by: Shirish Pargaonkar Signed-off-by: Steve French --- fs/cifs/CHANGES | 5 ++++- fs/cifs/inode.c | 15 ++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 1cbe5615993c..5d1f4873d701 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -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 ------------ 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) 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 */