summaryrefslogtreecommitdiffstats
path: root/fs/fuse
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@redhat.com>2019-05-28 13:22:50 +0200
committerMiklos Szeredi <mszeredi@redhat.com>2019-05-28 13:22:50 +0200
commit26eb3bae5003585806124c880bba5bef82c80a23 (patch)
tree0aabc5a7dde34e3c1b5aec26dcca8bb3067bfaab /fs/fuse
parentfuse: fix copy_file_range() in the writeback case (diff)
downloadlinux-26eb3bae5003585806124c880bba5bef82c80a23.tar.xz
linux-26eb3bae5003585806124c880bba5bef82c80a23.zip
fuse: extract helper for range writeback
The fuse_writeback_range() helper flushes dirty data to the userspace filesystem. When the function returns, the WRITE requests for the data in the given range have all been completed. This is not equivalent to fsync() on the given range, since the userspace filesystem may not yet have the data on stable storage. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs/fuse')
-rw-r--r--fs/fuse/file.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 4141d94de4ff..b8f9c83835d5 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -3021,6 +3021,16 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
return ret;
}
+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);
+
+ if (!err)
+ fuse_sync_writes(inode);
+
+ return err;
+}
+
static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
loff_t length)
{
@@ -3049,12 +3059,10 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
inode_lock(inode);
if (mode & FALLOC_FL_PUNCH_HOLE) {
loff_t endbyte = offset + length - 1;
- err = filemap_write_and_wait_range(inode->i_mapping,
- offset, endbyte);
+
+ err = fuse_writeback_range(inode, offset, endbyte);
if (err)
goto out;
-
- fuse_sync_writes(inode);
}
}
@@ -3136,10 +3144,7 @@ static ssize_t fuse_copy_file_range(struct file *file_in, loff_t pos_in,
if (fc->writeback_cache) {
inode_lock(inode_in);
- err = filemap_write_and_wait_range(inode_in->i_mapping,
- pos_in, pos_in + len);
- if (!err)
- fuse_sync_writes(inode_in);
+ err = fuse_writeback_range(inode_in, pos_in, pos_in + len);
inode_unlock(inode_in);
if (err)
return err;
@@ -3148,12 +3153,9 @@ static ssize_t fuse_copy_file_range(struct file *file_in, loff_t pos_in,
inode_lock(inode_out);
if (fc->writeback_cache) {
- err = filemap_write_and_wait_range(inode_out->i_mapping,
- pos_out, pos_out + len);
+ err = fuse_writeback_range(inode_out, pos_out, pos_out + len);
if (err)
goto out;
-
- fuse_sync_writes(inode_out);
}
if (is_unstable)