ANDROID: fuse-bpf: add bpf solution for splice read

filemap_splice_read is implemented through readahead and read_folio,
which results in sending fuse-bpf files to FuseDaemon.

When a backing file exists, redirect the splice read to the lowlevel
filesystem.

Bug: 337714402
Signed-off-by: Ed Tsai <ed.tsai@mediatek.com>
Change-Id: Ic22ad18a770fdf6911b2b13483b099da51edab10
This commit is contained in:
Ed Tsai
2024-05-02 21:39:53 +08:00
committed by Paul Lawrence
parent f8b483fb4d
commit f10e5f61de
3 changed files with 22 additions and 0 deletions
+13
View File
@@ -10,6 +10,7 @@
#include <linux/filelock.h>
#include <linux/filter.h>
#include <linux/fs_stack.h>
#include <linux/splice.h>
#include <linux/namei.h>
#include "../internal.h"
@@ -988,6 +989,18 @@ void *fuse_file_write_iter_finalize(struct fuse_bpf_args *fa,
return ERR_PTR(fwio->ret);
}
ssize_t fuse_splice_read_backing(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len, unsigned long flags)
{
struct fuse_file *ff = in->private_data;
ssize_t ret;
ret = vfs_splice_read(ff->backing_file, ppos, pipe, len, flags);
fuse_file_accessed(in, ff->backing_file);
return ret;
}
long fuse_backing_ioctl(struct file *file, unsigned int command, unsigned long arg, int flags)
{
struct fuse_file *ff = file->private_data;
+6
View File
@@ -1845,6 +1845,12 @@ static ssize_t fuse_splice_read(struct file *in, loff_t *ppos,
{
struct fuse_file *ff = in->private_data;
#ifdef CONFIG_FUSE_BPF
/* TODO - this is simply passthrough, not a proper BPF filter */
if (ff->backing_file)
return fuse_splice_read_backing(in, ppos, pipe, len, flags);
#endif
/* FOPEN_DIRECT_IO overrides FOPEN_PASSTHROUGH */
if (fuse_file_passthrough(ff) && !(ff->open_flags & FOPEN_DIRECT_IO))
return fuse_passthrough_splice_read(in, ppos, pipe, len, flags);
+3
View File
@@ -1813,6 +1813,9 @@ int fuse_file_write_iter_backing(struct fuse_bpf_args *fa,
void *fuse_file_write_iter_finalize(struct fuse_bpf_args *fa,
struct kiocb *iocb, struct iov_iter *from);
ssize_t fuse_splice_read_backing(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len, unsigned long flags);
long fuse_backing_ioctl(struct file *file, unsigned int command, unsigned long arg, int flags);
int fuse_file_flock_backing(struct file *file, int cmd, struct file_lock *fl);