mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
6be9a78618
The way we decided if an unwritten extent is considered a hole or data is by checking if the page and/or blocks are marked uptodate, that is contain valid data in the page cache. xfs/420 and xfs/421 try to exercise SEEK_HOLE / SEEK_DATA in the presence of cowextsize preallocations over holes in the data fork. The current XFS code never actually uses those for buffer writes, but a pending patch changes that. For SEEK_HOLE / SEEK_DATA to work properly in that case we also need to look at the COW fork in their implementations and thus have to rely on the unwritten extent page cache probing. But the tests for it ensure we do have valid data in the pagecache by calling md5sum on the test files, and thus reading their contents (including the zero-filled holes) in, and thus making them all valid data. Fix that by dropping the page cache content after the md5sum calls. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
153 lines
5.1 KiB
Bash
Executable File
153 lines
5.1 KiB
Bash
Executable File
#! /bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright (c) 2017, Oracle and/or its affiliates. All Rights Reserved.
|
|
#
|
|
# FS QA Test No. 420
|
|
#
|
|
# Test SEEK_HOLE/SEEK_DATA into a region that is marked CoW'd for
|
|
# speculative preallocation in the CoW fork and isn't backed by
|
|
# data fork extents.
|
|
#
|
|
# - Set a huge cowextsize hint.
|
|
# - Create a file "DD " (two data blocks, six hole blocks)
|
|
# - Reflink copy this file to a second file.
|
|
# - Write to the first block of the second file to create a single
|
|
# large CoW reservation covering the whole file.
|
|
# - Write to block 3, which should be a hole in the data fork.
|
|
# - Display the SEEK_HOLE/SEEK_DATA info for the second file to confirm
|
|
# that we see the data in blocks 0-1, the hole at block 2, the data
|
|
# at block 3, and the hole for the rest of the file.
|
|
#
|
|
# Basically we want to create a file with the following data/CoW forks:
|
|
#
|
|
# data: DD------
|
|
# cow: dddddddd
|
|
# ^--^---------- these blocks are dirty
|
|
#
|
|
# And then check that SEEK_HOLE and SEEK_DATA actually find that second
|
|
# dirty block even though we've never had a data fork extent mapping the
|
|
# second dirty block. We need the huge cowextsize so that the hole
|
|
# area receives preallocation in the CoW fork.
|
|
#
|
|
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.*
|
|
}
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
. ./common/reflink
|
|
|
|
# real QA test starts here
|
|
_supported_os Linux
|
|
_supported_fs xfs
|
|
_require_scratch_reflink
|
|
_require_cp_reflink
|
|
_require_xfs_io_command "cowextsize"
|
|
_require_xfs_io_command "fpunch"
|
|
|
|
rm -f $seqres.full
|
|
|
|
echo "Format and mount"
|
|
_scratch_mkfs > $seqres.full 2>&1
|
|
_scratch_mount >> $seqres.full 2>&1
|
|
|
|
testdir=$SCRATCH_MNT/test-$seq
|
|
mkdir $testdir
|
|
|
|
blksz=65536
|
|
nr=8
|
|
filesize=$((blksz * nr))
|
|
|
|
echo "Create the original files"
|
|
$XFS_IO_PROG -c "cowextsize" $testdir >> $seqres.full
|
|
$XFS_IO_PROG -c "cowextsize $filesize" $testdir >> $seqres.full
|
|
$XFS_IO_PROG -c "cowextsize" $testdir >> $seqres.full
|
|
$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((blksz * 2))" -c "truncate $filesize" -c "fpunch $((blksz * 2)) $((blksz * (nr - 2) ))" $testdir/file1 >> $seqres.full
|
|
_cp_reflink $testdir/file1 $testdir/file2 >> $seqres.full
|
|
$XFS_IO_PROG -f -c "pwrite -S 0 0 $filesize" -c "pwrite -S 0x61 0 $((blksz * 2))" $testdir/file3 >> $seqres.full
|
|
_scratch_cycle_mount
|
|
|
|
echo "Compare files"
|
|
md5sum $testdir/file1 | _filter_scratch
|
|
md5sum $testdir/file2 | _filter_scratch
|
|
md5sum $testdir/file3 | _filter_scratch
|
|
# drop caches to make sure the page cache for the unwritten extents is clean
|
|
echo 1 > /proc/sys/vm/drop_caches
|
|
|
|
echo "CoW the shared part then write into the empty part" | tee -a $seqres.full
|
|
$XFS_IO_PROG -c "cowextsize" $testdir/file1 >> $seqres.full
|
|
$XFS_IO_PROG -c "cowextsize" $testdir/file2 >> $seqres.full
|
|
$XFS_IO_PROG -c "pwrite -S 0x63 0 $blksz" $testdir/file2 >> $seqres.full
|
|
$XFS_IO_PROG -c "pwrite -S 0x63 $((blksz * 3)) $blksz" $testdir/file2 >> $seqres.full
|
|
|
|
$XFS_IO_PROG -c "pwrite -S 0x63 0 $blksz" $testdir/file3 >> $seqres.full
|
|
$XFS_IO_PROG -c "pwrite -S 0x63 $((blksz * 3)) $blksz" $testdir/file3 >> $seqres.full
|
|
|
|
$XFS_IO_PROG -c "bmap -ev" -c "bmap -cv" $testdir/file1 >> $seqres.full 2>&1
|
|
$XFS_IO_PROG -c "bmap -ev" -c "bmap -cv" $testdir/file2 >> $seqres.full 2>&1
|
|
$XFS_IO_PROG -c "bmap -ev" -c "bmap -cv" $testdir/file3 >> $seqres.full 2>&1
|
|
|
|
echo "Seek holes and data in file1"
|
|
$XFS_IO_PROG -c "seek -a -r 0" $testdir/file1
|
|
echo "Seek holes and data in file2"
|
|
$XFS_IO_PROG -c "seek -a -r 0" $testdir/file2
|
|
|
|
echo "Compare files"
|
|
md5sum $testdir/file1 | _filter_scratch
|
|
md5sum $testdir/file2 | _filter_scratch
|
|
md5sum $testdir/file3 | _filter_scratch
|
|
# drop caches to make sure the page cache for the unwritten extents is clean
|
|
echo 1 > /proc/sys/vm/drop_caches
|
|
|
|
echo "sync filesystem" | tee -a $seqres.full
|
|
sync
|
|
|
|
$XFS_IO_PROG -c "bmap -ev" -c "bmap -cv" $testdir/file1 >> $seqres.full 2>&1
|
|
$XFS_IO_PROG -c "bmap -ev" -c "bmap -cv" $testdir/file2 >> $seqres.full 2>&1
|
|
$XFS_IO_PROG -c "bmap -ev" -c "bmap -cv" $testdir/file3 >> $seqres.full 2>&1
|
|
|
|
echo "Seek holes and data in file1"
|
|
$XFS_IO_PROG -c "seek -a -r 0" $testdir/file1
|
|
echo "Seek holes and data in file2"
|
|
$XFS_IO_PROG -c "seek -a -r 0" $testdir/file2
|
|
|
|
echo "Compare files"
|
|
md5sum $testdir/file1 | _filter_scratch
|
|
md5sum $testdir/file2 | _filter_scratch
|
|
md5sum $testdir/file3 | _filter_scratch
|
|
# drop caches to make sure the page cache for the unwritten extents is clean
|
|
echo 1 > /proc/sys/vm/drop_caches
|
|
|
|
echo "Remount" | tee -a $seqres.full
|
|
_scratch_cycle_mount
|
|
|
|
$XFS_IO_PROG -c "bmap -ev" -c "bmap -cv" $testdir/file1 >> $seqres.full 2>&1
|
|
$XFS_IO_PROG -c "bmap -ev" -c "bmap -cv" $testdir/file2 >> $seqres.full 2>&1
|
|
$XFS_IO_PROG -c "bmap -ev" -c "bmap -cv" $testdir/file3 >> $seqres.full 2>&1
|
|
|
|
echo "Seek holes and data in file1"
|
|
$XFS_IO_PROG -c "seek -a -r 0" $testdir/file1
|
|
echo "Seek holes and data in file2"
|
|
$XFS_IO_PROG -c "seek -a -r 0" $testdir/file2
|
|
|
|
echo "Compare files"
|
|
md5sum $testdir/file1 | _filter_scratch
|
|
md5sum $testdir/file2 | _filter_scratch
|
|
md5sum $testdir/file3 | _filter_scratch
|
|
|
|
# success, all done
|
|
status=0
|
|
exit
|