diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 0ef46f6e0267..125abfeb4053 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3103,6 +3103,16 @@ static ssize_t fuse_copy_file_range(struct file *src_file, loff_t src_off, return ret; } +static int fuse_file_fadvise(struct file *file, loff_t offset, loff_t len, int advice) +{ + struct fuse_file *ff = file->private_data; + + if (fuse_is_passthrough(ff)) + return fuse_passthrough_fadvise(ff, offset, len, advice); + + return generic_fadvise(file, offset, len, advice); +} + static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read_iter = fuse_file_read_iter, @@ -3123,6 +3133,7 @@ static const struct file_operations fuse_file_operations = { .fallocate = fuse_file_fallocate, .copy_file_range = fuse_copy_file_range, .setlease = generic_setlease, + .fadvise = fuse_file_fadvise, }; static const struct address_space_operations fuse_file_aops = { diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 8546855386b5..893ddc33049a 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1316,6 +1316,7 @@ ssize_t fuse_passthrough_splice_write(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags); ssize_t fuse_passthrough_mmap(struct file *file, struct vm_area_struct *vma); +int fuse_passthrough_fadvise(struct fuse_file *ff, loff_t offset, loff_t len, int advice); #ifdef CONFIG_SYSCTL extern int fuse_sysctl_register(void); diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c index b43d3e0f7081..12aaaf0a2bbb 100644 --- a/fs/fuse/passthrough.c +++ b/fs/fuse/passthrough.c @@ -148,6 +148,19 @@ ssize_t fuse_passthrough_mmap(struct file *file, struct vm_area_struct *vma) return backing_file_mmap(backing_file, vma, &ctx); } +int fuse_passthrough_fadvise(struct fuse_file *ff, loff_t offset, loff_t len, int advice) +{ + struct file *backing_file = fuse_file_passthrough(ff); + const struct cred *old_cred; + int ret; + + old_cred = override_creds(ff->cred); + ret = vfs_fadvise(backing_file, offset, len, advice); + revert_creds(old_cred); + + return ret; +} + /* * Setup passthrough to a backing file. *