Skip to content

Commit

Permalink
Btrfs: dedupe_file_range ioctl: remove 16MiB restriction
Browse files Browse the repository at this point in the history
Currently btrfs_dedupe_file_range silently restricts the dedupe range to
to 16MiB to limit locking and working memory size and is documented in
manual page as implementation specific.

Let's remove that restriction by iterating over the dedup range in 16MiB
steps.  This is backward compatible and will not change anything for
requests smaller then 16MiB.

Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
Timofey Titovets authored and David Sterba committed May 28, 2018
1 parent 3973909 commit b672876
Showing 1 changed file with 18 additions and 6 deletions.
24 changes: 18 additions & 6 deletions fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3128,11 +3128,14 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen,
return ret;
}

#define BTRFS_MAX_DEDUPE_LEN SZ_16M

static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
struct inode *dst, u64 dst_loff)
{
int ret;
bool same_inode = (src == dst);
u64 i, tail_len, chunk_count;

if (olen == 0)
return 0;
Expand All @@ -3149,7 +3152,21 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
goto out_unlock;
}

ret = btrfs_extent_same_range(src, loff, olen, dst, dst_loff);
tail_len = olen % BTRFS_MAX_DEDUPE_LEN;
chunk_count = div_u64(olen, BTRFS_MAX_DEDUPE_LEN);

for (i = 0; i < chunk_count; i++) {
ret = btrfs_extent_same_range(src, loff, BTRFS_MAX_DEDUPE_LEN,
dst, dst_loff);
if (ret)
goto out_unlock;

loff += BTRFS_MAX_DEDUPE_LEN;
dst_loff += BTRFS_MAX_DEDUPE_LEN;
}

if (tail_len > 0)
ret = btrfs_extent_same_range(src, loff, tail_len, dst, dst_loff);

out_unlock:
if (same_inode)
Expand All @@ -3160,8 +3177,6 @@ static int btrfs_extent_same(struct inode *src, u64 loff, u64 olen,
return ret;
}

#define BTRFS_MAX_DEDUPE_LEN SZ_16M

ssize_t btrfs_dedupe_file_range(struct file *src_file, u64 loff, u64 olen,
struct file *dst_file, u64 dst_loff)
{
Expand All @@ -3170,9 +3185,6 @@ ssize_t btrfs_dedupe_file_range(struct file *src_file, u64 loff, u64 olen,
u64 bs = BTRFS_I(src)->root->fs_info->sb->s_blocksize;
ssize_t res;

if (olen > BTRFS_MAX_DEDUPE_LEN)
olen = BTRFS_MAX_DEDUPE_LEN;

if (WARN_ON_ONCE(bs < PAGE_SIZE)) {
/*
* Btrfs does not support blocksize < page_size. As a
Expand Down

0 comments on commit b672876

Please sign in to comment.