diff mbox series

[x/azure,c/azure] ext4: fix crash during online resizing

Message ID 20190704181645.16067-1-marcelo.cerri@canonical.com
State New
Headers show
Series [x/azure,c/azure] ext4: fix crash during online resizing | expand

Commit Message

Marcelo Henrique Cerri July 4, 2019, 6:16 p.m. UTC
From: Jan Kara <jack@suse.cz>

BugLink: http://bugs.launchpad.net/bugs/1835322

When computing maximum size of filesystem possible with given number of
group descriptor blocks, we forget to include s_first_data_block into
the number of blocks. Thus for filesystems with non-zero
s_first_data_block it can happen that computed maximum filesystem size
is actually lower than current filesystem size which confuses the code
and eventually leads to a BUG_ON in ext4_alloc_group_tables() hitting on
flex_gd->count == 0. The problem can be reproduced like:

truncate -s 100g /tmp/image
mkfs.ext4 -b 1024 -E resize=262144 /tmp/image 32768
mount -t ext4 -o loop /tmp/image /mnt
resize2fs /dev/loop0 262145
resize2fs /dev/loop0 300000

Fix the problem by properly including s_first_data_block into the
computed number of filesystem blocks.

Fixes: 1c6bd7173d66 "ext4: convert file system to meta_bg if needed..."
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@vger.kernel.org
(cherry picked from commit f96c3ac8dfc24b4e38fc4c2eba5fea2107b929d1)
Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
---
 fs/ext4/resize.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Thadeu Lima de Souza Cascardo July 4, 2019, 6:25 p.m. UTC | #1
Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Khalid Elmously July 4, 2019, 6:27 p.m. UTC | #2
Looks good, but BugLink should usually be https://.


On 2019-07-04 15:16:45 , Marcelo Henrique Cerri wrote:
> From: Jan Kara <jack@suse.cz>
> 
> BugLink: http://bugs.launchpad.net/bugs/1835322
> 
> When computing maximum size of filesystem possible with given number of
> group descriptor blocks, we forget to include s_first_data_block into
> the number of blocks. Thus for filesystems with non-zero
> s_first_data_block it can happen that computed maximum filesystem size
> is actually lower than current filesystem size which confuses the code
> and eventually leads to a BUG_ON in ext4_alloc_group_tables() hitting on
> flex_gd->count == 0. The problem can be reproduced like:
> 
> truncate -s 100g /tmp/image
> mkfs.ext4 -b 1024 -E resize=262144 /tmp/image 32768
> mount -t ext4 -o loop /tmp/image /mnt
> resize2fs /dev/loop0 262145
> resize2fs /dev/loop0 300000
> 
> Fix the problem by properly including s_first_data_block into the
> computed number of filesystem blocks.
> 
> Fixes: 1c6bd7173d66 "ext4: convert file system to meta_bg if needed..."
> Signed-off-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
> Cc: stable@vger.kernel.org
> (cherry picked from commit f96c3ac8dfc24b4e38fc4c2eba5fea2107b929d1)
> Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
> ---
>  fs/ext4/resize.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
> index c38f9e838aef..b7809d16a5d4 100644
> --- a/fs/ext4/resize.c
> +++ b/fs/ext4/resize.c
> @@ -1957,7 +1957,8 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
>  				le16_to_cpu(es->s_reserved_gdt_blocks);
>  			n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
>  			n_blocks_count = (ext4_fsblk_t)n_group *
> -				EXT4_BLOCKS_PER_GROUP(sb);
> +				EXT4_BLOCKS_PER_GROUP(sb) +
> +				le32_to_cpu(es->s_first_data_block);
>  			n_group--; /* set to last group number */
>  		}
>  
> -- 
> 2.20.1
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
Tyler Hicks July 4, 2019, 6:28 p.m. UTC | #3
On 2019-07-04 15:16:45, Marcelo Henrique Cerri wrote:
> From: Jan Kara <jack@suse.cz>
> 
> BugLink: http://bugs.launchpad.net/bugs/1835322
> 
> When computing maximum size of filesystem possible with given number of
> group descriptor blocks, we forget to include s_first_data_block into
> the number of blocks. Thus for filesystems with non-zero
> s_first_data_block it can happen that computed maximum filesystem size
> is actually lower than current filesystem size which confuses the code
> and eventually leads to a BUG_ON in ext4_alloc_group_tables() hitting on
> flex_gd->count == 0. The problem can be reproduced like:
> 
> truncate -s 100g /tmp/image
> mkfs.ext4 -b 1024 -E resize=262144 /tmp/image 32768
> mount -t ext4 -o loop /tmp/image /mnt
> resize2fs /dev/loop0 262145
> resize2fs /dev/loop0 300000
> 
> Fix the problem by properly including s_first_data_block into the
> computed number of filesystem blocks.
> 
> Fixes: 1c6bd7173d66 "ext4: convert file system to meta_bg if needed..."
> Signed-off-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
> Cc: stable@vger.kernel.org
> (cherry picked from commit f96c3ac8dfc24b4e38fc4c2eba5fea2107b929d1)
> Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>

Acked-by: Tyler Hicks <tyhicks@canonical.com>

Tyler

> ---
>  fs/ext4/resize.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
> index c38f9e838aef..b7809d16a5d4 100644
> --- a/fs/ext4/resize.c
> +++ b/fs/ext4/resize.c
> @@ -1957,7 +1957,8 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
>  				le16_to_cpu(es->s_reserved_gdt_blocks);
>  			n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
>  			n_blocks_count = (ext4_fsblk_t)n_group *
> -				EXT4_BLOCKS_PER_GROUP(sb);
> +				EXT4_BLOCKS_PER_GROUP(sb) +
> +				le32_to_cpu(es->s_first_data_block);
>  			n_group--; /* set to last group number */
>  		}
>  
> -- 
> 2.20.1
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
Marcelo Henrique Cerri July 4, 2019, 11:16 p.m. UTC | #4
On Thu, Jul 4, 2019 at 3:16 PM Marcelo Henrique Cerri
<marcelo.cerri@canonical.com> wrote:
>
> From: Jan Kara <jack@suse.cz>
>
> BugLink: http://bugs.launchpad.net/bugs/1835322
>
> When computing maximum size of filesystem possible with given number of
> group descriptor blocks, we forget to include s_first_data_block into
> the number of blocks. Thus for filesystems with non-zero
> s_first_data_block it can happen that computed maximum filesystem size
> is actually lower than current filesystem size which confuses the code
> and eventually leads to a BUG_ON in ext4_alloc_group_tables() hitting on
> flex_gd->count == 0. The problem can be reproduced like:
>
> truncate -s 100g /tmp/image
> mkfs.ext4 -b 1024 -E resize=262144 /tmp/image 32768
> mount -t ext4 -o loop /tmp/image /mnt
> resize2fs /dev/loop0 262145
> resize2fs /dev/loop0 300000
>
> Fix the problem by properly including s_first_data_block into the
> computed number of filesystem blocks.
>
> Fixes: 1c6bd7173d66 "ext4: convert file system to meta_bg if needed..."
> Signed-off-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
> Cc: stable@vger.kernel.org
> (cherry picked from commit f96c3ac8dfc24b4e38fc4c2eba5fea2107b929d1)
> Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
> ---
>  fs/ext4/resize.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
> index c38f9e838aef..b7809d16a5d4 100644
> --- a/fs/ext4/resize.c
> +++ b/fs/ext4/resize.c
> @@ -1957,7 +1957,8 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
>                                 le16_to_cpu(es->s_reserved_gdt_blocks);
>                         n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
>                         n_blocks_count = (ext4_fsblk_t)n_group *
> -                               EXT4_BLOCKS_PER_GROUP(sb);
> +                               EXT4_BLOCKS_PER_GROUP(sb) +
> +                               le32_to_cpu(es->s_first_data_block);
>                         n_group--; /* set to last group number */
>                 }
>
> --
> 2.20.1
>
diff mbox series

Patch

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index c38f9e838aef..b7809d16a5d4 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1957,7 +1957,8 @@  int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
 				le16_to_cpu(es->s_reserved_gdt_blocks);
 			n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
 			n_blocks_count = (ext4_fsblk_t)n_group *
-				EXT4_BLOCKS_PER_GROUP(sb);
+				EXT4_BLOCKS_PER_GROUP(sb) +
+				le32_to_cpu(es->s_first_data_block);
 			n_group--; /* set to last group number */
 		}