[RHEL7,COMMIT] ms/ext4: fix online resize's handling of a too-small final block group

Submitted by Konstantin Khorenko on Oct. 31, 2018, 10:44 a.m.

Details

Message ID 201810311044.w9VAifRo022716@finist-ce7.sw.ru
State New
Series "ms/ext4: fix online resize's handling of a too-small final block group"
Headers show

Commit Message

Konstantin Khorenko Oct. 31, 2018, 10:44 a.m.
The commit is pushed to "branch-rh7-3.10.0-862.14.4.vz7.72.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.14.4.vz7.72.15
------>
commit b8934960efb14c20ec6572ba0c7b892577c9d66f
Author: Theodore Ts'o <tytso@mit.edu>
Date:   Wed Oct 31 13:44:41 2018 +0300

    ms/ext4: fix online resize's handling of a too-small final block group
    
    commit f0a459dec5495a3580f8d784555e6f8f3bf7f263
    Author: Theodore Ts'o <tytso@mit.edu>
    Date:   Mon Sep 3 22:19:43 2018 -0400
    
        ext4: fix online resize's handling of a too-small final block group
    
        Avoid growing the file system to an extent so that the last block
        group is too small to hold all of the metadata that must be stored in
        the block group.
    
        This problem can be triggered with the following reproducer:
    
        umount /mnt
        mke2fs -F -m0 -b 4096 -t ext4 -O resize_inode,^has_journal \
                -E resize=1073741824 /tmp/foo.img 128M
        mount /tmp/foo.img /mnt
        truncate --size 1708M /tmp/foo.img
        resize2fs /dev/loop0 295400
        umount /mnt
        e2fsck -fy /tmp/foo.img
    
        Reported-by: Torsten Hilbrich <torsten.hilbrich@secunet.com>
        Signed-off-by: Theodore Ts'o <tytso@mit.edu>
        Cc: stable@vger.kernel.org
    
    fixes "attempt to access beyond end of device"
    https://jira.sw.ru/browse/PSBM-89583
    
    Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
---
 fs/ext4/resize.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Patch hide | download patch | download mbox

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 99682f90d7b3..5bfe31c8e0f9 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1931,6 +1931,26 @@  int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
 		}
 	}
 
+	/*
+	 * Make sure the last group has enough space so that it's
+	 * guaranteed to have enough space for all metadata blocks
+	 * that it might need to hold.  (We might not need to store
+	 * the inode table blocks in the last block group, but there
+	 * will be cases where this might be needed.)
+	 */
+	if ((ext4_group_first_block_no(sb, n_group) +
+	     ext4_group_overhead_blocks(sb, n_group) + 2 +
+	     sbi->s_itb_per_group + sbi->s_cluster_ratio) >= n_blocks_count) {
+		n_blocks_count = ext4_group_first_block_no(sb, n_group);
+		n_group--;
+		n_blocks_count_retry = 0;
+		if (resize_inode) {
+			iput(resize_inode);
+			resize_inode = NULL;
+		}
+		goto retry;
+	}
+
 	/* extend the last group */
 	if (n_group == o_group)
 		add = n_blocks_count - o_blocks_count;