mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
73beac7013
We were testing when the source file offset starts at EOF or beyond, but not when the destination offset is beyond EOF or when the destination offset is smaller than EOF but destination offset plus dedup length is greater than EOF. This is motivated by a bug in btrfs' extent_same (dedup) ioctl where we allowed the destination offset to start at EOF and beyond (and destination offset + length beyond EOF) for the case where the source and destination files are the same (was not allowed for different files used as source and destination). This also made the file's metadata inconsistent when the dedup operation succeeded, which happened when the source range corresponded to a file hole, prealloc extent or a data extent filled with zeroes. The btrfs issue is fixed by the following patch for the linux kernel: "Btrfs: fix extent_same allowing destination offset beyond i_size" Signed-off-by: Filipe Manana <fdmanana@suse.com> [darrick.wong@oracle.com: fix merge conflicts with latest reflink patchbomb] Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
136 lines
3.8 KiB
Bash
Executable File
136 lines
3.8 KiB
Bash
Executable File
#! /bin/bash
|
|
# FS QA Test No. 158
|
|
#
|
|
# Check that various invalid dedupe scenarios are rejected.
|
|
#
|
|
#-----------------------------------------------------------------------
|
|
# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved.
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License as
|
|
# published by the Free Software Foundation.
|
|
#
|
|
# This program is distributed in the hope that it would be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write the Free Software Foundation,
|
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
#-----------------------------------------------------------------------
|
|
|
|
seq=`basename $0`
|
|
seqres=$RESULT_DIR/$seq
|
|
echo "QA output created by $seq"
|
|
|
|
here=`pwd`
|
|
tmp=/tmp/$$
|
|
status=1 # failure is the default!
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
_cleanup()
|
|
{
|
|
cd /
|
|
rm -rf $tmp.* $testdir1
|
|
}
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
. ./common/attr
|
|
. ./common/reflink
|
|
|
|
# real QA test starts here
|
|
_supported_os Linux
|
|
_require_test_dedupe
|
|
_require_scratch_dedupe
|
|
|
|
rm -f $seqres.full
|
|
|
|
echo "Format and mount"
|
|
_scratch_mkfs > $seqres.full 2>&1
|
|
_scratch_mount >> $seqres.full 2>&1
|
|
|
|
testdir1="$TEST_DIR/test-$seq"
|
|
rm -rf $testdir1
|
|
mkdir $testdir1
|
|
|
|
testdir2=$SCRATCH_MNT/test-$seq
|
|
mkdir $testdir2
|
|
|
|
echo "Create the original files"
|
|
blksz="$(stat -f $testdir1 -c '%S')"
|
|
blks=1000
|
|
margin='7%'
|
|
sz=$((blksz * blks))
|
|
free_blocks0=$(stat -f $testdir1 -c '%f')
|
|
nr=4
|
|
filesize=$((blksz * nr))
|
|
_pwrite_byte 0x61 0 $sz $testdir1/file1 >> $seqres.full
|
|
_pwrite_byte 0x61 0 $sz $testdir1/file2 >> $seqres.full
|
|
_pwrite_byte 0x61 0 $sz $testdir1/file3 >> $seqres.full
|
|
_pwrite_byte 0x61 0 $sz $testdir2/file1 >> $seqres.full
|
|
_pwrite_byte 0x61 0 $sz $testdir2/file2 >> $seqres.full
|
|
mkdir $testdir1/dir1
|
|
seq 1 $((2 * blksz / 250)) | while read f; do
|
|
touch $testdir1/dir1/$f
|
|
done
|
|
mknod $testdir1/dev1 c 1 3
|
|
mkfifo $testdir1/fifo1
|
|
sync
|
|
|
|
_filter_enotty() {
|
|
sed -e 's/Inappropriate ioctl for device/Invalid argument/g'
|
|
}
|
|
|
|
_filter_eperm() {
|
|
sed -e 's/Permission denied/Invalid argument/g'
|
|
}
|
|
|
|
echo "Try cross-device dedupe"
|
|
_dedupe_range $testdir1/file1 0 $testdir2/file1 0 $blksz
|
|
|
|
echo "Try unaligned dedupe"
|
|
_dedupe_range $testdir1/file1 37 $testdir1/file1 59 23
|
|
|
|
echo "Try overlapping dedupe"
|
|
_dedupe_range $testdir1/file1 0 $testdir1/file1 1 $((blksz * 2))
|
|
|
|
echo "Try dedupe from past EOF"
|
|
_dedupe_range $testdir1/file1 $(( (blks + 10) * blksz)) $testdir1/file1 0 $blksz
|
|
|
|
echo "Try dedupe to past EOF, destination offset beyond EOF"
|
|
_dedupe_range $testdir1/file1 0 $testdir1/file1 $(( (blks + 10) * blksz)) \
|
|
$blksz
|
|
|
|
echo "Try dedupe to past EOF, destination offset behind EOF"
|
|
_dedupe_range $testdir1/file1 0 $testdir1/file1 $(( (blks - 1) * blksz)) \
|
|
$((blksz * 2))
|
|
|
|
echo "Try to dedupe a dir"
|
|
_dedupe_range $testdir1/dir1 0 $testdir1/file2 0 $blksz
|
|
|
|
echo "Try to dedupe a device"
|
|
_dedupe_range $testdir1/dev1 0 $testdir1/file2 0 $blksz 2>&1 | _filter_enotty
|
|
|
|
echo "Try to dedupe to a dir"
|
|
_dedupe_range $testdir1/file1 0 $testdir1/dir1 0 $blksz 2>&1 | _filter_test_dir
|
|
|
|
echo "Try to dedupe to a device"
|
|
_dedupe_range $testdir1/file1 0 $testdir1/dev1 0 $blksz 2>&1 | _filter_eperm
|
|
|
|
echo "Try to dedupe to a fifo"
|
|
_dedupe_range $testdir1/file1 0 $testdir1/fifo1 0 $blksz -n 2>&1 | _filter_eperm
|
|
|
|
echo "Try to dedupe an append-only file"
|
|
_dedupe_range $testdir1/file1 0 $testdir1/file3 0 $blksz -a >> $seqres.full
|
|
|
|
echo "Dedupe two files"
|
|
_dedupe_range $testdir1/file1 0 $testdir1/file2 0 $blksz >> $seqres.full
|
|
_dedupe_range $testdir2/file1 0 $testdir2/file2 0 $blksz >> $seqres.full
|
|
|
|
# success, all done
|
|
status=0
|
|
exit
|