mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-07 20:33:58 -04:00
UPSTREAM: ANDROID: fuse-bpf: Avoid reusing uint64_t for file
This moves the backing/fd files to their own space, instead of reusing the userspace provided fds. Bug: 222619123 Test: fuse_test passes, on cuttlefish CtsCameraTestCases passes Signed-off-by: Daniel Rosenberg <drosen@google.com> Change-Id: I5d3b1ea8299f249ef5adc1ce2b7f45404a041208
This commit is contained in:
parent
cbe5f9cd71
commit
66d1fc6d06
6 changed files with 34 additions and 30 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue