2 # Test cp reads unwritten extents efficiently
4 # Copyright (C) 2011 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 <http://www.gnu.org/licenses/>.
19 .
"${srcdir=.}/init.sh"; path_prepend_ ..
/src
22 # FIXME: enable any part of this test that is still relevant,
23 # or, if none are relevant (now that cp does not handle unwritten
24 # extents), just remove the test altogether.
25 skip_
'disabled for now'
28 fiemap_capable_ fiemap_chk ||
29 skip_
'this file system lacks FIEMAP support'
32 # TODO: rather than requiring `fallocate`, possible add
33 # this functionality to truncate --alloc
34 fallocate
--help >/dev
/null || skip_
'The fallocate utility is required'
35 fallocate
-l 1 -n falloc.
test ||
36 skip_
'this file system lacks FALLOCATE support'
39 # Require more space than we'll actually use, so that
40 # tests run in parallel do not run out of space.
41 # Otherwise, with inadequate space, simply running the following
42 # fallocate command would induce a temporary disk-full condition,
43 # which would cause failure of unrelated tests run in parallel.
44 require_file_system_bytes_free_
800000000
46 fallocate
-l 600MiB space.
test ||
47 skip_
'this test needs at least 600MiB free space'
49 # Disable this test on old BTRFS (e.g. Fedora 14)
50 # which reports ordinary extents for unwritten ones.
51 filefrag space.
test || skip_
'the `filefrag` utility is missing'
52 filefrag
-v space.
test |
grep -F 'unwritten' > /dev
/null ||
53 skip_
'this file system does not report empty extents as "unwritten"'
57 # Ensure we read a large empty file quickly
58 fallocate
-l 300MiB empty.big || framework_failure_
59 timeout
3 cp --sparse=always empty.big
cp.
test || fail
=1
60 test $
(stat
-c %s empty.big
) = $
(stat
-c %s
cp.
test) || fail
=1
63 # Ensure we handle extents beyond file size correctly.
64 # Note until we support fallocate, we will not maintain
65 # the file allocation. FIXME: amend this test when fallocate is supported.
66 fallocate
-l 10MiB
-n unwritten.withdata || framework_failure_
67 dd count
=10 if=/dev
/urandom conv
=notrunc iflag
=fullblock of
=unwritten.withdata
68 cp unwritten.withdata
cp.
test || fail
=1
69 test $
(stat
-c %s unwritten.withdata
) = $
(stat
-c %s
cp.
test) || fail
=1
70 cmp unwritten.withdata
cp.
test || fail
=1
71 rm unwritten.withdata
cp.
test
73 # The following to generate unaccounted extents followed by a hole, is not
74 # supported by ext4 at least. The ftruncate discards all extents not
75 # accounted for in the size.
76 # fallocate -l 10MiB -n unacc.withholes
77 # dd count=10 if=/dev/urandom conv=notrunc iflag=fullblock of=unacc.withholes
78 # truncate -s20M unacc.withholes
80 # Ensure we handle a hole after empty extents correctly.
81 # Since all extents are accounted for in the size,
82 # we can maintain the allocation independently from
83 # fallocate() support.
84 fallocate
-l 10MiB empty.withholes
85 truncate
-s 20M empty.withholes
86 sectors_per_block
=$
(expr $
(stat
-c %o .
) / 512)
87 cp empty.withholes
cp.
test || fail
=1
88 test $
(stat
-c %s empty.withholes
) = $
(stat
-c %s
cp.
test) || fail
=1
89 # These are usually equal but can vary by an IO block due to alignment
90 alloc_diff
=$
(expr $
(stat
-c %b empty.withholes
) - $
(stat
-c %b
cp.
test))
91 alloc_diff
=$
(echo $alloc_diff |
tr -d -- -) # abs()
92 test $alloc_diff -le $sectors_per_block || fail
=1
93 # Again with SPARSE_ALWAYS
94 cp --sparse=always empty.withholes
cp.
test || fail
=1
95 test $
(stat
-c %s empty.withholes
) = $
(stat
-c %s
cp.
test) || fail
=1
96 # cp.test should take 0 space, but allowing for some systems
97 # that store default extended attributes in data blocks
98 test $
(stat
-c %b
cp.
test) -le $sectors_per_block || fail
=1
99 rm empty.withholes
cp.
test