ANDROID: fuse-bpf: Get correct inode in mkdir
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 Change-Id: I0b6a6951599e0d211afd2243daacb98679503448 Signed-off-by: Paul Lawrence <paullawrence@google.com>
This commit is contained in:
parent
0fdb44964c
commit
8fb9de0877
@ -1446,32 +1446,34 @@ 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;
|
||||
@ -1479,14 +1481,19 @@ int fuse_mkdir_backing(
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user