1#!/bin/sh 2# Test cp handles extents correctly 3 4# Copyright (C) 2011-2023 Free Software Foundation, Inc. 5 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. 10 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. 15 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/>. 18 19. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src 20print_ver_ cp 21 22require_sparse_support_ 23 24touch sparse_chk || framework_failure_ 25seek_data_capable_ sparse_chk || 26 skip_ 'insufficient SEEK_DATA support' 27 28fallocate --help >/dev/null || skip_ 'The fallocate utility is required' 29touch falloc.test || framework_failure_ 30fallocate -l 1 -o 1 -n falloc.test || 31 skip_ 'this file system lacks FALLOCATE support' 32rm falloc.test 33 34# We don't currently handle unwritten extents specially 35if false; then 36# Require more space than we'll actually use, so that 37# tests run in parallel do not run out of space. 38# Otherwise, with inadequate space, simply running the following 39# fallocate command would induce a temporary file-system-full condition, 40# which would cause failure of unrelated tests run in parallel. 41require_file_system_bytes_free_ 800000000 42 43fallocate -l 1MiB num.test || 44 skip_ "this fallocate doesn't support numbers with IEX suffixes" 45 46fallocate -l 600MiB space.test || 47 skip_ 'this test needs at least 600MiB free space' 48 49# Disable this test on old BTRFS (e.g. Fedora 14) 50# which reports ordinary extents for unwritten ones. 51filefrag space.test || skip_ 'the 'filefrag' utility is missing' 52filefrag -v space.test | grep -F 'unwritten' > /dev/null || 53 skip_ 'this file system does not report empty extents as "unwritten"' 54 55rm space.test 56 57# Ensure we read a large empty file quickly 58fallocate -l 300MiB empty.big || framework_failure_ 59timeout 3 cp --reflink=never --sparse=always empty.big cp.test || fail=1 60test $(stat -c %s empty.big) = $(stat -c %s cp.test) || fail=1 61rm empty.big cp.test 62fi 63 64# Ensure we handle extents beyond file size correctly. 65# Note until we support fallocate, we will not maintain 66# the file allocation. FIXME: amend this test if fallocate is supported. 67# Note currently this only uses SEEK_DATA logic when the allocation (-l) 68# is smaller than the size, thus identifying the file as sparse. 69# Note the '-l 1' case is an effective noop, and just checks 70# a file with a trailing hole is copied correctly. 71for sparse_arg in always auto never; do 72 for alloc in '-l 4194304' '-l 1048576 -o 4194304' '-l 1'; do 73 dd count=10 if=/dev/urandom iflag=fullblock of=unwritten.withdata 74 truncate -s 2MiB unwritten.withdata || framework_failure_ 75 fallocate $alloc -n unwritten.withdata || framework_failure_ 76 cp --reflink=never --sparse=$sparse_arg unwritten.withdata cp.test || fail=1 77 test $(stat -c %s unwritten.withdata) = $(stat -c %s cp.test) || fail=1 78 cmp unwritten.withdata cp.test || fail=1 79 rm unwritten.withdata cp.test || framework_failure_ 80 done 81done 82 83Exit $fail 84