summaryrefslogtreecommitdiff
path: root/tests/ext4/033
blob: 22041a1711a37009f79453bcdaabeaed9372bc75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2018 Jan Kara, SUSE.  All Rights Reserved.
#
# FS QA Test 033
#
# Test s_inodes_count overflow for huge filesystems. This bug was fixed
# by commit 4f2f76f75143 ("ext4: Forbid overflowing inode count when
# resizing".)
#
. ./common/preamble
_begin_fstest auto ioctl resize

# Override the default cleanup function.
_cleanup()
{
	umount $SCRATCH_MNT >/dev/null 2>&1
	_dmhugedisk_cleanup
	cd /
	rm -f $tmp.*
}

# Import common functions.
. ./common/filter
. ./common/dmhugedisk

# real QA test starts here
_supported_fs ext4
_require_scratch_nocheck
_require_dmhugedisk
_require_dumpe2fs
_require_test_program ext4_resize

EXT4_RESIZE=$here/src/ext4_resize

# 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..."
echo $EXT4_RESIZE $SCRATCH_MNT $((limit_groups*group_blocks)) >> $seqres.full 2>&1
$EXT4_RESIZE $SCRATCH_MNT $((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..."
echo $EXT4_RESIZE $SCRATCH_MNT $(((limit_groups-1)*group_blocks)) >> $seqres.full 2>&1
$EXT4_RESIZE $SCRATCH_MNT $(((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..."
echo $EXT4_RESIZE $SCRATCH_MNT $(((limit_groups + 16)*group_blocks)) >> $seqres.full 2>&1
$EXT4_RESIZE $SCRATCH_MNT $(((limit_groups + 16)*group_blocks)) >> $seqres.full 2>&1
if [ $? -eq 0 ]; then
	echo "Resizing succeeded but it should fail!"
	exit
fi

# success, all done
status=0
exit