mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
d123585ea0
This test requires us to fragment free space, and in part accomplishes this by fallocating 400M of a 512M filesystem, then fallocating another 70M, and then using dd to eat remaining space. However, it's risky to assume the 400M figure because new features such as reflink and rmap have per-ag metadata reservations which add to overhead. Therefore, reserve the 70M fragment file first, then try to fallocate 95% of the remaining free space. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Tested-by: Yang Xu<xuyang2018.jy@cn.fujitsu.com> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
106 lines
2.8 KiB
Bash
Executable File
106 lines
2.8 KiB
Bash
Executable File
#! /bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# Copyright (c) 2017 Red Hat, Inc. All Rights Reserved.
|
|
#
|
|
# FS QA Test 294
|
|
#
|
|
# Test readdir on fragmented multi-fsb dir blocks
|
|
#
|
|
# If the readahead map ends with a partial multi-fsb dir
|
|
# block, the loop at the end of xfs_dir2_leaf_readbuf() may
|
|
# walk off the end of the mapping array, read garbage,
|
|
# corrupt the loop control counter, and never return.
|
|
#
|
|
# Failure is a hang; KASAN should also catch this.
|
|
#
|
|
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 -f $tmp.*
|
|
}
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
|
|
# remove previous $seqres.full before test
|
|
rm -f $seqres.full
|
|
|
|
# real QA test starts here
|
|
|
|
# Modify as appropriate.
|
|
_supported_fs xfs
|
|
_supported_os Linux
|
|
_require_scratch
|
|
_require_test_program "punch-alternating"
|
|
_require_xfs_io_command "falloc"
|
|
_require_xfs_io_command "fpunch"
|
|
|
|
# We want to mkfs with a very specific geometry
|
|
MKFS_OPTIONS=""
|
|
_scratch_mkfs "-d size=512m -n size=8192 -i size=1024" >> $seqres.full 2>&1 \
|
|
|| _fail "mkfs failed"
|
|
_scratch_mount
|
|
|
|
# Make a ton of mostly-empty inode clusters so we can always
|
|
# make more inodes
|
|
mkdir $SCRATCH_MNT/tmp
|
|
for I in `seq 1 10000`; do touch $SCRATCH_MNT/tmp/$I; done
|
|
|
|
# These mostly-empty clusters will live here:
|
|
mkdir $SCRATCH_MNT/clusters
|
|
for I in `seq 1 32 10000`; do
|
|
mv $SCRATCH_MNT/tmp/$I $SCRATCH_MNT/clusters;
|
|
done
|
|
rm -rf $SCRATCH_MNT/tmp
|
|
|
|
# Make our test dir with a couple blocks, should be contiguous
|
|
mkdir $SCRATCH_MNT/testdir
|
|
# roughly 20 chars per file
|
|
for I in `seq 1 100`; do
|
|
touch $SCRATCH_MNT/testdir/12345678901234567890$I;
|
|
done
|
|
|
|
# File to fragment:
|
|
$XFS_IO_PROG -f -c "falloc 0 70m" $SCRATCH_MNT/fragfile ||
|
|
_fail "Could not allocate space"
|
|
|
|
# Now completely fragment freespace.
|
|
# Consume most of it:
|
|
space=$(stat -f -c '%f * %S * 95 / 100' $SCRATCH_MNT | $BC_PROG)
|
|
$XFS_IO_PROG -f -c "falloc 0 $space" $SCRATCH_MNT/fillfile ||
|
|
_fail "Could not allocate space"
|
|
|
|
df -h $SCRATCH_MNT >> $seqres.full 2>&1
|
|
|
|
# Fill remaining space; let this run to failure
|
|
dd if=/dev/zero of=$SCRATCH_MNT/spacefile1 oflag=direct >> $seqres.full 2>&1
|
|
# Fragment our all-consuming file
|
|
./src/punch-alternating $SCRATCH_MNT/fragfile >> $seqres.full 2>&1
|
|
|
|
# Punching might have freed up large-ish swaths of metadata
|
|
# Consume hopefully any remaining contiguous freespace
|
|
# (and then some for good measure)
|
|
dd conv=fsync if=/dev/zero of=$SCRATCH_MNT/spacefile2 bs=1M count=64 >> $seqres.full 2>&1
|
|
|
|
# Now populate the directory so that it must allocate these
|
|
# fragmented blocks
|
|
for I in `seq 1 1400`; do
|
|
touch $SCRATCH_MNT/testdir/12345678901234567890$I;
|
|
done
|
|
|
|
# Now traverse that ugly thing!
|
|
find $SCRATCH_MNT/testdir | sort | _filter_scratch | md5sum
|
|
|
|
status=0
|
|
exit
|