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;
                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)
        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)
 {
        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