Skip to content

Commit 3cfb677

Browse files
committed
Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 fixes from Ted Ts'o: "Some miscellaneous ext4 fixes for 4.18; one fix is for a regression introduced in 4.18-rc4. Sorry for the late-breaking pull. I was originally going to wait for the next merge window, but Eric Whitney found a regression introduced in 4.18-rc4, so I decided to push out the regression plus the other fixes now. (The other commits have been baking in linux-next since early July)" * tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: fix check to prevent initializing reserved inodes ext4: check for allocation block validity with block group locked ext4: fix inline data updates with checksums enabled ext4: clear mmp sequence number when remounting read-only ext4: fix false negatives *and* false positives in ext4_check_descriptors()
2 parents 01cfb79 + 5012284 commit 3cfb677

File tree

6 files changed

+35
-33
lines changed

6 files changed

+35
-33
lines changed

fs/ext4/balloc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ static int ext4_validate_block_bitmap(struct super_block *sb,
368368
return -EFSCORRUPTED;
369369

370370
ext4_lock_group(sb, block_group);
371+
if (buffer_verified(bh))
372+
goto verified;
371373
if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group,
372374
desc, bh))) {
373375
ext4_unlock_group(sb, block_group);
@@ -386,6 +388,7 @@ static int ext4_validate_block_bitmap(struct super_block *sb,
386388
return -EFSCORRUPTED;
387389
}
388390
set_buffer_verified(bh);
391+
verified:
389392
ext4_unlock_group(sb, block_group);
390393
return 0;
391394
}

fs/ext4/ialloc.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ static int ext4_validate_inode_bitmap(struct super_block *sb,
9090
return -EFSCORRUPTED;
9191

9292
ext4_lock_group(sb, block_group);
93+
if (buffer_verified(bh))
94+
goto verified;
9395
blk = ext4_inode_bitmap(sb, desc);
9496
if (!ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh,
9597
EXT4_INODES_PER_GROUP(sb) / 8)) {
@@ -101,6 +103,7 @@ static int ext4_validate_inode_bitmap(struct super_block *sb,
101103
return -EFSBADCRC;
102104
}
103105
set_buffer_verified(bh);
106+
verified:
104107
ext4_unlock_group(sb, block_group);
105108
return 0;
106109
}
@@ -1385,7 +1388,10 @@ int ext4_init_inode_table(struct super_block *sb, ext4_group_t group,
13851388
ext4_itable_unused_count(sb, gdp)),
13861389
sbi->s_inodes_per_block);
13871390

