summaryrefslogtreecommitdiffstats
path: root/fs/dax.c
diff options
context:
space:
mode:
authorShiyang Ruan <ruansy.fnst@fujitsu.com>2023-03-22 08:25:58 +0100
committerAndrew Morton <akpm@linux-foundation.org>2023-03-29 00:24:32 +0200
commite900ba10d15041a6236cc75778cc6e06c3590a58 (patch)
treeb36f6c2bc2542ff9b0aed22e99fb51182c3d6cb4 /fs/dax.c
parentfsdax: unshare: zero destination if srcmap is HOLE or UNWRITTEN (diff)
downloadlinux-e900ba10d15041a6236cc75778cc6e06c3590a58.tar.xz
linux-e900ba10d15041a6236cc75778cc6e06c3590a58.zip
fsdax: dedupe should compare the min of two iters' length
In an dedupe comparison iter loop, the length of iomap_iter decreases because it implies the remaining length after each iteration. The dedupe command will fail with -EIO if the range is larger than one page size and not aligned to the page size. Also report warning in dmesg: [ 4338.498374] ------------[ cut here ]------------ [ 4338.498689] WARNING: CPU: 3 PID: 1415645 at fs/iomap/iter.c:16 ... The compare function should use the min length of the current iters, not the total length. Link: https://lkml.kernel.org/r/1679469958-2-1-git-send-email-ruansy.fnst@fujitsu.com Fixes: 0e79e3736d54 ("fsdax: dedupe: iter two files at the same time") Signed-off-by: Shiyang Ruan <ruansy.fnst@fujitsu.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Jan Kara <jack@suse.cz> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'fs/dax.c')
-rw-r--r--fs/dax.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/dax.c b/fs/dax.c
index e48d68902a8c..5d2e9b10030e 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -2027,8 +2027,8 @@ int dax_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
while ((ret = iomap_iter(&src_iter, ops)) > 0 &&
(ret = iomap_iter(&dst_iter, ops)) > 0) {
- compared = dax_range_compare_iter(&src_iter, &dst_iter, len,
- same);
+ compared = dax_range_compare_iter(&src_iter, &dst_iter,
+ min(src_iter.len, dst_iter.len), same);
if (compared < 0)
return ret;
src_iter.processed = dst_iter.processed = compared;