Subject: bug#6131: [PATCH]: fiemap support for efficient sparse file copy

From: Jim Meyering <[email-masked]>
Date: Tue, 28 Sep 2010 10:23:16 +0200

jeff.liu wrote:
> Sorry for the delay.
>
> This is the new patch to isolate the stuff regarding to extents reading to a new module. and teach
> cp(1) to make use of it.

Jeff,

I applied your patch to my rebased fiemap-copy branch.
My first step was to run the usual

  ./bootstrap && ./configure && make && make check

"make check" failed on due to a double free in your new code:
(x86_64, Fedora 13, ext4 working directory)

To get details, I made this temporary modification:

diff --git a/tests/cp/sparse-fiemap b/tests/cp/sparse-fiemap
index b6b1103..a8643bc 100755
--- a/tests/cp/sparse-fiemap
+++ b/tests/cp/sparse-fiemap
@@ -82,7 +82,7 @@ for i in $(seq 1 2 21); do
           -e 'for (1..'$j') { sysseek (*F, $n, 1)' \
           -e '&& syswrite (*F, chr($_)x$n) or die "$!"}' > j1 || fail=1
     # sync
-    cp --sparse=always j1 j2 || fail=1
+    valgrind cp --sparse=always j1 j2 || fail=1
     # sync
     # Technically we may need the 'sync' uses above, but
     # uncommenting them makes this test take much longer.

Then I reran make check.
That showed that 4 invocations of cp failed, each with errors
like the ones below.  I'll look at the actual code once you've
fixed these bugs:

==13203== Command: cp --sparse=always j1 j2
==13203==
==13203== Invalid read of size 1
==13203==    at 0x404960: extent_copy (copy.c:284)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==  Address 0x4c35b8d is 29 bytes inside a block of size 40 free'd
==13203==    at 0x4A04D72: free (vg_replace_malloc.c:325)
==13203==    by 0x4096A9: close_extent_scan (extent-scan.c:135)
==13203==    by 0x40495B: extent_copy (copy.c:283)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==
==13203== Invalid read of size 8
==13203==    at 0x409664: close_extent_scan (extent-scan.c:129)
==13203==    by 0x40497D: extent_copy (copy.c:287)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==  Address 0x4c35b90 is 32 bytes inside a block of size 40 free'd
==13203==    at 0x4A04D72: free (vg_replace_malloc.c:325)
==13203==    by 0x4096A9: close_extent_scan (extent-scan.c:135)
==13203==    by 0x40495B: extent_copy (copy.c:283)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==
==13203== Invalid read of size 1
==13203==    at 0x409671: close_extent_scan (extent-scan.c:129)
==13203==    by 0x40497D: extent_copy (copy.c:287)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==  Address 0x4c35b8d is 29 bytes inside a block of size 40 free'd
==13203==    at 0x4A04D72: free (vg_replace_malloc.c:325)
==13203==    by 0x4096A9: close_extent_scan (extent-scan.c:135)
==13203==    by 0x40495B: extent_copy (copy.c:283)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==
==13203== Invalid read of size 8
==13203==    at 0x409692: close_extent_scan (extent-scan.c:134)
==13203==    by 0x40497D: extent_copy (copy.c:287)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==  Address 0x4c35b78 is 8 bytes inside a block of size 40 free'd
==13203==    at 0x4A04D72: free (vg_replace_malloc.c:325)
==13203==    by 0x4096A9: close_extent_scan (extent-scan.c:135)
==13203==    by 0x40495B: extent_copy (copy.c:283)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==
==13203== Invalid free() / delete / delete[]
==13203==    at 0x4A04D72: free (vg_replace_malloc.c:325)
==13203==    by 0x40969D: close_extent_scan (extent-scan.c:134)
==13203==    by 0x40497D: extent_copy (copy.c:287)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==  Address 0x4c35be0 is 0 bytes inside a block of size 3 free'd
==13203==    at 0x4A04D72: free (vg_replace_malloc.c:325)
==13203==    by 0x40969D: close_extent_scan (extent-scan.c:134)
==13203==    by 0x40495B: extent_copy (copy.c:283)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==
==13203== Invalid free() / delete / delete[]
==13203==    at 0x4A04D72: free (vg_replace_malloc.c:325)
==13203==    by 0x4096A9: close_extent_scan (extent-scan.c:135)
==13203==    by 0x40497D: extent_copy (copy.c:287)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)
==13203==  Address 0x4c35b70 is 0 bytes inside a block of size 40 free'd
==13203==    at 0x4A04D72: free (vg_replace_malloc.c:325)
==13203==    by 0x4096A9: close_extent_scan (extent-scan.c:135)
==13203==    by 0x40495B: extent_copy (copy.c:283)
==13203==    by 0x405A92: copy_reg (copy.c:848)
==13203==    by 0x4084F2: copy_internal (copy.c:2189)
==13203==    by 0x40901E: copy (copy.c:2475)
==13203==    by 0x403AC9: do_copy (cp.c:757)
==13203==    by 0x4041F4: main (cp.c:1162)