mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
86c1b5588c
xfs/042 is really an xfs_fsr test, and it only writes about 60MB of data. however, because it is trying to write lots of data in ENOSPC conditions, it can take a long time as XFS does flushes to maximise space usage at ENOSPC. e.g. on a slow 1p VM: xfs/042 426s ... 425s It takes a long time to write a small amount of data. To avoid this slow flushing problem, create the fragmented files with fallocate() rather than write(), which fails much faster as there is no dirty data to flush before retrying the allocation and failing. THis results in: xfs/042 425s ... 11s A massive reduction in runtime, such that we can consider putting xfs/042 into the quick group.... Signed-off-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
151 lines
4.6 KiB
Bash
Executable File
151 lines
4.6 KiB
Bash
Executable File
#! /bin/bash
|
|
# FS QA Test No. 042
|
|
#
|
|
# xfs_fsr QA tests
|
|
# create a large fragmented file and check that xfs_fsr doesn't corrupt
|
|
# it or the other contents of the filesystem
|
|
#
|
|
#-----------------------------------------------------------------------
|
|
# Copyright (c) 2000-2002 Silicon Graphics, 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
|
|
#
|
|
#-----------------------------------------------------------------------
|
|
#
|
|
set +x
|
|
|
|
seq=`basename $0`
|
|
seqres=$RESULT_DIR/$seq
|
|
echo "QA output created by $seq"
|
|
|
|
here=`pwd`
|
|
tmp=/tmp/$$
|
|
status=1 # failure is the default!
|
|
|
|
_cleanup()
|
|
{
|
|
umount $SCRATCH_MNT
|
|
rm -f $tmp.*
|
|
}
|
|
trap "_cleanup ; exit \$status" 0 1 2 3 15
|
|
|
|
# get standard environment, filters and checks
|
|
. ./common/rc
|
|
. ./common/filter
|
|
|
|
# real QA test starts here
|
|
_supported_fs xfs
|
|
_supported_os IRIX Linux
|
|
|
|
_require_scratch
|
|
|
|
[ "$XFS_FSR_PROG" = "" ] && _notrun "xfs_fsr not found"
|
|
|
|
# Test performs several operations to produce a badly fragmented file, then
|
|
# create enough contiguous free space for xfs_fsr to defragment the fragmented
|
|
# file:
|
|
#
|
|
# - create fs with 3 minimum sized (16Mb) allocation groups
|
|
# - create 16x1MB contiguous files which will become large free space extents
|
|
# when deleted
|
|
# - put a small "space" between each of the 16 contiuguous files to ensure we
|
|
# have separated free space extents
|
|
# - fill the remaining free space with a "fill file"
|
|
# - mount/unmount/fill remaining free space with a pad file
|
|
# - punch alternate single block holes in the the "fill file" to create
|
|
# fragmented free space.
|
|
# - use fill2 to generate a very large fragmented file
|
|
# - delete the 16 large contiguous files created initially
|
|
# - run xfs_fsr on the filesystem
|
|
# - check checksums for remaining files
|
|
|
|
rm -f $seqres.full
|
|
_do_die_on_error=message_only
|
|
|
|
echo -n "Make a 48 megabyte filesystem on SCRATCH_DEV and mount... "
|
|
_scratch_mkfs_xfs -dsize=48m,agcount=3 2>&1 >/dev/null || _fail "mkfs failed"
|
|
_scratch_mount || _fail "mount failed"
|
|
|
|
echo "done"
|
|
|
|
echo -n "Reserve 16 1Mb unfragmented regions... "
|
|
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
|
do
|
|
_do "$XFS_IO_PROG -f -c \"resvsp 0 1m\" $SCRATCH_MNT/hole$i"
|
|
_do "$XFS_IO_PROG -f -c \"resvsp 0 4k\" $SCRATCH_MNT/space$i"
|
|
_do "xfs_bmap -vp $SCRATCH_MNT/hole$i"
|
|
done
|
|
echo "done"
|
|
|
|
# set up filesystem
|
|
echo -n "Fill filesystem with fill file... "
|
|
for i in `seq 0 1 31`; do
|
|
_do "$XFS_IO_PROG -f -c \"falloc ${i}m 1m\" $SCRATCH_MNT/fill"
|
|
done
|
|
_do "xfs_bmap -vp $SCRATCH_MNT/fill"
|
|
echo "done"
|
|
# flush the filesystem - make sure there is no space "lost" to pre-allocation
|
|
_do "umount $SCRATCH_MNT"
|
|
_do "_scratch_mount"
|
|
echo -n "Use up any further available space... "
|
|
_do "$XFS_IO_PROG -f -c \"falloc 0 1m\" $SCRATCH_MNT/pad"
|
|
echo "done"
|
|
|
|
# create fragmented file
|
|
#_do "Delete every second file" "_cull_files"
|
|
echo -n "Punch every second 4k block... "
|
|
for i in `seq 0 8 32768`; do
|
|
# This generates excessive output that significantly slows down the
|
|
# test. It's not necessary for debug, so just bin it.
|
|
$XFS_IO_PROG -f -c "unresvsp ${i}k 4k" $SCRATCH_MNT/fill \
|
|
> /dev/null 2>&1
|
|
done
|
|
_do "xfs_bmap -vp $SCRATCH_MNT/fill"
|
|
_do "sum $SCRATCH_MNT/fill >$tmp.fillsum1"
|
|
echo "done"
|
|
|
|
echo -n "Create one very large file... "
|
|
_do "src/fill2 -d nbytes=16000000,file=$SCRATCH_MNT/fragmented"
|
|
echo "done"
|
|
_do "xfs_bmap -v $SCRATCH_MNT/fragmented"
|
|
_do "sum $SCRATCH_MNT/fragmented >$tmp.sum1"
|
|
_do "Remove other files" "rm -rf $SCRATCH_MNT/{pad,hole*}"
|
|
|
|
# defragment
|
|
_do "Run xfs_fsr on filesystem" "$XFS_FSR_PROG -v $SCRATCH_MNT/fragmented"
|
|
_do "xfs_bmap -v $SCRATCH_MNT/fragmented"
|
|
|
|
echo -n "Check fill file... "
|
|
_do "sum $SCRATCH_MNT/fill >$tmp.fillsum2"
|
|
if ! _do "diff $tmp.fillsum1 $tmp.fillsum2"; then
|
|
echo "fail"
|
|
echo "Fill file is corrupt/missing after fsr. Test failed see $seqres.full"
|
|
status=1; exit
|
|
fi
|
|
echo "done"
|
|
|
|
# check
|
|
echo -n "Check large file... "
|
|
_do "sum $SCRATCH_MNT/fragmented >$tmp.sum2"
|
|
if ! _do "diff $tmp.sum1 $tmp.sum2"; then
|
|
echo "fail"
|
|
echo "File is corrupt/missing after fsr. Test failed see $seqres.full"
|
|
status=1; exit
|
|
fi
|
|
echo "done"
|
|
|
|
# success, all done
|
|
echo "xfs_fsr tests passed."
|
|
status=0 ; exit
|