[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>
This commit is contained in:
parent
38e2aff670
commit
066fcb06d3
|
@ -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.
|
(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
|
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
|
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
|
Version 1.47
|
||||||
------------
|
------------
|
||||||
|
|
|
@ -1196,6 +1196,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
struct cifsFileInfo *open_file = NULL;
|
struct cifsFileInfo *open_file = NULL;
|
||||||
FILE_BASIC_INFO time_buf;
|
FILE_BASIC_INFO time_buf;
|
||||||
int set_time = FALSE;
|
int set_time = FALSE;
|
||||||
|
int set_dosattr = FALSE;
|
||||||
__u64 mode = 0xFFFFFFFFFFFFFFFFULL;
|
__u64 mode = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
|
__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
|
__u64 gid = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
|
@ -1332,15 +1333,23 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
else if (attrs->ia_valid & ATTR_MODE) {
|
else if (attrs->ia_valid & ATTR_MODE) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
if ((mode & S_IWUGO) == 0) /* not writeable */ {
|
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 =
|
time_buf.Attributes =
|
||||||
cpu_to_le32(cifsInode->cifsAttrs |
|
cpu_to_le32(cifsInode->cifsAttrs |
|
||||||
ATTR_READONLY);
|
ATTR_READONLY);
|
||||||
|
}
|
||||||
} else if ((mode & S_IWUGO) == S_IWUGO) {
|
} else if ((mode & S_IWUGO) == S_IWUGO) {
|
||||||
if (cifsInode->cifsAttrs & ATTR_READONLY)
|
if (cifsInode->cifsAttrs & ATTR_READONLY) {
|
||||||
|
set_dosattr = TRUE;
|
||||||
time_buf.Attributes =
|
time_buf.Attributes =
|
||||||
cpu_to_le32(cifsInode->cifsAttrs &
|
cpu_to_le32(cifsInode->cifsAttrs &
|
||||||
(~ATTR_READONLY));
|
(~ATTR_READONLY));
|
||||||
|
/* Windows ignores set to zero */
|
||||||
|
if(time_buf.Attributes == 0)
|
||||||
|
time_buf.Attributes |=
|
||||||
|
cpu_to_le32(ATTR_NORMAL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* BB to be implemented -
|
/* BB to be implemented -
|
||||||
via Windows security descriptors or streams */
|
via Windows security descriptors or streams */
|
||||||
|
@ -1378,7 +1387,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
|
||||||
} else
|
} else
|
||||||
time_buf.ChangeTime = 0;
|
time_buf.ChangeTime = 0;
|
||||||
|
|
||||||
if (set_time || time_buf.Attributes) {
|
if (set_time || set_dosattr) {
|
||||||
time_buf.CreationTime = 0; /* do not change */
|
time_buf.CreationTime = 0; /* do not change */
|
||||||
/* In the future we should experiment - try setting timestamps
|
/* In the future we should experiment - try setting timestamps
|
||||||
via Handle (SetFileInfo) instead of by path */
|
via Handle (SetFileInfo) instead of by path */
|
||||||
|
|
Loading…
Reference in a new issue