diff options
author | Pádraig Brady <P@draigBrady.com> | 2014-10-02 14:07:42 +0100 |
---|---|---|
committer | Pádraig Brady <P@draigBrady.com> | 2014-10-15 02:19:16 +0100 |
commit | 759b0ac9e7f3fbd0f04090e3142087bf692e47bc (patch) | |
tree | a3d72b4d1a25bec8fb4101e8baecf90ee1a28afa /tests | |
parent | cb4fc9356f9167f1f92d42a7550c5f5f170179c3 (diff) | |
download | coreutils-759b0ac9e7f3fbd0f04090e3142087bf692e47bc.tar.xz |
copy: detect smaller holes than the copy buffer size
Previously cp would not detect runs of NULs that were
smaller than the buffer size used for I/O (currently 128KiB).
* src/copy.c (copy_reg): Use an independent hole_size, set to
st_blksize, to increase the chances of detecting a representable hole,
in a run of NULs read from the input.
(create_hole): A new function refactored from sparse_copy() and
extent_copy() so we have a single place to handle holes.
(sparse_copy): Adjust to loop over the larger input buffer
in chunks of the passed hole size. Also adjust to only call
lseek once per hole, rather than at least once per input buffer.
* tests/cp/sparse.sh: Add test cases for various sparse chunk sizes.
* NEWS: Mention the improvement.
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/cp/sparse.sh | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/tests/cp/sparse.sh b/tests/cp/sparse.sh index d6cc4c4b1..3e4a67caf 100755 --- a/tests/cp/sparse.sh +++ b/tests/cp/sparse.sh @@ -37,4 +37,37 @@ test $(stat --printf %b copy) -le $(stat --printf %b sparse) || fail=1 cp --sparse=always --reflink sparse copy && fail=1 cp --sparse=never --reflink sparse copy && fail=1 + +# Ensure we handle sparse/non-sparse transitions correctly +maxn=128 # how many $hole_size chunks per file +hole_size=$(stat -c %o copy) +dd if=/dev/zero bs=$hole_size count=$maxn of=zeros || framework_failure_ +tr '\0' 'U' < zeros > nonzero || framework_failure_ + +for pattern in 1 0; do + test "$pattern" = 1 && pattern="$(printf '%s\n%s' nonzero zeros)" + test "$pattern" = 0 && pattern="$(printf '%s\n%s' zeros nonzero)" + + for n in 1 2 4 11 32 $maxn; do + parts=$(expr $maxn / $n) + + rm -f sparse.in + + # Generate non sparse file for copying with alternating + # hole/data patterns of size n * $hole_size + for i in $(yes "$pattern" | head -n$parts); do + dd iflag=fullblock if=$i of=sparse.in conv=notrunc oflag=append \ + bs=$hole_size count=$n status=none || framework_failure_ + done + + cp --sparse=always sparse.in sparse.out || fail=1 # non sparse input + cp --sparse=always sparse.out sparse.out2 || fail=1 # sparse input + + cmp sparse.in sparse.out || fail=1 + cmp sparse.in sparse.out2 || fail=1 + + ls -lsh sparse.* + done +done + Exit $fail |