Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 066fcb06 authored by Steve French's avatar Steve French
Browse files

[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: default avatarPrasad Potluri <pvp@us.ibm.com>
Acked-by: default avatarShirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 38e2aff6
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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
------------
+12 −3
Original line number Diff line number Diff line
@@ -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 */