@@ -1749,17 +1749,29 @@ static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
17491749 return true;
17501750}
17511751
1752- static void iattr_to_fattr (struct fuse_conn * fc , struct iattr * iattr ,
1753- struct fuse_setattr_in * arg , bool trust_local_cmtime )
1752+ static void iattr_to_fattr (struct mnt_idmap * idmap , struct fuse_conn * fc ,
1753+ struct iattr * iattr , struct fuse_setattr_in * arg ,
1754+ bool trust_local_cmtime )
17541755{
17551756 unsigned ivalid = iattr -> ia_valid ;
17561757
17571758 if (ivalid & ATTR_MODE )
17581759 arg -> valid |= FATTR_MODE , arg -> mode = iattr -> ia_mode ;
1759- if (ivalid & ATTR_UID )
1760- arg -> valid |= FATTR_UID , arg -> uid = from_kuid (fc -> user_ns , iattr -> ia_uid );
1761- if (ivalid & ATTR_GID )
1762- arg -> valid |= FATTR_GID , arg -> gid = from_kgid (fc -> user_ns , iattr -> ia_gid );
1760+
1761+ if (ivalid & ATTR_UID ) {
1762+ kuid_t fsuid = from_vfsuid (idmap , fc -> user_ns , iattr -> ia_vfsuid );
1763+
1764+ arg -> valid |= FATTR_UID ;
1765+ arg -> uid = from_kuid (fc -> user_ns , fsuid );
1766+ }
1767+
1768+ if (ivalid & ATTR_GID ) {
1769+ kgid_t fsgid = from_vfsgid (idmap , fc -> user_ns , iattr -> ia_vfsgid );
1770+
1771+ arg -> valid |= FATTR_GID ;
1772+ arg -> gid = from_kgid (fc -> user_ns , fsgid );
1773+ }
1774+
17631775 if (ivalid & ATTR_SIZE )
17641776 arg -> valid |= FATTR_SIZE , arg -> size = iattr -> ia_size ;
17651777 if (ivalid & ATTR_ATIME ) {
@@ -1879,8 +1891,8 @@ int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
18791891 * vmtruncate() doesn't allow for this case, so do the rlimit checking
18801892 * and the actual truncation by hand.
18811893 */
1882- int fuse_do_setattr (struct dentry * dentry , struct iattr * attr ,
1883- struct file * file )
1894+ int fuse_do_setattr (struct mnt_idmap * idmap , struct dentry * dentry ,
1895+ struct iattr * attr , struct file * file )
18841896{
18851897 struct inode * inode = d_inode (dentry );
18861898 struct fuse_mount * fm = get_fuse_mount (inode );
@@ -1900,7 +1912,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
19001912 if (!fc -> default_permissions )
19011913 attr -> ia_valid |= ATTR_FORCE ;
19021914
1903- err = setattr_prepare (& nop_mnt_idmap , dentry , attr );
1915+ err = setattr_prepare (idmap , dentry , attr );
19041916 if (err )
19051917 return err ;
19061918
@@ -1959,7 +1971,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
19591971
19601972 memset (& inarg , 0 , sizeof (inarg ));
19611973 memset (& outarg , 0 , sizeof (outarg ));
1962- iattr_to_fattr (fc , attr , & inarg , trust_local_cmtime );
1974+ iattr_to_fattr (idmap , fc , attr , & inarg , trust_local_cmtime );
19631975 if (file ) {
19641976 struct fuse_file * ff = file -> private_data ;
19651977 inarg .valid |= FATTR_FH ;
@@ -2094,7 +2106,7 @@ static int fuse_setattr(struct mnt_idmap *idmap, struct dentry *entry,
20942106 if (!attr -> ia_valid )
20952107 return 0 ;
20962108
2097- ret = fuse_do_setattr (entry , attr , file );
2109+ ret = fuse_do_setattr (idmap , entry , attr , file );
20982110 if (!ret ) {
20992111 /*
21002112 * If filesystem supports acls it may have updated acl xattrs in
0 commit comments