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
3 changed files with 73 additions and 11 deletions
|
|
@ -1446,32 +1446,34 @@ int fuse_mkdir_initialize(
|
||||||
|
|
||||||
int fuse_mkdir_backing(
|
int fuse_mkdir_backing(
|
||||||
struct fuse_bpf_args *fa,
|
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;
|
int err = 0;
|
||||||
const struct fuse_mkdir_in *fmi = fa->in_args[0].value;
|
const struct fuse_mkdir_in *fmi = fa->in_args[0].value;
|
||||||
struct fuse_inode *fuse_inode = get_fuse_inode(dir);
|
struct fuse_inode *dir_fuse_inode = get_fuse_inode(dir_inode);
|
||||||
struct inode *backing_inode = fuse_inode->backing_inode;
|
struct inode *dir_backing_inode = dir_fuse_inode->backing_inode;
|
||||||
struct path backing_path = {};
|
struct path backing_path = {};
|
||||||
struct inode *inode = NULL;
|
struct inode *inode = NULL;
|
||||||
struct dentry *d;
|
|
||||||
|
|
||||||
//TODO Actually deal with changing the backing entry in mkdir
|
//TODO Actually deal with changing the backing entry in mkdir
|
||||||
get_fuse_backing_path(entry, &backing_path);
|
get_fuse_backing_path(entry, &backing_path);
|
||||||
if (!backing_path.dentry)
|
if (!backing_path.dentry)
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
|
|
||||||
inode_lock_nested(backing_inode, I_MUTEX_PARENT);
|
inode_lock_nested(dir_backing_inode, I_MUTEX_PARENT);
|
||||||
mode = fmi->mode;
|
mode = fmi->mode;
|
||||||
if (!IS_POSIXACL(backing_inode))
|
if (!IS_POSIXACL(dir_backing_inode))
|
||||||
mode &= ~fmi->umask;
|
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)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
if (d_really_is_negative(backing_path.dentry) ||
|
if (d_really_is_negative(backing_path.dentry) ||
|
||||||
unlikely(d_unhashed(backing_path.dentry))) {
|
unlikely(d_unhashed(backing_path.dentry))) {
|
||||||
d = lookup_one_len(entry->d_name.name, backing_path.dentry->d_parent,
|
struct dentry *d = lookup_one_len(entry->d_name.name,
|
||||||
entry->d_name.len);
|
backing_path.dentry->d_parent,
|
||||||
|
entry->d_name.len);
|
||||||
|
|
||||||
if (IS_ERR(d)) {
|
if (IS_ERR(d)) {
|
||||||
err = PTR_ERR(d);
|
err = PTR_ERR(d);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -1479,14 +1481,19 @@ int fuse_mkdir_backing(
|
||||||
dput(backing_path.dentry);
|
dput(backing_path.dentry);
|
||||||
backing_path.dentry = d;
|
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)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
d_instantiate(entry, inode);
|
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:
|
out:
|
||||||
inode_unlock(backing_inode);
|
inode_unlock(dir_backing_inode);
|
||||||
path_put(&backing_path);
|
path_put(&backing_path);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2047,6 +2047,38 @@ out:
|
||||||
return result;
|
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)
|
static void parse_range(const char *ranges, bool *run_test, size_t tests)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
@ -2175,6 +2207,7 @@ int main(int argc, char *argv[])
|
||||||
MAKE_TEST(bpf_test_lookup_postfilter),
|
MAKE_TEST(bpf_test_lookup_postfilter),
|
||||||
MAKE_TEST(flock_test),
|
MAKE_TEST(flock_test),
|
||||||
MAKE_TEST(bpf_test_create_and_remove_bpf),
|
MAKE_TEST(bpf_test_create_and_remove_bpf),
|
||||||
|
MAKE_TEST(bpf_test_mkdir_and_remove_bpf),
|
||||||
};
|
};
|
||||||
#undef MAKE_TEST
|
#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…
Add table
Add a link
Reference in a new issue