mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
ab1d756fe1
There are about 198 tests which requires scratch_dev, but does not check the file system consistency afterwards. Xfstests infrastructure does not do it automatically, so fix it by running _check_scratch_fs() after each test that _require_scratch. Also remove all the _check_scratch_fs() calls that are not actually needed and will be covered by the check script. Signed-off-by: Lukas Czerner <lczerner@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
200 lines
5.4 KiB
Bash
Executable File
200 lines
5.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# FS QA Test No. xfs/014
|
|
#
|
|
# Test the behavior of XFS dynamic speculative preallocation at ENOSPC and
|
|
# EDQUOT conditions. Speculative preallocation allocates post-EOF space to files
|
|
# as they are extended. This test creates conditions where an fs is near a space
|
|
# limit with lingering, relatively significant preallocations and verifies that
|
|
# new writers reclaim said preallocations rather than prematurely fail with
|
|
# ENOSPC/EDQUOT.
|
|
#
|
|
#-----------------------------------------------------------------------
|
|
# Copyright (c) 2014 Red Hat, Inc. 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!
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
. ./common/quota
|
|
|
|
_cleanup()
|
|
{
|
|
cd /
|
|
umount $LOOP_MNT 2>/dev/null
|
|
umount $SCRATCH_MNT 2>/dev/null
|
|
rm -f $tmp.*
|
|
}
|
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
|
|
|
# Create a file using a repeated open, extending write and close pattern. This
|
|
# causes the preallocation to persist after the file is closed. Preallocation
|
|
# will not be reclaimed unless the inode is evicted or we hit an allocation
|
|
# failure.
|
|
_spec_prealloc_file()
|
|
{
|
|
file=$1
|
|
|
|
rm -f $file
|
|
|
|
# a few file extending open-write-close cycles should be enough to
|
|
# trigger the fs to retain preallocation. write 256k in 32k intervals to
|
|
# be sure
|
|
for i in $(seq 0 32768 262144); do
|
|
$XFS_IO_PROG -f -c "pwrite $i 32k" $file >> $seqres.full
|
|
done
|
|
|
|
# write a 4k aligned amount of data to keep the calculations simple
|
|
$XFS_IO_PROG -c "pwrite 0 128m" $file >> $seqres.full
|
|
|
|
size=`stat -c "%s" $file`
|
|
blocks=`stat -c "%b" $file`
|
|
blocksize=`stat -c "%B" $file`
|
|
|
|
prealloc_size=$((blocks * blocksize - size))
|
|
if [ $prealloc_size -eq 0 ]; then
|
|
echo "Warning: No speculative preallocation for $file." \
|
|
"Check use of the allocsize= mount option."
|
|
fi
|
|
|
|
# keep a running total of how much preallocation we've created
|
|
TOTAL_PREALLOC=$((TOTAL_PREALLOC + prealloc_size))
|
|
}
|
|
|
|
_consume_free_space()
|
|
{
|
|
dir=$1
|
|
|
|
# allocate all but 10MB of available space
|
|
freesp=`df -m $dir | awk '/^\// { print $4 - 10 }'`
|
|
$XFS_IO_PROG -f -c "falloc 0 ${freesp}M" $dir/spc
|
|
}
|
|
|
|
# Create several files with preallocation and consume the remaining free space
|
|
# via fallocate to the put the fs at ENOSPC. Create a set of background writers
|
|
# to write into ENOSPC and cause the preallocation to be reclaimed and
|
|
# reallocated to the new writers.
|
|
_test_enospc()
|
|
{
|
|
dir=$1
|
|
|
|
rm -rf $dir/*
|
|
|
|
TOTAL_PREALLOC=0
|
|
for i in $(seq 0 3); do
|
|
_spec_prealloc_file $dir/pre$i
|
|
done
|
|
|
|
_consume_free_space $dir
|
|
|
|
# consume 1/2 of the current preallocation across the set of 4 writers
|
|
write_size=$((TOTAL_PREALLOC / 2 / 4))
|
|
for i in $(seq 0 3); do
|
|
$XFS_IO_PROG -f -c "pwrite 0 $write_size" $dir/file.$i \
|
|
>> $seqres.full &
|
|
done
|
|
|
|
wait
|
|
}
|
|
|
|
# Create preallocations accounted by both user and group quotas. Set the
|
|
# associated quota hard limits to put them at EDQUOT. Verify that a new writer
|
|
# reclaims the preallocated space and proceeds without error.
|
|
_test_edquot()
|
|
{
|
|
dir=$1
|
|
|
|
rm -rf $dir/*
|
|
|
|
TOTAL_PREALLOC=0
|
|
_spec_prealloc_file $dir/user
|
|
chown $qa_user $dir/user
|
|
|
|
_spec_prealloc_file $dir/group
|
|
chgrp $qa_group $dir/group
|
|
|
|
# writing to a file under both quotas means both will be reclaimed on
|
|
# allocation failure
|
|
touch $dir/file
|
|
chown $qa_user $dir/file
|
|
chgrp $qa_group $dir/file
|
|
|
|
# put both quotas at EDQUOT
|
|
blks=`$XFS_QUOTA_PROG -xc "quota -u $qa_user" $dir | \
|
|
tail -n 1 | awk '{ print $2 }'`
|
|
$XFS_QUOTA_PROG -xc "limit -u bhard=${blks}k $qa_user" $dir
|
|
blks=`$XFS_QUOTA_PROG -xc "quota -g $qa_grup" $dir | \
|
|
tail -n 1 | awk '{ print $2 }'`
|
|
$XFS_QUOTA_PROG -xc "limit -g bhard=${blks}k $qa_group" $dir
|
|
|
|
# each quota has a single file worth of preallocation to reclaim. leave
|
|
# some wiggle room and write to 1/3 the total.
|
|
write_size=$((TOTAL_PREALLOC / 3))
|
|
$XFS_IO_PROG -c "pwrite 0 $write_size" $dir/file >> $seqres.full
|
|
}
|
|
|
|
# real QA test starts here
|
|
_supported_fs xfs
|
|
_supported_os Linux
|
|
|
|
_require_scratch
|
|
_require_xfs_io_command "falloc"
|
|
_require_loop
|
|
_require_quota
|
|
_require_user
|
|
_require_group
|
|
|
|
rm -f $seqres.full
|
|
|
|
echo "Silence is golden."
|
|
|
|
_scratch_mkfs_xfs >> $seqres.full 2>&1
|
|
_scratch_mount
|
|
|
|
# make sure the background eofblocks scanner doesn't interfere
|
|
orig_sp_time=`cat /proc/sys/fs/xfs/speculative_prealloc_lifetime`
|
|
echo 9999 > /proc/sys/fs/xfs/speculative_prealloc_lifetime
|
|
|
|
LOOP_FILE=$SCRATCH_MNT/$seq.fs
|
|
LOOP_MNT=$SCRATCH_MNT/$seq.mnt
|
|
|
|
$MKFS_XFS_PROG -d "file=1,name=$LOOP_FILE,size=10g" >> $seqres.full 2>&1
|
|
|
|
mkdir -p $LOOP_MNT
|
|
mount -t xfs -o loop,uquota,gquota $LOOP_FILE $LOOP_MNT || \
|
|
_fail "Failed to mount loop fs."
|
|
|
|
_test_enospc $LOOP_MNT
|
|
_test_edquot $LOOP_MNT
|
|
|
|
umount $LOOP_MNT
|
|
|
|
echo $orig_sp_time > /proc/sys/fs/xfs/speculative_prealloc_lifetime
|
|
|
|
umount $SCRATCH_MNT
|
|
|
|
status=0
|
|
exit
|