This adds a backing implementation for mapping, but no bpf counterpart yet. Signed-off-by: Daniel Rosenberg <drosen@xxxxxxxxxx> Signed-off-by: Paul Lawrence <paullawrence@xxxxxxxxxx> --- fs/fuse/backing.c | 37 +++++++++++++++++++++++++++++++++++++ fs/fuse/file.c | 6 ++++++ fs/fuse/fuse_i.h | 3 +++ 3 files changed, 46 insertions(+) diff --git a/fs/fuse/backing.c b/fs/fuse/backing.c index 51088701e7ad..fa8805e24061 100644 --- a/fs/fuse/backing.c +++ b/fs/fuse/backing.c @@ -77,6 +77,43 @@ int parse_fuse_entry_bpf(struct fuse_entry_bpf *feb) return err; } +ssize_t fuse_backing_mmap(struct file *file, struct vm_area_struct *vma) +{ + int ret; + struct fuse_file *ff = file->private_data; + struct inode *fuse_inode = file_inode(file); + struct file *backing_file = ff->backing_file; + struct inode *backing_inode = file_inode(backing_file); + + if (!backing_file->f_op->mmap) + return -ENODEV; + + if (WARN_ON(file != vma->vm_file)) + return -EIO; + + vma->vm_file = get_file(backing_file); + + ret = call_mmap(vma->vm_file, vma); + + if (ret) + fput(backing_file); + else + fput(file); + + if (file->f_flags & O_NOATIME) + return ret; + + if ((!timespec64_equal(&fuse_inode->i_mtime, &backing_inode->i_mtime) || + !timespec64_equal(&fuse_inode->i_ctime, + &backing_inode->i_ctime))) { + fuse_inode->i_mtime = backing_inode->i_mtime; + fuse_inode->i_ctime = backing_inode->i_ctime; + } + touch_atime(&file->f_path); + + return ret; +} + /******************************************************************************* * Directory operations after here * ******************************************************************************/ diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 4fa2ebc068f0..138890eae07c 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -2452,6 +2452,12 @@ static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma) if (FUSE_IS_DAX(file_inode(file))) return fuse_dax_mmap(file, vma); +#ifdef CONFIG_FUSE_BPF + /* TODO - this is simply passthrough, not a proper BPF filter */ + if (ff->backing_file) + return fuse_backing_mmap(file, vma); +#endif + if (ff->open_flags & FOPEN_DIRECT_IO) { /* Can't provide the coherency needed for MAP_SHARED */ if (vma->vm_flags & VM_MAYSHARE) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 30ddc298fb27..a9653f71c145 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1404,8 +1404,11 @@ struct fuse_entry_bpf { struct bpf_prog *bpf; }; + int parse_fuse_entry_bpf(struct fuse_entry_bpf *feb); +ssize_t fuse_backing_mmap(struct file *file, struct vm_area_struct *vma); + struct fuse_lookup_io { struct fuse_entry_out feo; struct fuse_entry_bpf feb; -- 2.37.3.998.g577e59143f-goog