Skip to content

Commit e49d68c

Browse files
committed
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o: "Ext4 regression and bug fixes" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: inline jbd2_journal_[un]register_shrinker() ext4: fix flags validity checking for EXT4_IOC_CHECKPOINT ext4: fix possible UAF when remounting r/o a mmp-protected file system ext4: use ext4_grp_locked_error in mb_find_extent ext4: fix WARN_ON_ONCE(!buffer_uptodate) after an error writing the superblock Revert "ext4: consolidate checks for resize of bigalloc into ext4_resize_begin"
2 parents 47a7ce6 + 0705e8d commit e49d68c

9 files changed

Lines changed: 115 additions & 132 deletions

File tree

fs/ext4/ext4_jbd2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
327327

328328
set_buffer_meta(bh);
329329
set_buffer_prio(bh);
330+
set_buffer_uptodate(bh);
330331
if (ext4_handle_valid(handle)) {
331332
err = jbd2_journal_dirty_metadata(handle, bh);
332333
/* Errors can only happen due to aborted journal or a nasty bug */
@@ -355,7 +356,6 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line,
355356
err);
356357
}
357358
} else {
358-
set_buffer_uptodate(bh);
359359
if (inode)
360360
mark_buffer_dirty_inode(bh, inode);
361361
else

fs/ext4/ioctl.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,13 @@ static long ext4_ioctl_group_add(struct file *file,
692692
if (err)
693693
return err;
694694

695+
if (ext4_has_feature_bigalloc(sb)) {
696+
ext4_msg(sb, KERN_ERR,
697+
"Online resizing not supported with bigalloc");
698+
err = -EOPNOTSUPP;
699+
goto group_add_out;
700+
}
701+
695702
err = mnt_want_write_file(file);
696703
if (err)
697704
goto group_add_out;
@@ -816,7 +823,7 @@ static int ext4_ioctl_checkpoint(struct file *filp, unsigned long arg)
816823
if (!EXT4_SB(sb)->s_journal)
817824
return -ENODEV;
818825

819-
if (flags & ~JBD2_JOURNAL_FLUSH_VALID)
826+
if (flags & ~EXT4_IOC_CHECKPOINT_FLAG_VALID)
820827
return -EINVAL;
821828

822829
q = bdev_get_queue(EXT4_SB(sb)->s_journal->j_dev);
@@ -914,6 +921,13 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
914921
goto group_extend_out;
915922
}
916923

924+
if (ext4_has_feature_bigalloc(sb)) {
925+
ext4_msg(sb, KERN_ERR,
926+
"Online resizing not supported with bigalloc");
927+
err = -EOPNOTSUPP;
928+
goto group_extend_out;
929+
}
930+
917931
err = mnt_want_write_file(filp);
918932
if (err)
919933
goto group_extend_out;

fs/ext4/mballoc.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,10 +1909,11 @@ static int mb_find_extent(struct ext4_buddy *e4b, int block,
19091909
if (ex->fe_start + ex->fe_len > EXT4_CLUSTERS_PER_GROUP(e4b->bd_sb)) {
19101910
/* Should never happen! (but apparently sometimes does?!?) */
19111911
WARN_ON(1);
1912-
ext4_error(e4b->bd_sb, "corruption or bug in mb_find_extent "
1913-
"block=%d, order=%d needed=%d ex=%u/%d/%d@%u",
1914-
block, order, needed, ex->fe_group, ex->fe_start,
1915-
ex->fe_len, ex->fe_logical);
1912+
ext4_grp_locked_error(e4b->bd_sb, e4b->bd_group, 0, 0,
1913+
"corruption or bug in mb_find_extent "
1914+
"block=%d, order=%d needed=%d ex=%u/%d/%d@%u",
1915+
block, order, needed, ex->fe_group, ex->fe_start,
1916+
ex->fe_len, ex->fe_logical);
19161917
ex->fe_len = 0;
19171918
ex->fe_start = 0;
19181919
ex->fe_group = 0;

fs/ext4/mmp.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,12 @@ static int kmmpd(void *data)
156156
memcpy(mmp->mmp_nodename, init_utsname()->nodename,
157157
sizeof(mmp->mmp_nodename));
158158

159-
while (!kthread_should_stop()) {
159+
while (!kthread_should_stop() && !sb_rdonly(sb)) {
160+
if (!ext4_has_feature_mmp(sb)) {
161+
ext4_warning(sb, "kmmpd being stopped since MMP feature"
162+
" has been disabled.");
163+
goto wait_to_exit;
164+
}
160165
if (++seq > EXT4_MMP_SEQ_MAX)
161166
seq = 1;
162167

@@ -177,16 +182,6 @@ static int kmmpd(void *data)
177182
failed_writes++;
178183
}
179184

180-
if (!(le32_to_cpu(es->s_feature_incompat) &
181-
EXT4_FEATURE_INCOMPAT_MMP)) {
182-
ext4_warning(sb, "kmmpd being stopped since MMP feature"
183-
" has been disabled.");
184-
goto exit_thread;
185-
}
186-
187-
if (sb_rdonly(sb))
188-
break;
189-
190185
diff = jiffies - last_update_time;
191186
if (diff < mmp_update_interval * HZ)
192187
schedule_timeout_interruptible(mmp_update_interval *
@@ -207,7 +202,7 @@ static int kmmpd(void *data)
207202
ext4_error_err(sb, -retval,
208203
"error reading MMP data: %d",
209204
retval);
210-
goto exit_thread;
205+
goto wait_to_exit;
211206
}
212207

213208
mmp_check = (struct mmp_struct *)(bh_check->b_data);
@@ -221,7 +216,7 @@ static int kmmpd(void *data)
221216
ext4_error_err(sb, EBUSY, "abort");
222217
put_bh(bh_check);
223218
retval = -EBUSY;
224-
goto exit_thread;
219+
goto wait_to_exit;
225220
}
226221
put_bh(bh_check);
227222
}
@@ -244,7 +239,13 @@ static int kmmpd(void *data)
244239

245240
retval = write_mmp_block(sb, bh);
246241

247-
exit_thread:
242+
wait_to_exit:
243+
while (!kthread_should_stop()) {
244+
set_current_state(TASK_INTERRUPTIBLE);
245+
if (!kthread_should_stop())
246+
schedule();
247+
}
248+
set_current_state(TASK_RUNNING);
248249
return retval;
249250
}
250251

@@ -391,5 +392,3 @@ int ext4_multi_mount_protect(struct super_block *sb,
391392
brelse(bh);
392393
return 1;
393394
}
394-
395-

fs/ext4/resize.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,6 @@ int ext4_resize_begin(struct super_block *sb)
7474
return -EPERM;
7575
}
7676

