summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2021-08-31 14:18:08 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-09-15 10:02:35 +0200
commit84378e3a64c18d8b17e8c23efd463525bc0a76fa (patch)
treee30002f4b45a6af54058002e2ec8cd33afa9484a
parente9d6698e54949ebda76973680b185478cbd6b377 (diff)
downloadlinux-stable-84378e3a64c18d8b17e8c23efd463525bc0a76fa.tar.gz
linux-stable-84378e3a64c18d8b17e8c23efd463525bc0a76fa.tar.bz2
linux-stable-84378e3a64c18d8b17e8c23efd463525bc0a76fa.zip
fuse: flush extending writes
commit 59bda8ecee2ffc6a602b7bf2b9e43ca669cdbdcd upstream. Callers of fuse_writeback_range() assume that the file is ready for modification by the server in the supplied byte range after the call returns. If there's a write that extends the file beyond the end of the supplied range, then the file needs to be extended to at least the end of the range, but currently that's not done. There are at least two cases where this can cause problems: - copy_file_range() will return short count if the file is not extended up to end of the source range. - FALLOC_FL_ZERO_RANGE | FALLOC_FL_KEEP_SIZE will not extend the file, hence the region may not be fully allocated. Fix by flushing writes from the start of the range up to the end of the file. This could be optimized if the writes are non-extending, etc, but it's probably not worth the trouble. Fixes: a2bc92362941 ("fuse: fix copy_file_range() in the writeback case") Fixes: 6b1bdb56b17c ("fuse: allow fallocate(FALLOC_FL_ZERO_RANGE)") Cc: <stable@vger.kernel.org> # v5.2 Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/fuse/file.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 5e5efb66c7d7..88be26e5866b 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -2884,7 +2884,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
static int fuse_writeback_range(struct inode *inode, loff_t start, loff_t end)
{
- int err = filemap_write_and_wait_range(inode->i_mapping, start, end);
+ int err = filemap_write_and_wait_range(inode->i_mapping, start, -1);
if (!err)
fuse_sync_writes(inode);