Skip to content

Commit 18b34d9

Browse files
committed
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 bugfixes from Ted Ts'o: "More bug fixes for ext4 -- most importantly, a fix for a bug introduced in 3.15 that can end up triggering a file system corruption error after a journal replay. It shouldn't lead to any actual data corruption, but it is scary and can force file systems to be remounted read-only, etc" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: fix potential null pointer dereference in ext4_free_inode ext4: fix a potential deadlock in __ext4_es_shrink() ext4: revert commit which was causing fs corruption after journal replays ext4: disable synchronous transaction batching if max_batch_time==0 ext4: clarify ext4_error message in ext4_mb_generate_buddy_error() ext4: clarify error count warning messages ext4: fix unjournalled bg descriptor while initializing inode bitmap
2 parents 502fde1 + bf40c92 commit 18b34d9

File tree

5 files changed

+44
-45
lines changed

5 files changed

+44
-45
lines changed

fs/ext4/extents_status.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -966,10 +966,10 @@ static int __ext4_es_shrink(struct ext4_sb_info *sbi, int nr_to_scan,
966966
continue;
967967
}
968968

969-
if (ei->i_es_lru_nr == 0 || ei == locked_ei)
969+
if (ei->i_es_lru_nr == 0 || ei == locked_ei ||
970+
!write_trylock(&ei->i_es_lock))
970971
continue;
971972

972-
write_lock(&ei->i_es_lock);
973973
shrunk = __es_try_to_reclaim_extents(ei, nr_to_scan);
974974
if (ei->i_es_lru_nr == 0)
975975
list_del_init(&ei->i_es_lru);

