aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2018-05-29 18:55:57 +0200
committerEryu Guan <guaneryu@gmail.com>2018-06-03 22:16:15 +0800
commit678c3f477d0d372046858eb0ec6cf9e1231d1195 (patch)
tree454a70d851ff85f8f5fc7e743a8b21fd175ae4a5
parent828f12b965d9bdaa2871b72ae86e443974b0a9b0 (diff)
downloadxfstests-dev-678c3f477d0d372046858eb0ec6cf9e1231d1195.tar.gz
ext4: Test for s_inodes_count overflow during fs resize
Test for overflow of s_inodes_count during filesystem resizing. Signed-off-by: Jan Kara <jack@suse.cz> Reviewed-by: Eryu Guan <guaneryu@gmail.com> Signed-off-by: Eryu Guan <guaneryu@gmail.com>
-rw-r--r--common/config1
-rwxr-xr-xtests/ext4/033123
-rw-r--r--tests/ext4/033.out6
-rw-r--r--tests/ext4/group1
4 files changed, 131 insertions, 0 deletions
diff --git a/common/config b/common/config
index 4807e6cd78..f53516b1b0 100644
--- a/common/config
+++ b/common/config
@@ -173,6 +173,7 @@ export INDENT_PROG="$(type -P indent)"
export XFS_COPY_PROG="$(type -P xfs_copy)"
export FSTRIM_PROG="$(type -P fstrim)"
export DUMPE2FS_PROG="$(type -P dumpe2fs)"
+export RESIZE2FS_PROG="$(type -P resize2fs)"
export FIO_PROG="$(type -P fio)"
export FILEFRAG_PROG="$(type -P filefrag)"
export E4DEFRAG_PROG="$(type -P e4defrag)"
diff --git a/tests/ext4/033 b/tests/ext4/033
new file mode 100755
index 0000000000..d3e56ab7d1
--- /dev/null
+++ b/tests/ext4/033
@@ -0,0 +1,123 @@
+#! /bin/bash
+# FS QA Test 033
+#
+# Test s_inodes_count overflow for huge filesystems. This bug was fixed
+# by commit "ext4: Forbid overflowing inode count when resizing".
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2018 Jan Kara, SUSE. 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!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ umount $SCRATCH_MNT >/dev/null 2>&1
+ _dmhugedisk_cleanup
+ cd /
+ rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/dmhugedisk
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# real QA test starts here
+_supported_fs ext4
+_supported_os Linux
+_require_scratch_nocheck
+_require_dmhugedisk
+_require_dumpe2fs
+_require_command "$RESIZE2FS_PROG" resize2fs
+
+# Figure out whether device is large enough
+devsize=$(blockdev --getsize64 $SCRATCH_DEV)
+if [ $devsize -lt 4294967296 ]; then
+ _notrun "Too small scratch device, need at least 4G"
+fi
+
+# Figure out block size
+echo "Figure out block size"
+_scratch_mkfs >/dev/null 2>&1
+_scratch_mount >> $seqres.full
+blksz="$(_get_block_size $SCRATCH_MNT)"
+_scratch_unmount
+
+inodes_per_group=$((blksz*8))
+group_blocks=$((blksz*8))
+
+# Number of groups to overflow s_inodes_count
+limit_groups=$(((1<<32)/inodes_per_group))
+
+# Create device huge enough so that overflowing inode count is possible.
+# Set chunk size to 16 sectors. Group descriptors with META_BG feature
+# are rather sparse and that leads to huge overallocation especially with
+# 1k blocksize.
+echo "Format huge device"
+_dmhugedisk_init $(((limit_groups + 16)*group_blocks*(blksz/512))) 16
+
+# Start with small fs
+group_count=$((limit_groups - 16))
+_mkfs_dev -N $((group_count*inodes_per_group)) -b $blksz \
+ $DMHUGEDISK_DEV $((group_count*group_blocks))
+
+_mount $DMHUGEDISK_DEV $SCRATCH_MNT
+
+echo "Initial fs dump" >> $seqres.full
+$DUMPE2FS_PROG -h $DMHUGEDISK_DEV >> $seqres.full 2>&1
+
+# This should fail, s_inodes_count would just overflow!
+echo "Resizing to inode limit + 1..."
+$RESIZE2FS_PROG $DMHUGEDISK_DEV $((limit_groups*group_blocks)) >> $seqres.full 2>&1
+if [ $? -eq 0 ]; then
+ echo "Resizing succeeded but it should fail!"
+ exit
+fi
+
+# This should succeed, we are maxing out inodes
+echo "Resizing to max group count..."
+$RESIZE2FS_PROG $DMHUGEDISK_DEV $(((limit_groups-1)*group_blocks)) >> $seqres.full 2>&1
+if [ $? -ne 0 ]; then
+ echo "Resizing failed!"
+ exit
+fi
+
+echo "Fs dump after resize" >> $seqres.full
+$DUMPE2FS_PROG -h $DMHUGEDISK_DEV >> $seqres.full 2>&1
+
+# This should fail, s_inodes_count would overflow by quite a bit!
+echo "Resizing to device size..."
+$RESIZE2FS_PROG $DMHUGEDISK_DEV >> $seqres.full 2>&1
+if [ $? -eq 0 ]; then
+ echo "Resizing succeeded but it should fail!"
+ exit
+fi
+
+# success, all done
+status=0
+exit
diff --git a/tests/ext4/033.out b/tests/ext4/033.out
new file mode 100644
index 0000000000..24c251cbb2
--- /dev/null
+++ b/tests/ext4/033.out
@@ -0,0 +1,6 @@
+QA output created by 033
+Figure out block size
+Format huge device
+Resizing to inode limit + 1...
+Resizing to max group count...
+Resizing to device size...
diff --git a/tests/ext4/group b/tests/ext4/group
index 5bd15f82b3..b850f568e6 100644
--- a/tests/ext4/group
+++ b/tests/ext4/group
@@ -35,6 +35,7 @@
030 auto quick dax
031 auto quick dax
032 auto quick ioctl resize
+033 auto ioctl resize
271 auto rw quick
301 aio auto ioctl rw stress defrag
302 aio auto ioctl rw stress defrag