2 # Test cp --sparse=always through SEEK_DATA copy
4 # Copyright (C) 2010-2024 Free Software Foundation, Inc.
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <https://www.gnu.org/licenses/>.
19 .
"${srcdir=.}/tests/init.sh"; path_prepend_ .
/src
23 # The test was seen to fail on ext3 so exclude that type
24 # (or any file system where the type can't be determined)
26 if seek_data_capable_ sparse_chk
&& ! df
-t ext3 .
>/dev
/null
; then
27 : # Current partition has working extents. Good!
29 skip_
"insufficient SEEK_DATA support"
31 # It's not; we need to create one, hence we need root access.
35 cleanup_
() { cd /; umount
"$cwd/mnt"; }
38 # Create an ext4 loopback file system
39 dd if=/dev
/zero of
=blob bs
=32k count
=1000 || skip
=1
41 mkfs
-t ext4
-F blob ||
42 skip_
"failed to create ext4 file system"
43 mount
-oloop blob mnt || skip
=1
45 echo test > f || skip
=1
49 skip_
"insufficient mount/ext4 support"
52 # =================================================
53 # The data below was set up to ensure that the original FIEMAP-copying code
54 # was exercised enough to provoke at least two iterations of the do...while loop
55 # in which it calls ioctl (fd, FS_IOC_FIEMAP,...
56 # This also verifies that non-trivial extents are preserved.
58 # Extract logical block number and length pairs from filefrag -v output.
59 # The initial sed is to remove the "eof" from the normally-empty "flags" field.
60 # Similarly, remove flags values like "unknown,delalloc,eof".
61 # That is required when that final extent has no number in the "expected" field.
64 sed 's/ [a-z,][a-z,]*$//' $@ \
65 |
$AWK '/^ *[0-9]/ {printf "%d %d ", $2, (NF>=6 ? $6 : (NF<5 ? $NF : $5)) }
69 for i
in $
(seq 1 2 21); do
70 for j
in 1 2 31 100; do
71 $PERL -e '$n = '$i' * 1024; *F = *STDOUT;' \
72 -e 'for (1..'$j') { sysseek (*F, $n, 1)' \
73 -e '&& syswrite (*F, chr($_)x$n) or die "$!"}' > j1 || fail
=1
75 # Note there is an implicit sync performed by cp on Linux kernels
76 # before 2.6.39 to work around bugs in EXT4 and BTRFS.
77 # (this was removed in the release after coreutils-8.32).
78 # Note also the -s parameter to the filefrag commands below
79 # for the same reasons.
80 cp --reflink=never
--sparse=always j1 j2 || fail
=1
82 cmp j1 j2 || fail_
"data loss i=$i j=$j"
83 if ! filefrag
-vs j1 |
grep -F extent
>/dev
/null
; then
84 test $skip != 1 && warn_
'skipping part; you lack filefrag'
87 # Here is sample filefrag output:
88 # $ perl -e 'BEGIN{$n=16*1024; *F=*STDOUT}' \
89 # -e 'for (1..5) { sysseek(*F,$n,1)' \
90 # -e '&& syswrite *F,"."x$n or die "$!"}' > j
92 # File system type is: ef53
93 # File size of j is 163840 (40 blocks, blocksize 4096)
94 # ext logical physical expected length flags
96 # 1 12 6258892 6258887 4
97 # 2 20 6258900 6258895 4
98 # 3 28 6258908 6258903 4
99 # 4 36 6258916 6258911 4 eof
102 # exclude the physical block numbers; they always differ
103 filefrag
-v j1
> ff1 || framework_failure_
104 filefrag
-vs j2
> ff2 || framework_failure_
105 { f ff1
; f ff2
; } |
$PERL $abs_srcdir/tests
/filefrag-extent-compare \
107 warn_ ignoring filefrag-reported extent map differences
108 # Show the differing extent maps.
112 test $fail = 1 && break 2