fs/ext4/ialloc.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
338338
fatal = err;
339339
} else {
340340
ext4_error(sb, "bit already cleared for inode %lu", ino);
341-
if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
341+
if (gdp && !EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
342342
int count;
343343
count = ext4_free_inodes_count(sb, gdp);
344344
percpu_counter_sub(&sbi->s_freeinodes_counter,
@@ -874,6 +874,13 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
874874
goto out;
875875
}
876876

877+
BUFFER_TRACE(group_desc_bh, "get_write_access");
878+
err = ext4_journal_get_write_access(handle, group_desc_bh);
879+
if (err) {
880+
ext4_std_error(sb, err);
881+
goto out;
882+
}
883+
877884
/* We may have to initialize the block bitmap if it isn't already */
878885
if (ext4_has_group_desc_csum(sb) &&
879886
gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
@@ -910,13 +917,6 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
910917
}
911918
}
912919

913-
BUFFER_TRACE(group_desc_bh, "get_write_access");
914-
err = ext4_journal_get_write_access(handle, group_desc_bh);
915-
if (err) {
916-
ext4_std_error(sb, err);
917-
goto out;
918-
}
919-
920920
/* Update the relevant bg descriptor fields */
921921
if (ext4_has_group_desc_csum(sb)) {
922922
int free;

fs/ext4/mballoc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,8 +752,8 @@ void ext4_mb_generate_buddy(struct super_block *sb,
752752

753753
if (free != grp->bb_free) {
754754
ext4_grp_locked_error(sb, group, 0, 0,
755-
"%u clusters in bitmap, %u in gd; "
756-
"block bitmap corrupt.",
755+
"block bitmap and bg descriptor "
756+
"inconsistent: %u vs %u free clusters",
757757
free, grp->bb_free);
758758
/*
759759
* If we intend to continue, we consider group descriptor

fs/ext4/super.c

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,8 +1525,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
15251525
arg = JBD2_DEFAULT_MAX_COMMIT_AGE;
15261526
sbi->s_commit_interval = HZ * arg;
15271527
} else if (token == Opt_max_batch_time) {
1528-
if (arg == 0)
1529-
arg = EXT4_DEF_MAX_BATCH_TIME;
15301528
sbi->s_max_batch_time = arg;
15311529
} else if (token == Opt_min_batch_time) {
15321530
sbi->s_min_batch_time = arg;
@@ -2809,10 +2807,11 @@ static void print_daily_error_info(unsigned long arg)
28092807
es = sbi->s_es;
28102808

28112809
if (es->s_error_count)
2812-
ext4_msg(sb, KERN_NOTICE, "error count: %u",
2810+
/* fsck newer than v1.41.13 is needed to clean this condition. */
2811+
ext4_msg(sb, KERN_NOTICE, "error count since last fsck: %u",
28132812
le32_to_cpu(es->s_error_count));
28142813
if (es->s_first_error_time) {
2815-
printk(KERN_NOTICE "EXT4-fs (%s): initial error at %u: %.*s:%d",
2814+
printk(KERN_NOTICE "EXT4-fs (%s): initial error at time %u: %.*s:%d",
28162815
sb->s_id, le32_to_cpu(es->s_first_error_time),
28172816
(int) sizeof(es->s_first_error_func),
28182817
es->s_first_error_func,
@@ -2826,7 +2825,7 @@ static void print_daily_error_info(unsigned long arg)
28262825
printk("\n");
28272826
}
28282827
if (es->s_last_error_time) {
2829-
printk(KERN_NOTICE "EXT4-fs (%s): last error at %u: %.*s:%d",
2828+
printk(KERN_NOTICE "EXT4-fs (%s): last error at time %u: %.*s:%d",
28302829
sb->s_id, le32_to_cpu(es->s_last_error_time),
28312830
(int) sizeof(es->s_last_error_func),
28322831
es->s_last_error_func,
@@ -3880,38 +3879,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
38803879
goto failed_mount2;
38813880
}
38823881
}
3883-
3884-
/*
3885-
* set up enough so that it can read an inode,
3886-
* and create new inode for buddy allocator
3887-
*/
3888-
sbi->s_gdb_count = db_count;
3889-
if (!test_opt(sb, NOLOAD) &&
3890-
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
3891-
sb->s_op = &ext4_sops;
3892-
else
3893-
sb->s_op = &ext4_nojournal_sops;
3894-
3895-
ext4_ext_init(sb);
3896-
err = ext4_mb_init(sb);
3897-
if (err) {
3898-
ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
3899-
err);
3900-
goto failed_mount2;
3901-
}
3902-
39033882
if (!ext4_check_descriptors(sb, &first_not_zeroed)) {
39043883
ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
3905-
goto failed_mount2a;
3884+
goto failed_mount2;
39063885
}
39073886
if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG))
39083887
if (!ext4_fill_flex_info(sb)) {
39093888
ext4_msg(sb, KERN_ERR,
39103889
"unable to initialize "
39113890
"flex_bg meta info!");
3912-
goto failed_mount2a;
3891+
goto failed_mount2;
39133892
}
39143893

3894+
sbi->s_gdb_count = db_count;
39153895
get_random_bytes(&sbi->s_next_generation, sizeof(u32));
39163896
spin_lock_init(&sbi->s_next_gen_lock);
39173897

@@ -3946,6 +3926,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
39463926
sbi->s_stripe = ext4_get_stripe_size(sbi);
39473927
sbi->s_extent_max_zeroout_kb = 32;
39483928

3929+
/*
3930+
* set up enough so that it can read an inode
3931+
*/
3932+
if (!test_opt(sb, NOLOAD) &&
3933+
EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL))
3934+
sb->s_op = &ext4_sops;
3935+
else
3936+
sb->s_op = &ext4_nojournal_sops;
39493937
sb->s_export_op = &ext4_export_ops;
39503938
sb->s_xattr = ext4_xattr_handlers;
39513939
#ifdef CONFIG_QUOTA
@@ -4135,13 +4123,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
41354123
if (err) {
41364124
ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for "
41374125
"reserved pool", ext4_calculate_resv_clusters(sb));
4138-
goto failed_mount5;
4126+
goto failed_mount4a;
41394127
}
41404128

41414129
err = ext4_setup_system_zone(sb);
41424130
if (err) {
41434131
ext4_msg(sb, KERN_ERR, "failed to initialize system "
41444132
"zone (%d)", err);
4133+
goto failed_mount4a;
4134+
}
4135+
4136+
ext4_ext_init(sb);
4137+
err = ext4_mb_init(sb);
4138+
if (err) {
4139+
ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
4140+
err);
41454141
goto failed_mount5;
41464142
}
41474143

@@ -4218,8 +4214,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
42184214
failed_mount7:
42194215
ext4_unregister_li_request(sb);
42204216
failed_mount6:
4221-
ext4_release_system_zone(sb);
4217+
ext4_mb_release(sb);
42224218
failed_mount5:
4219+
ext4_ext_release(sb);
4220+
ext4_release_system_zone(sb);
4221+
failed_mount4a:
42234222
dput(sb->s_root);
42244223
sb->s_root = NULL;
42254224
failed_mount4:
@@ -4243,14 +4242,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
42434242
percpu_counter_destroy(&sbi->s_extent_cache_cnt);
42444243
if (sbi->s_mmp_tsk)
42454244
kthread_stop(sbi->s_mmp_tsk);
4246-
failed_mount2a:
4247-
ext4_mb_release(sb);
42484245
failed_mount2:
42494246
for (i = 0; i < db_count; i++)
42504247
brelse(sbi->s_group_desc[i]);
42514248
ext4_kvfree(sbi->s_group_desc);
42524249
failed_mount:
4253-
ext4_ext_release(sb);
42544250
if (sbi->s_chksum_driver)
42554251
crypto_free_shash(sbi->s_chksum_driver);
42564252
if (sbi->s_proc) {

fs/jbd2/transaction.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1588,9 +1588,12 @@ int jbd2_journal_stop(handle_t *handle)
15881588
* to perform a synchronous write. We do this to detect the
15891589
* case where a single process is doing a stream of sync
15901590
* writes. No point in waiting for joiners in that case.
1591+
*
1592+
* Setting max_batch_time to 0 disables this completely.
15911593
*/
15921594
pid = current->pid;
1593-
if (handle->h_sync && journal->j_last_sync_writer != pid) {
1595+
if (handle->h_sync && journal->j_last_sync_writer != pid &&
1596+
journal->j_max_batch_time) {
15941597
u64 commit_time, trans_time;
15951598

15961599
journal->j_last_sync_writer = pid;

0 commit comments

Comments
 (0)