1388-
if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group)) {
1391+
if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) ||
1392+
((group == 0) && ((EXT4_INODES_PER_GROUP(sb) -
1393+
ext4_itable_unused_count(sb, gdp)) <
1394+
EXT4_FIRST_INO(sb)))) {
13891395
ext4_error(sb, "Something is wrong with group %u: "
13901396
"used itable blocks: %d; "
13911397
"itable unused count: %u",

fs/ext4/inline.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,10 @@ int ext4_try_to_write_inline_data(struct address_space *mapping,
682682
goto convert;
683683
}
684684

685+
ret = ext4_journal_get_write_access(handle, iloc.bh);
686+
if (ret)
687+
goto out;
688+
685689
flags |= AOP_FLAG_NOFS;
686690

687691
page = grab_cache_page_write_begin(mapping, 0, flags);
@@ -710,7 +714,7 @@ int ext4_try_to_write_inline_data(struct address_space *mapping,
710714
out_up_read:
711715
up_read(&EXT4_I(inode)->xattr_sem);
712716
out:
713-
if (handle)
717+
if (handle && (ret != 1))
714718
ext4_journal_stop(handle);
715719
brelse(iloc.bh);
716720
return ret;
@@ -752,6 +756,7 @@ int ext4_write_inline_data_end(struct inode *inode, loff_t pos, unsigned len,
752756

753757
ext4_write_unlock_xattr(inode, &no_expand);
754758
brelse(iloc.bh);
759+
mark_inode_dirty(inode);
755760
out:
756761
return copied;
757762
}
@@ -898,7 +903,6 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
898903
goto out;
899904
}
900905

901-
902906
page = grab_cache_page_write_begin(mapping, 0, flags);
903907
if (!page) {
904908
ret = -ENOMEM;
@@ -916,6 +920,9 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping,
916920
if (ret < 0)
917921
goto out_release_page;
918922
}
923+
ret = ext4_journal_get_write_access(handle, iloc.bh);
924+
if (ret)
925+
goto out_release_page;
919926

920927
up_read(&EXT4_I(inode)->xattr_sem);
921928
*pagep = page;
@@ -936,7 +943,6 @@ int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
936943
unsigned len, unsigned copied,
937944
struct page *page)
938945
{
939-
int i_size_changed = 0;
940946
int ret;
941947

942948
ret = ext4_write_inline_data_end(inode, pos, len, copied, page);
@@ -954,10 +960,8 @@ int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
954960
* But it's important to update i_size while still holding page lock:
955961
* page writeout could otherwise come in and zero beyond i_size.
956962
*/
957-
if (pos+copied > inode->i_size) {
963+
if (pos+copied > inode->i_size)
958964
i_size_write(inode, pos+copied);
959-
i_size_changed = 1;
960-
}
961965
unlock_page(page);
962966
put_page(page);
963967

@@ -967,8 +971,7 @@ int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
967971
* ordering of page lock and transaction start for journaling
968972
* filesystems.
969973
*/
970-
if (i_size_changed)
971-
mark_inode_dirty(inode);
974+
mark_inode_dirty(inode);
972975

973976
return copied;
974977
}

fs/ext4/inode.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,9 +1389,10 @@ static int ext4_write_end(struct file *file,
13891389
loff_t old_size = inode->i_size;
13901390
int ret = 0, ret2;
13911391
int i_size_changed = 0;
1392+
int inline_data = ext4_has_inline_data(inode);
13921393

13931394
trace_ext4_write_end(inode, pos, len, copied);
1394-
if (ext4_has_inline_data(inode)) {
1395+
if (inline_data) {
13951396
ret = ext4_write_inline_data_end(inode, pos, len,
13961397
copied, page);
13971398
if (ret < 0) {
@@ -1419,7 +1420,7 @@ static int ext4_write_end(struct file *file,
14191420
* ordering of page lock and transaction start for journaling
14201421
* filesystems.
14211422
*/
1422-
if (i_size_changed)
1423+
if (i_size_changed || inline_data)
14231424
ext4_mark_inode_dirty(handle, inode);
14241425

14251426
if (pos + len > inode->i_size && ext4_can_truncate(inode))
@@ -1493,14 +1494,15 @@ static int ext4_journalled_write_end(struct file *file,
14931494
int partial = 0;
14941495
unsigned from, to;
14951496
int size_changed = 0;
1497+
int inline_data = ext4_has_inline_data(inode);
14961498

14971499
trace_ext4_journalled_write_end(inode, pos, len, copied);
14981500
from = pos & (PAGE_SIZE - 1);
14991501
to = from + len;
15001502

15011503
BUG_ON(!ext4_handle_valid(handle));
15021504

1503-
if (ext4_has_inline_data(inode)) {
1505+
if (inline_data) {
15041506
ret = ext4_write_inline_data_end(inode, pos, len,
15051507
copied, page);
15061508
if (ret < 0) {
@@ -1531,7 +1533,7 @@ static int ext4_journalled_write_end(struct file *file,
15311533
if (old_size < pos)
15321534
pagecache_isize_extended(inode, old_size, pos);
15331535

1534-
if (size_changed) {
1536+
if (size_changed || inline_data) {
15351537
ret2 = ext4_mark_inode_dirty(handle, inode);
15361538
if (!ret)
15371539
ret = ret2;
@@ -2028,11 +2030,7 @@ static int __ext4_journalled_writepage(struct page *page,
20282030
}
20292031

20302032
if (inline_data) {
2031-
BUFFER_TRACE(inode_bh, "get write access");
2032-
ret = ext4_journal_get_write_access(handle, inode_bh);
2033-
2034-
err = ext4_handle_dirty_metadata(handle, inode, inode_bh);
2035-
2033+
ret = ext4_mark_inode_dirty(handle, inode);
20362034
} else {
20372035
ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL,
20382036
do_journal_get_write_access);

fs/ext4/mmp.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,8 @@ static int kmmpd(void *data)
186186
goto exit_thread;
187187
}
188188

189-
if (sb_rdonly(sb)) {
190-
ext4_warning(sb, "kmmpd being stopped since filesystem "
191-
"has been remounted as readonly.");
192-
goto exit_thread;
193-
}
189+
if (sb_rdonly(sb))
190+
break;
194191

195192
diff = jiffies - last_update_time;
196193
if (diff < mmp_update_interval * HZ)

fs/ext4/super.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,7 +2342,7 @@ static int ext4_check_descriptors(struct super_block *sb,
23422342
struct ext4_sb_info *sbi = EXT4_SB(sb);
23432343
ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block);
23442344
ext4_fsblk_t last_block;
2345-
ext4_fsblk_t last_bg_block = sb_block + ext4_bg_num_gdb(sb, 0) + 1;
2345+
ext4_fsblk_t last_bg_block = sb_block + ext4_bg_num_gdb(sb, 0);
23462346
ext4_fsblk_t block_bitmap;
23472347
ext4_fsblk_t inode_bitmap;
23482348
ext4_fsblk_t inode_table;
@@ -3141,14 +3141,8 @@ static ext4_group_t ext4_has_uninit_itable(struct super_block *sb)
31413141
if (!gdp)
31423142
continue;
31433143

3144-
if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))
3145-
continue;
3146-
if (group != 0)
3144+
if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)))
31473145
break;
3148-
ext4_error(sb, "Inode table for bg 0 marked as "
3149-
"needing zeroing");
3150-
if (sb_rdonly(sb))
3151-
return ngroups;
31523146
}
31533147

31543148
return group;
@@ -4085,14 +4079,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
40854079
goto failed_mount2;
40864080
}
40874081
}
4082+
sbi->s_gdb_count = db_count;
40884083
if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) {
40894084
ext4_msg(sb, KERN_ERR, "group descriptors corrupted!");
40904085
ret = -EFSCORRUPTED;
40914086
goto failed_mount2;
40924087
}
40934088

4094-
sbi->s_gdb_count = db_count;
4095-
40964089
timer_setup(&sbi->s_err_report, print_daily_error_info, 0);
40974090

40984091
/* Register extent status tree shrinker */
@@ -5213,6 +5206,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
52135206

52145207
if (sbi->s_journal)
52155208
ext4_mark_recovery_complete(sb, es);
5209+
if (sbi->s_mmp_tsk)
5210+
kthread_stop(sbi->s_mmp_tsk);
52165211
} else {
52175212
/* Make sure we can mount this feature set readwrite */
52185213
if (ext4_has_feature_readonly(sb) ||

0 commit comments

Comments
 (0)