diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2020-05-20 12:39:35 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-06-24 18:50:30 +0300 |
commit | c9ddb8dd12e1e8d1ef5895175d54b50279317ce8 (patch) | |
tree | 778b053c8ec9c007330339ec38b1b04cf4b8bf60 | |
parent | ad7f78b7ce3975fa6713b392dbcbfbf3cc2e3fe2 (diff) | |
download | linux-c9ddb8dd12e1e8d1ef5895175d54b50279317ce8.tar.xz |
fuse: fix copy_file_range cache issues
[ Upstream commit 2c4656dfd994538176db30ce09c02cc0dfc361ae ]
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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r-- | fs/fuse/file.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 713d55a61890..e730e3d8ad99 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -3280,13 +3280,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); @@ -3294,11 +3292,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); |