Skip to content

Commit b5f7ab6

Browse files
committed
Merge tag 'fs-dedupe-last-block-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull fs deduplication fix from David Sterba: "This is a fix for deduplication bug: the last block of two files is allowed to deduplicated. This got broken in 5.1 by lifting some generic checks to VFS layer. The affected filesystems are btrfs and xfs. The patches are marked for stable as the bug decreases deduplication effectivity" * tag 'fs-dedupe-last-block-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: Btrfs: make deduplication with range including the last block work fs: allow deduplication of eof block into the end of the destination file
2 parents 81a046b + 831d2fa commit b5f7ab6

File tree

2 files changed

+6
-7
lines changed

2 files changed

+6
-7
lines changed

fs/btrfs/ioctl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3243,14 +3243,15 @@ static void btrfs_double_extent_lock(struct inode *inode1, u64 loff1,
32433243
static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 len,
32443244
struct inode *dst, u64 dst_loff)
32453245
{
3246+
const u64 bs = BTRFS_I(src)->root->fs_info->sb->s_blocksize;
32463247
int ret;
32473248

32483249
/*
32493250
* Lock destination range to serialize with concurrent readpages() and
32503251
* source range to serialize with relocation.
32513252
*/
32523253
btrfs_double_extent_lock(src, loff, dst, dst_loff, len);
3253-
ret = btrfs_clone(src, dst, loff, len, len, dst_loff, 1);
3254+
ret = btrfs_clone(src, dst, loff, len, ALIGN(len, bs), dst_loff, 1);
32543255
btrfs_double_extent_unlock(src, loff, dst, dst_loff, len);
32553256

32563257
return ret;

fs/read_write.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,10 +1777,9 @@ static int remap_verify_area(struct file *file, loff_t pos, loff_t len,
17771777
* else. Assume that the offsets have already been checked for block
17781778
* alignment.
17791779
*
1780-
* For deduplication we always scale down to the previous block because we
1781-
* can't meaningfully compare post-EOF contents.
1782-
*
1783-
* For clone we only link a partial EOF block above the destination file's EOF.
1780+
* For clone we only link a partial EOF block above or at the destination file's
1781+
* EOF. For deduplication we accept a partial EOF block only if it ends at the
1782+
* destination file's EOF (can not link it into the middle of a file).
17841783
*
17851784
* Shorten the request if possible.
17861785
*/
@@ -1796,8 +1795,7 @@ static int generic_remap_check_len(struct inode *inode_in,
17961795
if ((*len & blkmask) == 0)
17971796
return 0;
17981797

1799-
if ((remap_flags & REMAP_FILE_DEDUP) ||
1800-
pos_out + *len < i_size_read(inode_out))
1798+
if (pos_out + *len < i_size_read(inode_out))
18011799
new_len &= ~blkmask;
18021800

18031801
if (new_len == *len)

0 commit comments

Comments
 (0)