| From 5012284700775a4e6e3fbe7eac4c543c4874b559 Mon Sep 17 00:00:00 2001 |
| From: Theodore Ts'o <tytso@mit.edu> |
| Date: Sat, 28 Jul 2018 08:12:04 -0400 |
| Subject: ext4: fix check to prevent initializing reserved inodes |
| |
| From: Theodore Ts'o <tytso@mit.edu> |
| |
| commit 5012284700775a4e6e3fbe7eac4c543c4874b559 upstream. |
| |
| Commit 8844618d8aa7: "ext4: only look at the bg_flags field if it is |
| valid" will complain if block group zero does not have the |
| EXT4_BG_INODE_ZEROED flag set. Unfortunately, this is not correct, |
| since a freshly created file system has this flag cleared. It gets |
| almost immediately after the file system is mounted read-write --- but |
| the following somewhat unlikely sequence will end up triggering a |
| false positive report of a corrupted file system: |
| |
| mkfs.ext4 /dev/vdc |
| mount -o ro /dev/vdc /vdc |
| mount -o remount,rw /dev/vdc |
| |
| Instead, when initializing the inode table for block group zero, test |
| to make sure that itable_unused count is not too large, since that is |
| the case that will result in some or all of the reserved inodes |
| getting cleared. |
| |
| This fixes the failures reported by Eric Whiteney when running |
| generic/230 and generic/231 in the the nojournal test case. |
| |
| Fixes: 8844618d8aa7 ("ext4: only look at the bg_flags field if it is valid") |
| Reported-by: Eric Whitney <enwlinux@gmail.com> |
| Signed-off-by: Theodore Ts'o <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/ext4/ialloc.c | 5 ++++- |
| fs/ext4/super.c | 8 +------- |
| 2 files changed, 5 insertions(+), 8 deletions(-) |
| |
| --- a/fs/ext4/ialloc.c |
| +++ b/fs/ext4/ialloc.c |
| @@ -1316,7 +1316,10 @@ int ext4_init_inode_table(struct super_b |
| ext4_itable_unused_count(sb, gdp)), |
| sbi->s_inodes_per_block); |
| |
| - if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group)) { |
| + if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) || |
| + ((group == 0) && ((EXT4_INODES_PER_GROUP(sb) - |
| + ext4_itable_unused_count(sb, gdp)) < |
| + EXT4_FIRST_INO(sb)))) { |
| ext4_error(sb, "Something is wrong with group %u: " |
| "used itable blocks: %d; " |
| "itable unused count: %u", |
| --- a/fs/ext4/super.c |
| +++ b/fs/ext4/super.c |
| @@ -3031,14 +3031,8 @@ static ext4_group_t ext4_has_uninit_itab |
| if (!gdp) |
| continue; |
| |
| - if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)) |
| - continue; |
| - if (group != 0) |
| + if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))) |
| break; |
| - ext4_error(sb, "Inode table for bg 0 marked as " |
| - "needing zeroing"); |
| - if (sb->s_flags & MS_RDONLY) |
| - return ngroups; |
| } |
| |
| return group; |