diff --git a/fs/fuse/backing.c b/fs/fuse/backing.c index 8db2a0c87f75..eac91793e7a5 100644 --- a/fs/fuse/backing.c +++ b/fs/fuse/backing.c @@ -1016,6 +1016,19 @@ void *fuse_file_write_iter_finalize(struct fuse_bpf_args *fa, return ERR_PTR(fwio->ret); } +long fuse_backing_ioctl(struct file *file, unsigned int command, unsigned long arg, int flags) +{ + struct fuse_file *ff = file->private_data; + long ret; + + if (flags & FUSE_IOCTL_COMPAT) + ret = -ENOTTY; + else + ret = vfs_ioctl(ff->backing_file, command, arg); + + return ret; +} + int fuse_file_flock_backing(struct file *file, int cmd, struct file_lock *fl) { struct fuse_file *ff = file->private_data; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 781f5fe3ab0e..ac3b4e9f5668 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3176,6 +3176,15 @@ long fuse_ioctl_common(struct file *file, unsigned int cmd, if (fuse_is_bad(inode)) return -EIO; +#ifdef CONFIG_FUSE_BPF + { + struct fuse_file *ff = file->private_data; + + /* TODO - this is simply passthrough, not a proper BPF filter */ + if (ff->backing_file) + return fuse_backing_ioctl(file, cmd, arg, flags); + } +#endif return fuse_do_ioctl(file, cmd, arg, flags); } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 05e43ad2215e..f758c09f77fe 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1580,6 +1580,8 @@ 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); +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); ssize_t fuse_backing_mmap(struct file *file, struct vm_area_struct *vma);