Skip to content

Commit

Permalink
fuse: fix copy_file_range cache issues
Browse files Browse the repository at this point in the history
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: 88bc7d5 ("fuse: add support for copy_file_range()")
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
  • Loading branch information
Miklos Szeredi committed May 20, 2020
1 parent 6b2fb79 commit 2c4656d
Showing 1 changed file with 8 additions and 12 deletions.
20 changes: 8 additions & 12 deletions fs/fuse/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -3325,25 +3325,21 @@ 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);

err = file_modified(file_out);
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);
Expand Down

0 comments on commit 2c4656d

Please sign in to comment.