1 ext4: fix scheduling in atomic on group checksum failure
3 From: Jan Kara <jack@suse.cz>
5 When block group checksum is wrong, we call ext4_error() while holding
6 group spinlock from ext4_init_block_bitmap() or
7 ext4_init_inode_bitmap() which results in scheduling while in atomic.
8 Fix the issue by calling ext4_error() later after dropping the spinlock.
10 CC: stable@vger.kernel.org
11 Reported-by: Dmitry Vyukov <dvyukov@google.com>
12 Signed-off-by: Jan Kara <jack@suse.cz>
13 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
14 Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
16 fs/ext4/balloc.c | 7 ++++---
17 fs/ext4/ialloc.c | 6 ++++--
18 2 files changed, 8 insertions(+), 5 deletions(-)
20 diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
21 index ec0668a60678..fe1f50fe764f 100644
22 --- a/fs/ext4/balloc.c
23 +++ b/fs/ext4/balloc.c
24 @@ -191,7 +191,6 @@ static int ext4_init_block_bitmap(struct super_block *sb,
25 /* If checksum is bad mark all blocks used to prevent allocation
26 * essentially implementing a per-group read-only flag. */
27 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
28 - ext4_error(sb, "Checksum bad for group %u", block_group);
29 grp = ext4_get_group_info(sb, block_group);
30 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
31 percpu_counter_sub(&sbi->s_freeclusters_counter,
32 @@ -442,14 +441,16 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
34 ext4_lock_group(sb, block_group);
35 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
37 err = ext4_init_block_bitmap(sb, bh, block_group, desc);
38 set_bitmap_uptodate(bh);
39 set_buffer_uptodate(bh);
40 ext4_unlock_group(sb, block_group);
44 + ext4_error(sb, "Failed to init block bitmap for group "
45 + "%u: %d", block_group, err);
50 ext4_unlock_group(sb, block_group);
51 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
52 index 3fcfd50a2e8a..acc0ad56bf2f 100644
53 --- a/fs/ext4/ialloc.c
54 +++ b/fs/ext4/ialloc.c
55 @@ -76,7 +76,6 @@ static int ext4_init_inode_bitmap(struct super_block *sb,
56 /* If checksum is bad mark all blocks and inodes use to prevent
57 * allocation, essentially implementing a per-group read-only flag. */
58 if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
59 - ext4_error(sb, "Checksum bad for group %u", block_group);
60 grp = ext4_get_group_info(sb, block_group);
61 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
62 percpu_counter_sub(&sbi->s_freeclusters_counter,
63 @@ -191,8 +190,11 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
64 set_buffer_verified(bh);
65 ext4_unlock_group(sb, block_group);
69 + ext4_error(sb, "Failed to init inode bitmap for group "
70 + "%u: %d", block_group, err);
75 ext4_unlock_group(sb, block_group);
80 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
81 the body of a message to majordomo@vger.kernel.org
82 More majordomo info at http://vger.kernel.org/majordomo-info.html