]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.18.11/ext4-fix-online-resize-s-handling-of-a-too-small-final-block-group.patch
fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 4.18.11 / ext4-fix-online-resize-s-handling-of-a-too-small-final-block-group.patch
CommitLineData
9d09275e
GKH
1From f0a459dec5495a3580f8d784555e6f8f3bf7f263 Mon Sep 17 00:00:00 2001
2From: Theodore Ts'o <tytso@mit.edu>
3Date: Mon, 3 Sep 2018 22:19:43 -0400
4Subject: ext4: fix online resize's handling of a too-small final block group
5
6From: Theodore Ts'o <tytso@mit.edu>
7
8commit f0a459dec5495a3580f8d784555e6f8f3bf7f263 upstream.
9
10Avoid growing the file system to an extent so that the last block
11group is too small to hold all of the metadata that must be stored in
12the block group.
13
14This problem can be triggered with the following reproducer:
15
16umount /mnt
17mke2fs -F -m0 -b 4096 -t ext4 -O resize_inode,^has_journal \
18 -E resize=1073741824 /tmp/foo.img 128M
19mount /tmp/foo.img /mnt
20truncate --size 1708M /tmp/foo.img
21resize2fs /dev/loop0 295400
22umount /mnt
23e2fsck -fy /tmp/foo.img
24
25Reported-by: Torsten Hilbrich <torsten.hilbrich@secunet.com>
26Signed-off-by: Theodore Ts'o <tytso@mit.edu>
27Cc: stable@vger.kernel.org
28Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
29
30---
31 fs/ext4/resize.c | 20 ++++++++++++++++++++
32 1 file changed, 20 insertions(+)
33
34--- a/fs/ext4/resize.c
35+++ b/fs/ext4/resize.c
36@@ -1986,6 +1986,26 @@ retry:
37 }
38 }
39
40+ /*
41+ * Make sure the last group has enough space so that it's
42+ * guaranteed to have enough space for all metadata blocks
43+ * that it might need to hold. (We might not need to store
44+ * the inode table blocks in the last block group, but there
45+ * will be cases where this might be needed.)
46+ */
47+ if ((ext4_group_first_block_no(sb, n_group) +
48+ ext4_group_overhead_blocks(sb, n_group) + 2 +
49+ sbi->s_itb_per_group + sbi->s_cluster_ratio) >= n_blocks_count) {
50+ n_blocks_count = ext4_group_first_block_no(sb, n_group);
51+ n_group--;
52+ n_blocks_count_retry = 0;
53+ if (resize_inode) {
54+ iput(resize_inode);
55+ resize_inode = NULL;
56+ }
57+ goto retry;
58+ }
59+
60 /* extend the last group */
61 if (n_group == o_group)
62 add = n_blocks_count - o_blocks_count;