77-
if (ext4_has_feature_bigalloc(sb)) {
78-
ext4_msg(sb, KERN_ERR, "Online resizing not supported with bigalloc");
79-
return -EOPNOTSUPP;
80-
}
8177
if (ext4_has_feature_sparse_super2(sb)) {
8278
ext4_msg(sb, KERN_ERR, "Online resizing not supported with sparse_super2");
8379
return -EOPNOTSUPP;

fs/ext4/super.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -705,15 +705,23 @@ static void flush_stashed_error_work(struct work_struct *work)
705705
* ext4 error handling code during handling of previous errors.
706706
*/
707707
if (!sb_rdonly(sbi->s_sb) && journal) {
708+
struct buffer_head *sbh = sbi->s_sbh;
708709
handle = jbd2_journal_start(journal, 1);
709710
if (IS_ERR(handle))
710711
goto write_directly;
711-
if (jbd2_journal_get_write_access(handle, sbi->s_sbh)) {
712+
if (jbd2_journal_get_write_access(handle, sbh)) {
712713
jbd2_journal_stop(handle);
713714
goto write_directly;
714715
}
715716
ext4_update_super(sbi->s_sb);
716-
if (jbd2_journal_dirty_metadata(handle, sbi->s_sbh)) {
717+
if (buffer_write_io_error(sbh) || !buffer_uptodate(sbh)) {
718+
ext4_msg(sbi->s_sb, KERN_ERR, "previous I/O error to "
719+
"superblock detected");
720+
clear_buffer_write_io_error(sbh);
721+
set_buffer_uptodate(sbh);
722+
}
723+
724+
if (jbd2_journal_dirty_metadata(handle, sbh)) {
717725
jbd2_journal_stop(handle);
718726
goto write_directly;
719727
}
@@ -1176,7 +1184,6 @@ static void ext4_put_super(struct super_block *sb)
11761184
ext4_unregister_sysfs(sb);
11771185

11781186
if (sbi->s_journal) {
1179-
jbd2_journal_unregister_shrinker(sbi->s_journal);
11801187
aborted = is_journal_aborted(sbi->s_journal);
11811188
err = jbd2_journal_destroy(sbi->s_journal);
11821189
sbi->s_journal = NULL;
@@ -5168,7 +5175,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
51685175
sbi->s_ea_block_cache = NULL;
51695176

51705177
if (sbi->s_journal) {
5171-
jbd2_journal_unregister_shrinker(sbi->s_journal);
51725178
jbd2_journal_destroy(sbi->s_journal);
51735179
sbi->s_journal = NULL;
51745180
}
@@ -5494,12 +5500,6 @@ static int ext4_load_journal(struct super_block *sb,
54945500
ext4_commit_super(sb);
54955501
}
54965502

5497-
err = jbd2_journal_register_shrinker(journal);
5498-
if (err) {
5499-
EXT4_SB(sb)->s_journal = NULL;
5500-
goto err_out;
5501-
}
5502-
55035503
return 0;
55045504

55055505
err_out:
@@ -5985,7 +5985,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
59855985
*/
59865986
ext4_mark_recovery_complete(sb, es);
59875987
}
5988-
ext4_stop_mmpd(sbi);
59895988
} else {
59905989
/* Make sure we can mount this feature set readwrite */
59915990
if (ext4_has_feature_readonly(sb) ||
@@ -6099,6 +6098,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
60996098
if (!test_opt(sb, BLOCK_VALIDITY) && sbi->s_system_blks)
61006099
ext4_release_system_zone(sb);
61016100

6101+
if (!ext4_has_feature_mmp(sb) || sb_rdonly(sb))
6102+
ext4_stop_mmpd(sbi);
6103+
61026104
/*
61036105
* Some options can be enabled by ext4 and/or by VFS mount flag
61046106
* either way we need to make sure it matches in both *flags and
@@ -6132,6 +6134,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
61326134
for (i = 0; i < EXT4_MAXQUOTAS; i++)
61336135
kfree(to_free[i]);
61346136
#endif
6137+
if (!ext4_has_feature_mmp(sb) || sb_rdonly(sb))
6138+
ext4_stop_mmpd(sbi);
61356139
kfree(orig_data);
61366140
return err;
61376141
}

fs/jbd2/checkpoint.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
701701

702702
__buffer_unlink(jh);
703703
jh->b_cp_transaction = NULL;
704-
percpu_counter_dec(&journal->j_jh_shrink_count);
704+
percpu_counter_dec(&journal->j_checkpoint_jh_count);
705705
jbd2_journal_put_journal_head(jh);
706706

707707
/* Is this transaction empty? */
@@ -764,7 +764,7 @@ void __jbd2_journal_insert_checkpoint(struct journal_head *jh,
764764
jh->b_cpnext->b_cpprev = jh;
765765
}
766766
transaction->t_checkpoint_list = jh;
767-
percpu_counter_inc(&transaction->t_journal->j_jh_shrink_count);
767+
percpu_counter_inc(&transaction->t_journal->j_checkpoint_jh_count);
768768
}
769769

770770
/*

0 commit comments

Comments
 (0)