Commit 556208e1 authored by Alexander Mikhalitsyn's avatar Alexander Mikhalitsyn Committed by Miklos Szeredi

fuse: support idmap for mkdir/mknod/symlink/create/tmpfile

We have all the infrastructure in place, we just need
to pass an idmapping here.
Signed-off-by: default avatarAlexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Reviewed-by: default avatarChristian Brauner <brauner@kernel.org>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent d561254f
...@@ -614,9 +614,9 @@ static void free_ext_value(struct fuse_args *args) ...@@ -614,9 +614,9 @@ static void free_ext_value(struct fuse_args *args)
* If the filesystem doesn't support this, then fall back to separate * If the filesystem doesn't support this, then fall back to separate
* 'mknod' + 'open' requests. * 'mknod' + 'open' requests.
*/ */
static int fuse_create_open(struct inode *dir, struct dentry *entry, static int fuse_create_open(struct mnt_idmap *idmap, struct inode *dir,
struct file *file, unsigned int flags, struct dentry *entry, struct file *file,
umode_t mode, u32 opcode) unsigned int flags, umode_t mode, u32 opcode)
{ {
int err; int err;
struct inode *inode; struct inode *inode;
...@@ -673,11 +673,11 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, ...@@ -673,11 +673,11 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
args.out_args[1].size = sizeof(*outopenp); args.out_args[1].size = sizeof(*outopenp);
args.out_args[1].value = outopenp; args.out_args[1].value = outopenp;
err = get_create_ext(&nop_mnt_idmap, &args, dir, entry, mode); err = get_create_ext(idmap, &args, dir, entry, mode);
if (err) if (err)
goto out_free_ff; goto out_free_ff;
err = fuse_simple_request(NULL, fm, &args); err = fuse_simple_request(idmap, fm, &args);
free_ext_value(&args); free_ext_value(&args);
if (err) if (err)
goto out_free_ff; goto out_free_ff;
...@@ -734,6 +734,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry, ...@@ -734,6 +734,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
umode_t mode) umode_t mode)
{ {
int err; int err;
struct mnt_idmap *idmap = file_mnt_idmap(file);
struct fuse_conn *fc = get_fuse_conn(dir); struct fuse_conn *fc = get_fuse_conn(dir);
struct dentry *res = NULL; struct dentry *res = NULL;
...@@ -758,7 +759,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry, ...@@ -758,7 +759,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
if (fc->no_create) if (fc->no_create)
goto mknod; goto mknod;
err = fuse_create_open(dir, entry, file, flags, mode, FUSE_CREATE); err = fuse_create_open(idmap, dir, entry, file, flags, mode, FUSE_CREATE);
if (err == -ENOSYS) { if (err == -ENOSYS) {
fc->no_create = 1; fc->no_create = 1;
goto mknod; goto mknod;
...@@ -769,7 +770,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry, ...@@ -769,7 +770,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
return err; return err;
mknod: mknod:
err = fuse_mknod(&nop_mnt_idmap, dir, entry, mode, 0); err = fuse_mknod(idmap, dir, entry, mode, 0);
if (err) if (err)
goto out_dput; goto out_dput;
no_open: no_open:
...@@ -779,9 +780,9 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry, ...@@ -779,9 +780,9 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
/* /*
* Code shared between mknod, mkdir, symlink and link * Code shared between mknod, mkdir, symlink and link
*/ */
static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args, static int create_new_entry(struct mnt_idmap *idmap, struct fuse_mount *fm,
struct inode *dir, struct dentry *entry, struct fuse_args *args, struct inode *dir,
umode_t mode) struct dentry *entry, umode_t mode)
{ {
struct fuse_entry_out outarg; struct fuse_entry_out outarg;
struct inode *inode; struct inode *inode;
...@@ -803,12 +804,12 @@ static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args, ...@@ -803,12 +804,12 @@ static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,
args->out_args[0].value = &outarg; args->out_args[0].value = &outarg;
if (args->opcode != FUSE_LINK) { if (args->opcode != FUSE_LINK) {
err = get_create_ext(&nop_mnt_idmap, args, dir, entry, mode); err = get_create_ext(idmap, args, dir, entry, mode);
if (err) if (err)
goto out_put_forget_req; goto out_put_forget_req;
} }
err = fuse_simple_request(NULL, fm, args); err = fuse_simple_request(idmap, fm, args);
free_ext_value(args); free_ext_value(args);
if (err) if (err)
goto out_put_forget_req; goto out_put_forget_req;
...@@ -869,13 +870,13 @@ static int fuse_mknod(struct mnt_idmap *idmap, struct inode *dir, ...@@ -869,13 +870,13 @@ static int fuse_mknod(struct mnt_idmap *idmap, struct inode *dir,
args.in_args[0].value = &inarg; args.in_args[0].value = &inarg;
args.in_args[1].size = entry->d_name.len + 1; args.in_args[1].size = entry->d_name.len + 1;
args.in_args[1].value = entry->d_name.name; args.in_args[1].value = entry->d_name.name;
return create_new_entry(fm, &args, dir, entry, mode); return create_new_entry(idmap, fm, &args, dir, entry, mode);
} }
static int fuse_create(struct mnt_idmap *idmap, struct inode *dir, static int fuse_create(struct mnt_idmap *idmap, struct inode *dir,
struct dentry *entry, umode_t mode, bool excl) struct dentry *entry, umode_t mode, bool excl)
{ {
return fuse_mknod(&nop_mnt_idmap, dir, entry, mode, 0); return fuse_mknod(idmap, dir, entry, mode, 0);
} }
static int fuse_tmpfile(struct mnt_idmap *idmap, struct inode *dir, static int fuse_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
...@@ -887,7 +888,8 @@ static int fuse_tmpfile(struct mnt_idmap *idmap, struct inode *dir, ...@@ -887,7 +888,8 @@ static int fuse_tmpfile(struct mnt_idmap *idmap, struct inode *dir,
if (fc->no_tmpfile) if (fc->no_tmpfile)
return -EOPNOTSUPP; return -EOPNOTSUPP;
err = fuse_create_open(dir, file->f_path.dentry, file, file->f_flags, mode, FUSE_TMPFILE); err = fuse_create_open(idmap, dir, file->f_path.dentry, file,
file->f_flags, mode, FUSE_TMPFILE);
if (err == -ENOSYS) { if (err == -ENOSYS) {
fc->no_tmpfile = 1; fc->no_tmpfile = 1;
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
...@@ -914,7 +916,7 @@ static int fuse_mkdir(struct mnt_idmap *idmap, struct inode *dir, ...@@ -914,7 +916,7 @@ static int fuse_mkdir(struct mnt_idmap *idmap, struct inode *dir,
args.in_args[0].value = &inarg; args.in_args[0].value = &inarg;
args.in_args[1].size = entry->d_name.len + 1; args.in_args[1].size = entry->d_name.len + 1;
args.in_args[1].value = entry->d_name.name; args.in_args[1].value = entry->d_name.name;
return create_new_entry(fm, &args, dir, entry, S_IFDIR); return create_new_entry(idmap, fm, &args, dir, entry, S_IFDIR);
} }
static int fuse_symlink(struct mnt_idmap *idmap, struct inode *dir, static int fuse_symlink(struct mnt_idmap *idmap, struct inode *dir,
...@@ -930,7 +932,7 @@ static int fuse_symlink(struct mnt_idmap *idmap, struct inode *dir, ...@@ -930,7 +932,7 @@ static int fuse_symlink(struct mnt_idmap *idmap, struct inode *dir,
args.in_args[0].value = entry->d_name.name; args.in_args[0].value = entry->d_name.name;
args.in_args[1].size = len; args.in_args[1].size = len;
args.in_args[1].value = link; args.in_args[1].value = link;
return create_new_entry(fm, &args, dir, entry, S_IFLNK); return create_new_entry(idmap, fm, &args, dir, entry, S_IFLNK);
} }
void fuse_flush_time_update(struct inode *inode) void fuse_flush_time_update(struct inode *inode)
...@@ -1124,7 +1126,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, ...@@ -1124,7 +1126,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
args.in_args[0].value = &inarg; args.in_args[0].value = &inarg;
args.in_args[1].size = newent->d_name.len + 1; args.in_args[1].size = newent->d_name.len + 1;
args.in_args[1].value = newent->d_name.name; args.in_args[1].value = newent->d_name.name;
err = create_new_entry(fm, &args, newdir, newent, inode->i_mode); err = create_new_entry(NULL, fm, &args, newdir, newent, inode->i_mode);
if (!err) if (!err)
fuse_update_ctime_in_cache(inode); fuse_update_ctime_in_cache(inode);
else if (err == -EINTR) else if (err == -EINTR)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment