fuse: fix copy_file_range cache issues
authorMiklos Szeredi <mszeredi@redhat.com>
Wed, 20 May 2020 09:39:35 +0000 (11:39 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Wed, 20 May 2020 09:39:35 +0000 (11:39 +0200)
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>
fs/fuse/file.c

index 15812a8..d365008 100644 (file)
@@ -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);