xfs: test fragmented multi-fsb readdir

Regression test for kernel commit:
023cc840 xfs: handle array index overrun in xfs_dir2_leaf_readbuf()

See commit for detailed problem description.

tl;dr: readahead on weirdly fragmented multi-block directories
was broken.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Eryu Guan <eguan@redhat.com>
Signed-off-by: Eryu Guan <eguan@redhat.com>
This commit is contained in:
Eric Sandeen
2017-05-03 19:21:19 -05:00
committed by Eryu Guan
parent cf0e25209d
commit 9343320e67
3 changed files with 121 additions and 0 deletions
Executable
+118
View File
@@ -0,0 +1,118 @@
#! /bin/bash
# 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.
#
#-----------------------------------------------------------------------
# Copyright (c) 2017 Red Hat, Inc. All Rights Reserved.
# Author: Eric Sandeen <sandeen@redhat.com>
#
# 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 -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"
# 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
# Now completely fragment freespace.
# Consume most of it:
$XFS_IO_PROG -f -c "falloc 0 400m" $SCRATCH_MNT/fillfile ||
_fail "Could not allocate space"
# File to fragment:
$XFS_IO_PROG -f -c "falloc 0 70m" $SCRATCH_MNT/fragfile ||
_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
+2
View File
@@ -0,0 +1,2 @@
QA output created by 294
23accd029fad51ec02e4ec1f24799878 -
+1
View File
@@ -291,6 +291,7 @@
291 auto repair 291 auto repair
292 auto mkfs quick 292 auto mkfs quick
293 auto quick 293 auto quick
294 auto dir metadata dangerous
295 auto logprint quick 295 auto logprint quick
296 dump auto quick 296 dump auto quick
297 auto freeze 297 auto freeze