[linux-cifs-client] Reset of read-only attribute on Windows not
reflected in client
Alan Tyson
atyson at hp.com
Thu Jan 11 17:31:46 GMT 2007
I've been seeing the same problem that was mentioned in this posting
http://lists.samba.org/archive/samba/2006-September/125279.html
and can still duplicate this problem using the 1.45 tarball for RHEL4.
Having looked at the problem a little more, I do not believe that this
as been resolved in the lastest git archives.
Win 2003 or Win XP server and RHEL4 client using the following mount command
# mount -t cifs -o user=me,dom=mysom,uid=500,gid=500,file_mod=0777 \
> //server/test /mnt
Initially, the file is writeable, so the permissions appear as
-rwxrwxrwx. When the read-only flag is set on the server, then the
permissions change to -r-xr-xr-x. However, when the read-only flag is
reset on the server, the unix permissions remain at -r-xr-xr-x instead
of allowing write access to the file.
Network tracing shows that the server is definitely sending back file
attributes of 0x20 after the read-only flag has been reset (the
read-only flag is the least sig bit of the attributes). I can also see
that the cached inode for the file has cifsAttrs =0x20 whereas i_mode is
set to 0100555.
Looking at fill_in_inode I can see that the resetting of the w bits is
easy when the read-only attribute flag is set. All that needs to be
done is to reset all three w bits:
201 if (attr & ATTR_READONLY)
202 tmp_inode->i_mode &= ~(S_IWUGO);
However, there is no else clause to this statement, so the w bits don't
get set again if the read-only permissions are unset on the server.
Is this intentional? If not, I would like to begin a discussion on how
we could correct this.
I see that the main problem here is knowing which w bits to set. If I
add an else to the above which ORs the mode with (S_IWUGO &
cifs_sb->mnt_file_mode) then I break chmod. Chmod 700 ends up being
722. If I just set the owner's w bit, then the permissions are not
being set back to what they were originally. What is the feeling about
this additional else clause? Would this break anything?
if (attr & ATTR_READONLY)
tmp_inode->i_mode &= ~(S_IWUGO);
else {
/* if no w bits are set, assume that the flag has been changed
on the server and set the same w bits as would be set at
mount time
*/
if ((tmp_inode->i_mode & S_IWUGO) == 0)
tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode);
}
- Alan Tyson, HP Services, UK.
More information about the linux-cifs-client
mailing list