diff --git a/fs/fuse/backing.c b/fs/fuse/backing.c index 7cb9a17eb71c..63bfd60897b1 100644 --- a/fs/fuse/backing.c +++ b/fs/fuse/backing.c @@ -874,8 +874,8 @@ int fuse_lookup_initialize(struct fuse_args *fa, struct fuse_lookup_io *fli, .value = &fli->feo, }, .out_args[1] = (struct fuse_arg) { - .size = sizeof(fli->febo), - .value = &fli->febo, + .size = sizeof(fli->feb.out), + .value = &fli->feb.out, }, }; @@ -917,6 +917,7 @@ struct dentry *fuse_lookup_finalize(struct fuse_args *fa, struct inode *dir, struct inode *inode, *backing_inode; struct fuse_entry_out *feo = fa->out_args[0].value; struct fuse_entry_bpf_out *febo = fa->out_args[1].value; + struct fuse_entry_bpf *feb = container_of(febo, struct fuse_entry_bpf, out); fd = get_fuse_dentry(entry); if (!fd) @@ -952,7 +953,7 @@ struct dentry *fuse_lookup_finalize(struct fuse_args *fa, struct inode *dir, break; case FUSE_ACTION_REPLACE: { - struct file *bpf_file = (struct file*) febo->bpf_fd; + struct file *bpf_file = feb->bpf_file; struct bpf_prog *bpf_prog = ERR_PTR(-EINVAL); if (bpf_file && !IS_ERR(bpf_file)) @@ -985,7 +986,7 @@ struct dentry *fuse_lookup_finalize(struct fuse_args *fa, struct inode *dir, struct file *backing_file; fc = get_fuse_mount(dir)->fc; - backing_file = (struct file *) febo->backing_fd; + backing_file = feb->backing_file; if (!backing_file || IS_ERR(backing_file)) return ERR_PTR(-EIO); diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 3c9764124b6b..4b0e5a97f03c 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1964,11 +1964,12 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud, req->args->out_args[1].size == sizeof(struct fuse_entry_bpf_out)) { struct fuse_entry_bpf_out *febo = (struct fuse_entry_bpf_out *) req->args->out_args[1].value; + struct fuse_entry_bpf *feb = container_of(febo, struct fuse_entry_bpf, out); if (febo->backing_action == FUSE_ACTION_REPLACE) - febo->backing_fd = (uint64_t) fget(febo->backing_fd); + feb->backing_file = fget(febo->backing_fd); if (febo->bpf_action == FUSE_ACTION_REPLACE) - febo->bpf_fd = (uint64_t) fget(febo->bpf_fd); + feb->bpf_file = fget(febo->bpf_fd); } spin_lock(&fpq->lock); diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 85f2b608e9f0..ceda69466011 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -196,7 +196,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) || (flags & LOOKUP_REVAL)) { struct fuse_entry_out outarg; - struct fuse_entry_bpf_out bpf_outarg; + struct fuse_entry_bpf bpf_arg; FUSE_ARGS(args); struct fuse_forget_link *forget; u64 attr_version; @@ -234,7 +234,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) parent = dget_parent(entry); fuse_lookup_init(fm->fc, &args, get_node_id(d_inode(parent)), - &entry->d_name, &outarg, &bpf_outarg); + &entry->d_name, &outarg, &bpf_arg.out); ret = fuse_simple_request(fm, &args); dput(parent); @@ -243,15 +243,15 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags) * change the backing file ever, so not sure what is correct * here yet, especially as we can't return an error to user */ - if (bpf_outarg.backing_action == FUSE_ACTION_REPLACE) { - struct file *file = (struct file *) bpf_outarg.backing_fd; + if (bpf_arg.out.backing_action == FUSE_ACTION_REPLACE) { + struct file *file = bpf_arg.backing_file; if (file && !IS_ERR(file)) fput(file); } - if (bpf_outarg.bpf_action == FUSE_ACTION_REPLACE) { - struct file *file = (struct file *) bpf_outarg.bpf_fd; + if (bpf_arg.out.bpf_action == FUSE_ACTION_REPLACE) { + struct file *file = bpf_arg.bpf_file; if (file && !IS_ERR(file)) fput(file); @@ -498,12 +498,12 @@ bool fuse_invalid_attr(struct fuse_attr *attr) int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name, struct fuse_entry_out *outarg, - struct fuse_entry_bpf_out *bpf_outarg, struct dentry *entry, struct inode **inode) { struct fuse_mount *fm = get_fuse_mount_super(sb); FUSE_ARGS(args); + struct fuse_entry_bpf bpf_arg = {0}; struct fuse_forget_link *forget; u64 attr_version; int err; @@ -521,11 +521,11 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name attr_version = fuse_get_attr_version(fm->fc); - fuse_lookup_init(fm->fc, &args, nodeid, name, outarg, bpf_outarg); + fuse_lookup_init(fm->fc, &args, nodeid, name, outarg, &bpf_arg.out); err = fuse_simple_request(fm, &args); #ifdef CONFIG_FUSE_BPF - if (err == sizeof(*bpf_outarg)) { + if (err == sizeof(bpf_arg.out)) { /* TODO Make sure this handles invalid handles */ /* TODO Do we need the same code in revalidate */ struct file *backing_file; @@ -536,20 +536,20 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name goto out_queue_forget; err = -EINVAL; - if (bpf_outarg->backing_action != FUSE_ACTION_REPLACE) + if (bpf_arg.out.backing_action != FUSE_ACTION_REPLACE) goto out_queue_forget; - backing_file = (struct file *) bpf_outarg->backing_fd; + backing_file = bpf_arg.backing_file; if (!backing_file || IS_ERR(backing_file)) goto out_queue_forget; backing_inode = backing_file->f_inode; *inode = fuse_iget_backing(sb, backing_inode); if (!*inode) - goto bpf_outarg_out; + goto bpf_arg_out; - if (bpf_outarg->bpf_action == FUSE_ACTION_REPLACE) { - struct file *bpf_file = (struct file*) bpf_outarg->bpf_fd; + if (bpf_arg.out.bpf_action == FUSE_ACTION_REPLACE) { + struct file *bpf_file = bpf_arg.bpf_file; struct bpf_prog *bpf_prog = ERR_PTR(-EINVAL); if (bpf_file && !IS_ERR(bpf_file)) @@ -559,7 +559,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name iput(*inode); *inode = NULL; err = PTR_ERR(bpf_prog); - goto bpf_outarg_out; + goto bpf_arg_out; } get_fuse_inode(*inode)->bpf = bpf_prog; } @@ -567,7 +567,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name get_fuse_dentry(entry)->backing_path = backing_file->f_path; path_get(&get_fuse_dentry(entry)->backing_path); -bpf_outarg_out: +bpf_arg_out: fput(backing_file); } else #endif @@ -608,7 +608,6 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, { int err; struct fuse_entry_out outarg; - struct fuse_entry_bpf_out bpf_outarg = {0}; struct inode *inode; struct dentry *newent; bool outarg_valid = true; @@ -630,7 +629,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, locked = fuse_lock_inode(dir); err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name, - &outarg, &bpf_outarg, entry, &inode); + &outarg, entry, &inode); fuse_unlock_inode(dir, locked); if (err == -ENOENT) { outarg_valid = false; diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index c2dcb4e16ae3..a5a070461524 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -949,7 +949,6 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name, struct fuse_entry_out *outarg, - struct fuse_entry_bpf_out *bpf_outarg, struct dentry *entry, struct inode **inode); /** @@ -1519,7 +1518,7 @@ void *fuse_file_fallocate_finalize(struct fuse_args *fa, struct fuse_lookup_io { struct fuse_entry_out feo; - struct fuse_entry_bpf_out febo; + struct fuse_entry_bpf feb; }; int fuse_lookup_initialize(struct fuse_args *fa, struct fuse_lookup_io *feo, diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 2ff5282bb648..8025cf345196 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -933,14 +933,13 @@ static struct dentry *fuse_get_dentry(struct super_block *sb, inode = ilookup5(sb, handle->nodeid, fuse_inode_eq, &fii); if (!inode) { struct fuse_entry_out outarg; - struct fuse_entry_bpf_out bpf_outarg; const struct qstr name = QSTR_INIT(".", 1); if (!fc->export_support) goto out_err; err = fuse_lookup_name(sb, handle->nodeid, &name, &outarg, - &bpf_outarg, NULL, &inode); + NULL, &inode); if (err && err != -ENOENT) goto out_err; if (err || !inode) { @@ -1034,7 +1033,6 @@ static struct dentry *fuse_get_parent(struct dentry *child) struct inode *inode; struct dentry *parent; struct fuse_entry_out outarg; - struct fuse_entry_bpf_out bpf_outarg; const struct qstr name = QSTR_INIT("..", 2); int err; @@ -1042,7 +1040,7 @@ static struct dentry *fuse_get_parent(struct dentry *child) return ERR_PTR(-ESTALE); err = fuse_lookup_name(child_inode->i_sb, get_node_id(child_inode), - &name, &outarg, &bpf_outarg, NULL, &inode); + &name, &outarg, NULL, &inode); if (err) { if (err == -ENOENT) return ERR_PTR(-ESTALE); diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index dfb20abbf536..a0c34ffc97fe 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h @@ -527,6 +527,12 @@ struct fuse_entry_bpf_out { uint64_t bpf_fd; }; +struct fuse_entry_bpf { + struct fuse_entry_bpf_out out; + struct file *backing_file; + struct file *bpf_file; +}; + struct fuse_forget_in { uint64_t nlookup; };