summaryrefslogtreecommitdiff
path: root/fs/fuse
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2020-05-20 11:39:35 +0200
committerMiklos Szeredi <mszeredi@redhat.com>2020-05-20 11:39:35 +0200
commit2c4656dfd994538176db30ce09c02cc0dfc361ae (patch)
tree97b1493375d67921b68a15ed75c7a444ba82b310 /fs/fuse
parent6b2fb79963fbed7db3ef850926d913518fd5c62f (diff)
fuse: fix copy_file_range cache issues
a) Dirty cache needs to be written back not just in the writeback_cache case, since the dirty pages may come from memory maps. b) The fuse_writeback_range() helper takes an inclusive interval, so the end position needs to be pos+len-1 instead of pos+len. Fixes: 88bc7d5097a1 ("fuse: add support for copy_file_range()") Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/file.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 15812a8b3834..d365008fda44 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -3325,13 +3325,11 @@ static ssize_t __fuse_copy_file_range(struct file *file_in, loff_t pos_in,
if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb)
return -EXDEV;
- if (fc->writeback_cache) {
- inode_lock(inode_in);
- err = fuse_writeback_range(inode_in, pos_in, pos_in + len);
- inode_unlock(inode_in);
- if (err)
- return err;
- }
+ inode_lock(inode_in);
+ err = fuse_writeback_range(inode_in, pos_in, pos_in + len - 1);
+ inode_unlock(inode_in);
+ if (err)
+ return err;
inode_lock(inode_out);
@@ -3339,11 +3337,9 @@ static ssize_t __fuse_copy_file_range(struct file *file_in, loff_t pos_in,
if (err)
goto out;
- if (fc->writeback_cache) {
- err = fuse_writeback_range(inode_out, pos_out, pos_out + len);
- if (err)
- goto out;
- }
+ err = fuse_writeback_range(inode_out, pos_out, pos_out + len - 1);
+ if (err)
+ goto out;
if (is_unstable)
set_bit(FUSE_I_SIZE_UNSTABLE, &fi_out->state);