<p>Did you actually see a need for this fix? Even though the semantics of fuse_setattr allow for multiple attributes coming in the same call, it never happens practically. This is because the POSIX system calls which exist, change only one attribute at a time (chmod, chown, utimes) and fuse performs these calls synchronously. Maybe in the future if fuse (kernel module) does some kind of aggregation of these calls (quite tricky actually) into a single setattr call, moving in this direction might make sense.</p>
<p><br></p><p>Avati</p><p><br></p>
<p></p><blockquote>On Jan 23, 2009 7:48 AM, &quot;Filipe Maia&quot; &lt;<a href="mailto:filipe@xray.bmc.uu.se" target="_blank">filipe@xray.bmc.uu.se</a>&gt; wrote:<br><br>Hi,<br>
<br>
There is a problem with fuse_setattr() when the valid flag matches<br>
more than one condition.<br>
Imagine the following situation:<br>
<br>
A file is created by the root and it&#39;s mode changed to 6555. Then the<br>
owner is change to someone else.<br>
When &nbsp;this happens the setuid and setgid bits are removed at the same<br>
as the owner is changed.<br>
In this case valid == FUSE_SET_ATTR_MODE|FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID.<br>
<br>
Due to the if else structure of the code the chown call will only<br>
change the permissions it will not actually change the owner. Only the<br>
second chown call will change the owner.<br>
Changing the if else to a bunch of ifs causes problem which I think<br>
are related to double freeing of some variables. It seems to me that<br>
with the current code it&#39;s difficult to do<br>
two fops from the same setattr.<br>
<br>
The best solution I found for now was to use the following patch:<br>
<br>
--- fuse-bridge.c.old &nbsp; 2009-01-23 16:39:32.000000000 +0100<br>
+++ fuse-bridge.c &nbsp; &nbsp; &nbsp; 2009-01-23 16:38:43.000000000 +0100<br>
@@ -858,11 +858,10 @@<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int valid,<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; struct fuse_file_info *fi)<br>
&nbsp;{<br>
-<br>
- &nbsp; &nbsp; &nbsp; &nbsp;if (valid &amp; FUSE_SET_ATTR_MODE)<br>
- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;do_chmod (req, ino, attr, fi);<br>
- &nbsp; &nbsp; &nbsp; &nbsp;else if (valid &amp; (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;if (valid &amp; (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; do_chown (req, ino, attr, valid, fi);<br>
+ &nbsp; &nbsp; &nbsp; &nbsp;else if (valid &amp; FUSE_SET_ATTR_MODE)<br>
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;do_chmod (req, ino, attr, fi);<br>
 &nbsp; &nbsp; &nbsp; &nbsp; else if (valid &amp; FUSE_SET_ATTR_SIZE)<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; do_truncate (req, ino, attr, fi);<br>
 &nbsp; &nbsp; &nbsp; &nbsp; else if (valid &amp; (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))<br>
<br>
Having the USE_SET_ATTR_UID | FUSE_SET_ATTR_GID tested before<br>
FUSE_SET_ATTR_MOD will cause the correct behaviour with the chown on<br>
my machine.<br>
But hardly seems like a proper solution. The best way I think would be<br>
to test all possible flags one at a time, but I didn&#39;t manage to get<br>
that working.<br>
<br>
Filipe<br>
<br>
<br>
_______________________________________________<br>
Gluster-devel mailing list<br>
<a href="mailto:Gluster-devel@nongnu.org" target="_blank">Gluster-devel@nongnu.org</a><br>
<a href="http://lists.nongnu.org/mailman/listinfo/gluster-devel" target="_blank">http://lists.nongnu.org/mailman/listinfo/gluster-devel</a><br>
</blockquote><p></p>