ext4/033: test EXT4_IOC_RESIZE_FS by calling the ioctl directly
[xfstests-dev.git] / tests / ext4 / 033
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2018 Jan Kara, SUSE.  All Rights Reserved.
4 #
5 # FS QA Test 033
6 #
7 # Test s_inodes_count overflow for huge filesystems. This bug was fixed
8 # by commit 4f2f76f75143 ("ext4: Forbid overflowing inode count when
9 # resizing".)
10 #
11 . ./common/preamble
12 _begin_fstest auto ioctl resize
13
14 # Override the default cleanup function.
15 _cleanup()
16 {
17         umount $SCRATCH_MNT >/dev/null 2>&1
18         _dmhugedisk_cleanup
19         cd /
20         rm -f $tmp.*
21 }
22
23 # Import common functions.
24 . ./common/filter
25 . ./common/dmhugedisk
26
27 # real QA test starts here
28 _supported_fs ext4
29 _require_scratch_nocheck
30 _require_dmhugedisk
31 _require_dumpe2fs
32 _require_test_program ext4_resize
33
34 EXT4_RESIZE=$here/src/ext4_resize
35
36 # Figure out whether device is large enough
37 devsize=$(blockdev --getsize64 $SCRATCH_DEV)
38 if [ $devsize -lt 4294967296 ]; then
39         _notrun "Too small scratch device, need at least 4G"
40 fi
41
42 # Figure out block size
43 echo "Figure out block size"
44 _scratch_mkfs >/dev/null 2>&1
45 _scratch_mount >> $seqres.full
46 blksz="$(_get_block_size $SCRATCH_MNT)"
47 _scratch_unmount
48
49 inodes_per_group=$((blksz*8))
50 group_blocks=$((blksz*8))
51
52 # Number of groups to overflow s_inodes_count
53 limit_groups=$(((1<<32)/inodes_per_group))
54
55 # Create device huge enough so that overflowing inode count is possible.
56 # Set chunk size to 16 sectors. Group descriptors with META_BG feature
57 # are rather sparse and that leads to huge overallocation especially with
58 # 1k blocksize.
59 echo "Format huge device"
60 _dmhugedisk_init $(((limit_groups + 16)*group_blocks*(blksz/512))) 16
61
62 # Start with small fs
63 group_count=$((limit_groups - 16))
64 _mkfs_dev -N $((group_count*inodes_per_group)) -b $blksz \
65         $DMHUGEDISK_DEV $((group_count*group_blocks))
66
67 _mount $DMHUGEDISK_DEV $SCRATCH_MNT
68
69 echo "Initial fs dump" >> $seqres.full
70 $DUMPE2FS_PROG -h $DMHUGEDISK_DEV >> $seqres.full 2>&1
71
72 # This should fail, s_inodes_count would just overflow!
73 echo "Resizing to inode limit + 1..."
74 echo $EXT4_RESIZE $SCRATCH_MNT $((limit_groups*group_blocks)) >> $seqres.full 2>&1
75 $EXT4_RESIZE $SCRATCH_MNT $((limit_groups*group_blocks)) >> $seqres.full 2>&1
76 if [ $? -eq 0 ]; then
77         echo "Resizing succeeded but it should fail!"
78         exit
79 fi
80
81 # This should succeed, we are maxing out inodes
82 echo "Resizing to max group count..."
83 echo $EXT4_RESIZE $SCRATCH_MNT $(((limit_groups-1)*group_blocks)) >> $seqres.full 2>&1
84 $EXT4_RESIZE $SCRATCH_MNT $(((limit_groups-1)*group_blocks)) >> $seqres.full 2>&1
85 if [ $? -ne 0 ]; then
86         echo "Resizing failed!"
87         exit
88 fi
89
90 echo "Fs dump after resize" >> $seqres.full
91 $DUMPE2FS_PROG -h $DMHUGEDISK_DEV >> $seqres.full 2>&1
92
93 # This should fail, s_inodes_count would overflow by quite a bit!
94 echo "Resizing to device size..."
95 echo $EXT4_RESIZE $SCRATCH_MNT $(((limit_groups + 16)*group_blocks)) >> $seqres.full 2>&1
96 $EXT4_RESIZE $SCRATCH_MNT $(((limit_groups + 16)*group_blocks)) >> $seqres.full 2>&1
97 if [ $? -eq 0 ]; then
98         echo "Resizing succeeded but it should fail!"
99         exit
100 fi
101
102 # success, all done
103 status=0
104 exit