Skip to content

Commit

Permalink
ANDROID: fuse-bpf: Get correct inode in mkdir
Browse files Browse the repository at this point in the history
We were getting the inode with the parent inode info
Also change variable names to remove confusion
Also set bpf correctly in new inode

Bug: 293838958
Test: fuse_test, atest ScopedStorageDeviceTest,
	atest CtsScopedStorageHostTest
Signed-off-by: Paul Lawrence <paullawrence@google.com>
(cherry picked from https://android-review.googlesource.com/q/commit:12eb00420cad77d7b7fcfbd1088c921ae629e69d)
Merged-In: I0b6a6951599e0d211afd2243daacb98679503448
Change-Id: I0b6a6951599e0d211afd2243daacb98679503448
  • Loading branch information
PaulLawrenceGoogle committed Sep 5, 2023
1 parent 1594563 commit a1f654e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 11 deletions.
29 changes: 18 additions & 11 deletions fs/fuse/backing.c
Original file line number Diff line number Diff line change
Expand Up @@ -1445,47 +1445,54 @@ int fuse_mkdir_initialize(

int fuse_mkdir_backing(
struct fuse_bpf_args *fa,
struct inode *dir, struct dentry *entry, umode_t mode)
struct inode *dir_inode, struct dentry *entry, umode_t mode)
{
int err = 0;
const struct fuse_mkdir_in *fmi = fa->in_args[0].value;
struct fuse_inode *fuse_inode = get_fuse_inode(dir);
struct inode *backing_inode = fuse_inode->backing_inode;
struct fuse_inode *dir_fuse_inode = get_fuse_inode(dir_inode);
struct inode *dir_backing_inode = dir_fuse_inode->backing_inode;
struct path backing_path = {};
struct inode *inode = NULL;
struct dentry *d;

//TODO Actually deal with changing the backing entry in mkdir
get_fuse_backing_path(entry, &backing_path);
if (!backing_path.dentry)
return -EBADF;

inode_lock_nested(backing_inode, I_MUTEX_PARENT);
inode_lock_nested(dir_backing_inode, I_MUTEX_PARENT);
mode = fmi->mode;
if (!IS_POSIXACL(backing_inode))
if (!IS_POSIXACL(dir_backing_inode))
mode &= ~fmi->umask;
err = vfs_mkdir(&init_user_ns, backing_inode, backing_path.dentry, mode);
err = vfs_mkdir(&init_user_ns, dir_backing_inode, backing_path.dentry,
mode);
if (err)
goto out;
if (d_really_is_negative(backing_path.dentry) ||
unlikely(d_unhashed(backing_path.dentry))) {
d = lookup_one_len(entry->d_name.name, backing_path.dentry->d_parent,
entry->d_name.len);
struct dentry *d = lookup_one_len(entry->d_name.name,
backing_path.dentry->d_parent,
entry->d_name.len);

if (IS_ERR(d)) {
err = PTR_ERR(d);
goto out;
}
dput(backing_path.dentry);
backing_path.dentry = d;
}
inode = fuse_iget_backing(dir->i_sb, fuse_inode->nodeid, backing_inode);
inode = fuse_iget_backing(dir_inode->i_sb, 0,
backing_path.dentry->d_inode);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto out;
}
d_instantiate(entry, inode);
if (get_fuse_inode(inode)->bpf)
bpf_prog_put(get_fuse_inode(inode)->bpf);
get_fuse_inode(inode)->bpf = get_fuse_dentry(entry)->bpf;
get_fuse_dentry(entry)->bpf = NULL;
out:
inode_unlock(backing_inode);
inode_unlock(dir_backing_inode);
path_put(&backing_path);
return err;
}
Expand Down
33 changes: 33 additions & 0 deletions tools/testing/selftests/filesystems/fuse/fuse_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -2047,6 +2047,38 @@ static int bpf_test_create_and_remove_bpf(const char *mount_dir)
return result;
}

static int bpf_test_mkdir_and_remove_bpf(const char *mount_dir)
{
const char *dir = "dir";

int result = TEST_FAILURE;
int src_fd = -1;
int bpf_fd = -1;
int fuse_dev = -1;
int fd = -1;
int fd2 = -1;

TEST(src_fd = open(ft_src, O_DIRECTORY | O_RDONLY | O_CLOEXEC),
src_fd != -1);
TESTEQUAL(install_elf_bpf("test_bpf.bpf", "test_mkdir_remove", &bpf_fd,
NULL, NULL), 0);
TESTEQUAL(mount_fuse_no_init(mount_dir, bpf_fd, src_fd, &fuse_dev), 0);
TEST(fd = s_mkdir(s_path(s(mount_dir), s(dir)), 0777),
fd != -1);
TEST(fd2 = s_open(s_path(s(mount_dir), s(dir)), O_RDONLY),
fd2 != -1);

result = TEST_SUCCESS;
out:
close(fd2);
close(fd);
close(fuse_dev);
close(bpf_fd);
close(src_fd);
umount(mount_dir);
return result;
}

static void parse_range(const char *ranges, bool *run_test, size_t tests)
{
size_t i;
Expand Down Expand Up @@ -2175,6 +2207,7 @@ int main(int argc, char *argv[])
MAKE_TEST(bpf_test_lookup_postfilter),
MAKE_TEST(flock_test),
MAKE_TEST(bpf_test_create_and_remove_bpf),
MAKE_TEST(bpf_test_mkdir_and_remove_bpf),
};
#undef MAKE_TEST

Expand Down
22 changes: 22 additions & 0 deletions tools/testing/selftests/filesystems/fuse/test_bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -530,4 +530,26 @@ int createremovebpf_test(struct fuse_bpf_args *fa)
}
}

SEC("test_mkdir_remove")
int mkdirremovebpf_test(struct fuse_bpf_args *fa)
{
switch (fa->opcode) {
case FUSE_LOOKUP | FUSE_PREFILTER: {
return FUSE_BPF_BACKING | FUSE_BPF_POST_FILTER;
}

case FUSE_LOOKUP | FUSE_POSTFILTER: {
struct fuse_entry_bpf_out *febo = fa->out_args[1].value;

febo->bpf_action = FUSE_ACTION_REMOVE;
return 0;
}

case FUSE_OPENDIR | FUSE_PREFILTER: {
return -EIO;
}

default:
return FUSE_BPF_BACKING;
}
}

0 comments on commit a1f654e

Please sign in to comment.