Skip to content

Commit 276a025

Browse files
mihalicynMiklos Szeredi
authored andcommitted
fuse: support idmapped ->setattr op
Need to translate uid and gid in case of chown(2). Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com> Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
1 parent c1d8221 commit 276a025

File tree

3 files changed

+26
-14
lines changed

3 files changed

+26
-14
lines changed

fs/fuse/dir.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

fs/fuse/file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2971,7 +2971,7 @@ static void fuse_do_truncate(struct file *file)
29712971
attr.ia_file = file;
29722972
attr.ia_valid |= ATTR_FILE;
29732973

2974-
fuse_do_setattr(file_dentry(file), &attr, file);
2974+
fuse_do_setattr(file_mnt_idmap(file), file_dentry(file), &attr, file);
29752975
}
29762976

29772977
static inline loff_t fuse_round_up(struct fuse_conn *fc, loff_t off)

fs/fuse/fuse_i.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,8 +1324,8 @@ bool fuse_write_update_attr(struct inode *inode, loff_t pos, ssize_t written);
13241324
int fuse_flush_times(struct inode *inode, struct fuse_file *ff);
13251325
int fuse_write_inode(struct inode *inode, struct writeback_control *wbc);
13261326

1327-
int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
1328-
struct file *file);
1327+
int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
1328+
struct iattr *attr, struct file *file);
13291329

13301330
void fuse_set_initialized(struct fuse_conn *fc);
13311331

0 commit comments

Comments
 (0)