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()

Changed files
+35 -33
fs
+3
fs/ext4/balloc.c
··· 368 368 return -EFSCORRUPTED; 369 369 370 370 ext4_lock_group(sb, block_group); 371 + if (buffer_verified(bh)) 372 + goto verified; 371 373 if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, 372 374 desc, bh))) { 373 375 ext4_unlock_group(sb, block_group); ··· 388 386 return -EFSCORRUPTED; 389 387 } 390 388 set_buffer_verified(bh); 389 + verified: 391 390 ext4_unlock_group(sb, block_group); 392 391 return 0; 393 392 }
+7 -1
fs/ext4/ialloc.c
··· 90 90 return -EFSCORRUPTED; 91 91 92 92 ext4_lock_group(sb, block_group); 93 + if (buffer_verified(bh)) 94 + goto verified; 93 95 blk = ext4_inode_bitmap(sb, desc); 94 96 if (!ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh, 95 97 EXT4_INODES_PER_GROUP(sb) / 8)) { ··· 103 101 return -EFSBADCRC; 104 102 } 105 103 set_buffer_verified(bh); 104 + verified: 106 105 ext4_unlock_group(sb, block_group); 107 106 return 0; 108 107 } ··· 1388 1385 ext4_itable_unused_count(sb, gdp)), 1389 1386 sbi->s_inodes_per_block); 1390 1387 1391 - if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group)) { 1388 + if ((used_blks < 0) || (used_blks > sbi->s_itb_per_group) || 1389 + ((group == 0) && ((EXT4_INODES_PER_GROUP(sb) - 1390 + ext4_itable_unused_count(sb, gdp)) < 1391 + EXT4_FIRST_INO(sb)))) { 1392 1392 ext4_error(sb, "Something is wrong with group %u: " 1393 1393 "used itable blocks: %d; " 1394 1394 "itable unused count: %u",
+11 -8
fs/ext4/inline.c
··· 682 682 goto convert; 683 683 } 684 684 685 + ret = ext4_journal_get_write_access(handle, iloc.bh); 686 + if (ret) 687 + goto out; 688 + 685 689 flags |= AOP_FLAG_NOFS; 686 690 687 691 page = grab_cache_page_write_begin(mapping, 0, flags); ··· 714 710 out_up_read: 715 711 up_read(&EXT4_I(inode)->xattr_sem); 716 712 out: 717 - if (handle) 713 + if (handle && (ret != 1)) 718 714 ext4_journal_stop(handle); 719 715 brelse(iloc.bh); 720 716 return ret; ··· 756 752 757 753 ext4_write_unlock_xattr(inode, &no_expand); 758 754 brelse(iloc.bh); 755 + mark_inode_dirty(inode); 759 756 out: 760 757 return copied; 761 758 } ··· 903 898 goto out; 904 899 } 905 900 906 - 907 901 page = grab_cache_page_write_begin(mapping, 0, flags); 908 902 if (!page) { 909 903 ret = -ENOMEM; ··· 920 916 if (ret < 0) 921 917 goto out_release_page; 922 918 } 919 + ret = ext4_journal_get_write_access(handle, iloc.bh); 920 + if (ret) 921 + goto out_release_page; 923 922 924 923 up_read(&EXT4_I(inode)->xattr_sem); 925 924 *pagep = page; ··· 943 936 unsigned len, unsigned copied, 944 937 struct page *page) 945 938 { 946 - int i_size_changed = 0; 947 939 int ret; 948 940 949 941 ret = ext4_write_inline_data_end(inode, pos, len, copied, page); ··· 960 954 * But it's important to update i_size while still holding page lock: 961 955 * page writeout could otherwise come in and zero beyond i_size. 962 956 */ 963 - if (pos+copied > inode->i_size) { 957 + if (pos+copied > inode->i_size) 964 958 i_size_write(inode, pos+copied); 965 - i_size_changed = 1; 966 - } 967 959 unlock_page(page); 968 960 put_page(page); 969 961 ··· 971 967 * ordering of page lock and transaction start for journaling 972 968 * filesystems. 973 969 */ 974 - if (i_size_changed) 975 - mark_inode_dirty(inode); 970 + mark_inode_dirty(inode); 976 971 977 972 return copied; 978 973 }
+7 -9
fs/ext4/inode.c
··· 1389 1389 loff_t old_size = inode->i_size; 1390 1390 int ret = 0, ret2; 1391 1391 int i_size_changed = 0; 1392 + int inline_data = ext4_has_inline_data(inode); 1392 1393 1393 1394 trace_ext4_write_end(inode, pos, len, copied); 1394 - if (ext4_has_inline_data(inode)) { 1395 + if (inline_data) { 1395 1396 ret = ext4_write_inline_data_end(inode, pos, len, 1396 1397 copied, page); 1397 1398 if (ret < 0) { ··· 1420 1419 * ordering of page lock and transaction start for journaling 1421 1420 * filesystems. 1422 1421 */ 1423 - if (i_size_changed) 1422 + if (i_size_changed || inline_data) 1424 1423 ext4_mark_inode_dirty(handle, inode); 1425 1424 1426 1425 if (pos + len > inode->i_size && ext4_can_truncate(inode)) ··· 1494 1493 int partial = 0; 1495 1494 unsigned from, to; 1496 1495 int size_changed = 0; 1496 + int inline_data = ext4_has_inline_data(inode); 1497 1497 1498 1498 trace_ext4_journalled_write_end(inode, pos, len, copied); 1499 1499 from = pos & (PAGE_SIZE - 1); ··· 1502 1500 1503 1501 BUG_ON(!ext4_handle_valid(handle)); 1504 1502 1505 - if (ext4_has_inline_data(inode)) { 1503 + if (inline_data) { 1506 1504 ret = ext4_write_inline_data_end(inode, pos, len, 1507 1505 copied, page); 1508 1506 if (ret < 0) { ··· 1533 1531 if (old_size < pos) 1534 1532 pagecache_isize_extended(inode, old_size, pos); 1535 1533 1536 - if (size_changed) { 1534 + if (size_changed || inline_data) { 1537 1535 ret2 = ext4_mark_inode_dirty(handle, inode); 1538 1536 if (!ret) 1539 1537 ret = ret2; ··· 2030 2028 } 2031 2029 2032 2030 if (inline_data) { 2033 - BUFFER_TRACE(inode_bh, "get write access"); 2034 - ret = ext4_journal_get_write_access(handle, inode_bh); 2035 - 2036 - err = ext4_handle_dirty_metadata(handle, inode, inode_bh); 2037 - 2031 + ret = ext4_mark_inode_dirty(handle, inode); 2038 2032 } else { 2039 2033 ret = ext4_walk_page_buffers(handle, page_bufs, 0, len, NULL, 2040 2034 do_journal_get_write_access);
+2 -5
fs/ext4/mmp.c
··· 186 186 goto exit_thread; 187 187 } 188 188 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; 194 191 195 192 diff = jiffies - last_update_time; 196 193 if (diff < mmp_update_interval * HZ)
+5 -10
fs/ext4/super.c
··· 2342 2342 struct ext4_sb_info *sbi = EXT4_SB(sb); 2343 2343 ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); 2344 2344 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); 2346 2346 ext4_fsblk_t block_bitmap; 2347 2347 ext4_fsblk_t inode_bitmap; 2348 2348 ext4_fsblk_t inode_table; ··· 3141 3141 if (!gdp) 3142 3142 continue; 3143 3143 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))) 3147 3145 break; 3148 - ext4_error(sb, "Inode table for bg 0 marked as " 3149 - "needing zeroing"); 3150 - if (sb_rdonly(sb)) 3151 - return ngroups; 3152 3146 } 3153 3147 3154 3148 return group; ··· 4079 4085 goto failed_mount2; 4080 4086 } 4081 4087 } 4088 + sbi->s_gdb_count = db_count; 4082 4089 if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { 4083 4090 ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); 4084 4091 ret = -EFSCORRUPTED; 4085 4092 goto failed_mount2; 4086 4093 } 4087 - 4088 - sbi->s_gdb_count = db_count; 4089 4094 4090 4095 timer_setup(&sbi->s_err_report, print_daily_error_info, 0); 4091 4096 ··· 5206 5213 5207 5214 if (sbi->s_journal) 5208 5215 ext4_mark_recovery_complete(sb, es); 5216 + if (sbi->s_mmp_tsk) 5217 + kthread_stop(sbi->s_mmp_tsk); 5209 5218 } else { 5210 5219 /* Make sure we can mount this feature set readwrite */ 5211 5220 if (ext4_has_feature_readonly(sb) ||