ANDROID: fuse-bpf: Correctly put backing files
Backing files were sometimes put twice before, this fixes it so backing files sent in response to lookups are closed exactly once always Test: fuse_test pases, Android no longer throws a double close Bug: 273737310 Change-Id: Ifa75ffd846185cfabfd1f5bad504078d955c99ed Signed-off-by: Paul Lawrence <paullawrence@google.com> Signed-off-by: Alistair Delva <adelva@google.com>
This commit is contained in:
committed by
Treehugger Robot
parent
8e6265391e
commit
fd28863aa4
@@ -1172,8 +1172,6 @@ int fuse_handle_backing(struct fuse_entry_bpf *feb, struct inode **backing_inode
|
||||
path_put(backing_path);
|
||||
*backing_path = backing_file->f_path;
|
||||
path_get(backing_path);
|
||||
|
||||
fput(backing_file);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1249,36 +1247,55 @@ struct dentry *fuse_lookup_finalize(struct fuse_bpf_args *fa, struct inode *dir,
|
||||
struct fuse_entry_bpf *feb = container_of(febo, struct fuse_entry_bpf, out);
|
||||
int error = -1;
|
||||
u64 target_nodeid = 0;
|
||||
struct dentry *ret;
|
||||
|
||||
fd = get_fuse_dentry(entry);
|
||||
if (!fd)
|
||||
return ERR_PTR(-EIO);
|
||||
if (!fd) {
|
||||
ret = ERR_PTR(-EIO);
|
||||
goto out;
|
||||
}
|
||||
|
||||
bd = fd->backing_path.dentry;
|
||||
if (!bd)
|
||||
return ERR_PTR(-ENOENT);
|
||||
if (!bd) {
|
||||
ret = ERR_PTR(-ENOENT);
|
||||
goto out;
|
||||
}
|
||||
|
||||
backing_inode = bd->d_inode;
|
||||
if (!backing_inode)
|
||||
return 0;
|
||||
if (!backing_inode) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (d_inode)
|
||||
target_nodeid = get_fuse_inode(d_inode)->nodeid;
|
||||
|
||||
inode = fuse_iget_backing(dir->i_sb, target_nodeid, backing_inode);
|
||||
|
||||
if (IS_ERR(inode))
|
||||
return ERR_PTR(PTR_ERR(inode));
|
||||
if (IS_ERR(inode)) {
|
||||
ret = ERR_PTR(PTR_ERR(inode));
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = fuse_handle_bpf_prog(feb, dir, &get_fuse_inode(inode)->bpf);
|
||||
if (error)
|
||||
return ERR_PTR(error);
|
||||
if (error) {
|
||||
ret = ERR_PTR(error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = fuse_handle_backing(feb, &get_fuse_inode(inode)->backing_inode, &fd->backing_path);
|
||||
if (error)
|
||||
return ERR_PTR(error);
|
||||
if (error) {
|
||||
ret = ERR_PTR(error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
get_fuse_inode(inode)->nodeid = feo->nodeid;
|
||||
|
||||
return d_splice_alias(inode, entry);
|
||||
ret = d_splice_alias(inode, entry);
|
||||
out:
|
||||
if (feb->backing_file)
|
||||
fput(feb->backing_file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fuse_revalidate_backing(struct dentry *entry, unsigned int flags)
|
||||
|
||||
@@ -186,8 +186,10 @@ static bool backing_data_changed(struct fuse_inode *fi, struct dentry *entry,
|
||||
int err;
|
||||
bool ret = true;
|
||||
|
||||
if (!entry)
|
||||
return false;
|
||||
if (!entry) {
|
||||
ret = false;
|
||||
goto put_backing_file;
|
||||
}
|
||||
|
||||
get_fuse_backing_path(entry, &new_backing_path);
|
||||
new_backing_inode = fi->backing_inode;
|
||||
@@ -210,6 +212,9 @@ put_bpf:
|
||||
put_inode:
|
||||
iput(new_backing_inode);
|
||||
path_put(&new_backing_path);
|
||||
put_backing_file:
|
||||
if (bpf_arg->backing_file)
|
||||
fput(bpf_arg->backing_file);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
@@ -534,7 +539,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name
|
||||
backing_inode = backing_file->f_inode;
|
||||
*inode = fuse_iget_backing(sb, outarg->nodeid, backing_inode);
|
||||
if (!*inode)
|
||||
goto bpf_arg_out;
|
||||
goto out;
|
||||
|
||||
err = fuse_handle_backing(&bpf_arg,
|
||||
&get_fuse_inode(*inode)->backing_inode,
|
||||
@@ -545,8 +550,6 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name
|
||||
err = fuse_handle_bpf_prog(&bpf_arg, NULL, &get_fuse_inode(*inode)->bpf);
|
||||
if (err)
|
||||
goto out;
|
||||
bpf_arg_out:
|
||||
fput(backing_file);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@@ -578,6 +581,8 @@ out_queue_forget:
|
||||
out_put_forget:
|
||||
kfree(forget);
|
||||
out:
|
||||
if (bpf_arg.backing_file)
|
||||
fput(bpf_arg.backing_file);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user