summaryrefslogtreecommitdiff
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2018-11-27 08:23:56 +0300
committerJoel Stanley <joel@jms.id.au>2018-11-27 08:24:09 +0300
commitd608acfd4ac3fe17f3081bee8fcd4dcd896c2ffa (patch)
treeade4450a72a2e358a1d2e5cde321de0097fb291c /fs/btrfs/ioctl.c
parent62ccc3924eff37012bd0c227d8b7dc71188fc358 (diff)
parenta9da8725b7a744be3ff0ff44cab2547e4d1e6675 (diff)
downloadlinux-dev-4.18.tar.xz
Merge tag 'v4.18.20' into dev-4.18dev-4.18
This is the 4.18.20 stable release Signed-off-by: Joel Stanley <joel@jms.id.au>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index c972920701a3..ec021bd947ba 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3499,6 +3499,8 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
const u64 sz = BTRFS_I(src)->root->fs_info->sectorsize;
len = round_down(i_size_read(src), sz) - loff;
+ if (len == 0)
+ return 0;
olen = len;
}
}
@@ -4291,9 +4293,17 @@ static noinline int btrfs_clone_files(struct file *file, struct file *file_src,
goto out_unlock;
if (len == 0)
olen = len = src->i_size - off;
- /* if we extend to eof, continue to block boundary */
- if (off + len == src->i_size)
+ /*
+ * If we extend to eof, continue to block boundary if and only if the
+ * destination end offset matches the destination file's size, otherwise
+ * we would be corrupting data by placing the eof block into the middle
+ * of a file.
+ */
+ if (off + len == src->i_size) {
+ if (!IS_ALIGNED(len, bs) && destoff + len < inode->i_size)
+ goto out_unlock;
len = ALIGN(src->i_size, bs) - off;
+ }
if (len == 0) {
ret = 0;