mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
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>
This commit is contained in:
parent
c1d82215d3
commit
276a025699
@ -1749,17 +1749,29 @@ static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
|
||||
struct fuse_setattr_in *arg, bool trust_local_cmtime)
|
||||
static void iattr_to_fattr(struct mnt_idmap *idmap, struct fuse_conn *fc,
|
||||
struct iattr *iattr, struct fuse_setattr_in *arg,
|
||||
bool trust_local_cmtime)
|
||||
{
|
||||
unsigned ivalid = iattr->ia_valid;
|
||||
|
||||
if (ivalid & ATTR_MODE)
|
||||
arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
|
||||
if (ivalid & ATTR_UID)
|
||||
arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
|
||||
if (ivalid & ATTR_GID)
|
||||
arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
|
||||
|
||||
if (ivalid & ATTR_UID) {
|
||||
kuid_t fsuid = from_vfsuid(idmap, fc->user_ns, iattr->ia_vfsuid);
|
||||
|
||||
arg->valid |= FATTR_UID;
|
||||
arg->uid = from_kuid(fc->user_ns, fsuid);
|
||||
}
|
||||
|
||||
if (ivalid & ATTR_GID) {
|
||||
kgid_t fsgid = from_vfsgid(idmap, fc->user_ns, iattr->ia_vfsgid);
|
||||
|
||||
arg->valid |= FATTR_GID;
|
||||
arg->gid = from_kgid(fc->user_ns, fsgid);
|
||||
}
|
||||
|
||||
if (ivalid & ATTR_SIZE)
|
||||
arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
|
||||
if (ivalid & ATTR_ATIME) {
|
||||
@ -1879,8 +1891,8 @@ int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
|
||||
* vmtruncate() doesn't allow for this case, so do the rlimit checking
|
||||
* and the actual truncation by hand.
|
||||
*/
|
||||
int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
|
||||
struct file *file)
|
||||
int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr, struct file *file)
|
||||
{
|
||||
struct inode *inode = d_inode(dentry);
|
||||
struct fuse_mount *fm = get_fuse_mount(inode);
|
||||
@ -1900,7 +1912,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
|
||||
if (!fc->default_permissions)
|
||||
attr->ia_valid |= ATTR_FORCE;
|
||||
|
||||
err = setattr_prepare(&nop_mnt_idmap, dentry, attr);
|
||||
err = setattr_prepare(idmap, dentry, attr);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -1959,7 +1971,7 @@ int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
|
||||
|
||||
memset(&inarg, 0, sizeof(inarg));
|
||||
memset(&outarg, 0, sizeof(outarg));
|
||||
iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
|
||||
iattr_to_fattr(idmap, fc, attr, &inarg, trust_local_cmtime);
|
||||
if (file) {
|
||||
struct fuse_file *ff = file->private_data;
|
||||
inarg.valid |= FATTR_FH;
|
||||
@ -2094,7 +2106,7 @@ static int fuse_setattr(struct mnt_idmap *idmap, struct dentry *entry,
|
||||
if (!attr->ia_valid)
|
||||
return 0;
|
||||
|
||||
ret = fuse_do_setattr(entry, attr, file);
|
||||
ret = fuse_do_setattr(idmap, entry, attr, file);
|
||||
if (!ret) {
|
||||
/*
|
||||
* If filesystem supports acls it may have updated acl xattrs in
|
||||
|
@ -2971,7 +2971,7 @@ static void fuse_do_truncate(struct file *file)
|
||||
attr.ia_file = file;
|
||||
attr.ia_valid |= ATTR_FILE;
|
||||
|
||||
fuse_do_setattr(file_dentry(file), &attr, file);
|
||||
fuse_do_setattr(file_mnt_idmap(file), file_dentry(file), &attr, file);
|
||||
}
|
||||
|
||||
static inline loff_t fuse_round_up(struct fuse_conn *fc, loff_t off)
|
||||
|
@ -1324,8 +1324,8 @@ bool fuse_write_update_attr(struct inode *inode, loff_t pos, ssize_t written);
|
||||
int fuse_flush_times(struct inode *inode, struct fuse_file *ff);
|
||||
int fuse_write_inode(struct inode *inode, struct writeback_control *wbc);
|
||||
|
||||
int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
|
||||
struct file *file);
|
||||
int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
|
||||
struct iattr *attr, struct file *file);
|
||||
|
||||
void fuse_set_initialized(struct fuse_conn *fc);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user