Skip to content

Commit

Permalink
ANDROID: fuse-bpf: Add bpf to negative fuse_dentry
Browse files Browse the repository at this point in the history
Store the results of a negative lookup in the fuse_dentry so later
opcodes can use them to create files

Bug: 291705489
Test: fuse_test passes
Signed-off-by: Paul Lawrence <[email protected]>
Change-Id: I725e714a1d6ce43f24431d07c24e96349ef1a55c
  • Loading branch information
PaulLawrenceGoogle authored and bengris32 committed Jun 22, 2024
1 parent eea50e6 commit 3bc8d20
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 32 deletions.
64 changes: 32 additions & 32 deletions fs/fuse/backing.c
Original file line number Diff line number Diff line change
Expand Up @@ -1289,60 +1289,60 @@ int fuse_handle_bpf_prog(struct fuse_entry_bpf *feb, struct inode *parent,
struct dentry *fuse_lookup_finalize(struct fuse_bpf_args *fa, struct inode *dir,
struct dentry *entry, unsigned int flags)
{
struct fuse_dentry *fd;
struct dentry *bd;
struct fuse_dentry *fuse_entry;
struct dentry *backing_entry;
struct inode *inode = NULL, *backing_inode;
struct inode *d_inode = entry->d_inode;
struct inode *entry_inode = entry->d_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);
struct fuse_entry_bpf *feb = container_of(febo, struct fuse_entry_bpf,
out);
int error = -1;
u64 target_nodeid = 0;
struct dentry *ret;
struct dentry *ret = NULL;

fd = get_fuse_dentry(entry);
if (!fd) {
fuse_entry = get_fuse_dentry(entry);
if (!fuse_entry) {
ret = ERR_PTR(-EIO);
goto out;
}

bd = fd->backing_path.dentry;
if (!bd) {
backing_entry = fuse_entry->backing_path.dentry;
if (!backing_entry) {
ret = ERR_PTR(-ENOENT);
goto out;
}

backing_inode = bd->d_inode;
if (!backing_inode) {
ret = 0;
goto out;
}
if (entry_inode)
target_nodeid = get_fuse_inode(entry_inode)->nodeid;

if (d_inode)
target_nodeid = get_fuse_inode(d_inode)->nodeid;

inode = fuse_iget_backing(dir->i_sb, target_nodeid, backing_inode);
if (!inode) {
ret = ERR_PTR(-EIO);
goto out;
}
backing_inode = backing_entry->d_inode;
if (backing_inode)
inode = fuse_iget_backing(dir->i_sb, target_nodeid,
backing_inode);

error = fuse_handle_bpf_prog(feb, dir, &get_fuse_inode(inode)->bpf);
error = inode ?
fuse_handle_bpf_prog(feb, dir, &get_fuse_inode(inode)->bpf) :
fuse_handle_bpf_prog(feb, dir, &fuse_entry->bpf);
if (error) {
ret = ERR_PTR(error);
goto out;
}

error = fuse_handle_backing(feb, &get_fuse_inode(inode)->backing_inode, &fd->backing_path);
if (error) {
ret = ERR_PTR(error);
goto out;
}
if (inode) {
error = fuse_handle_backing(feb,
&get_fuse_inode(inode)->backing_inode,
&fuse_entry->backing_path);
if (error) {
ret = ERR_PTR(error);
goto out;
}

get_fuse_inode(inode)->nodeid = feo->nodeid;
ret = d_splice_alias(inode, entry);
if (!IS_ERR(ret))
inode = NULL;
get_fuse_inode(inode)->nodeid = feo->nodeid;
ret = d_splice_alias(inode, entry);
if (!IS_ERR(ret))
inode = NULL;
}
out:
iput(inode);
if (feb->backing_file)
Expand Down
5 changes: 5 additions & 0 deletions fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,14 @@ static void fuse_dentry_release(struct dentry *dentry)
{
struct fuse_dentry *fd = dentry->d_fsdata;

#ifdef CONFIG_FUSE_BPF
if (fd && fd->backing_path.dentry)
path_put(&fd->backing_path);

if (fd && fd->bpf)
bpf_prog_put(fd->bpf);
#endif

kfree_rcu(fd, rcu);
}
#endif
Expand Down
6 changes: 6 additions & 0 deletions fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,13 @@ struct fuse_dentry {
u64 time;
struct rcu_head rcu;
};

#ifdef CONFIG_FUSE_BPF
struct path backing_path;

/* bpf program *only* set for negative dentries */
struct bpf_prog *bpf;
#endif
};

static inline struct fuse_dentry *get_fuse_dentry(const struct dentry *entry)
Expand Down

0 comments on commit 3bc8d20

Please sign in to comment.