Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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:
"Bug fixes for ext4; most of which relate to vulnerabilities where a
maliciously crafted file system image can result in a kernel OOPS or
hang.

At least one fix addresses an inline data bug could be triggered by
userspace without the need of a crafted file system (although it does
require that the inline data feature be enabled)"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: check superblock mapped prior to committing
ext4: add more mount time checks of the superblock
ext4: add more inode number paranoia checks
ext4: avoid running out of journal credits when appending to an inline file
jbd2: don't mark block as modified if the handle is out of credits
ext4: never move the system.data xattr out of the inode body
ext4: clear i_data in ext4_inode_info when removing inline data
ext4: include the illegal physical block in the bad map ext4_error msg
ext4: verify the depth of extent tree in ext4_find_extent()
ext4: only look at the bg_flags field if it is valid
ext4: make sure bitmaps and the inode table don't overlap with bg descriptors
ext4: always check block group bounds in ext4_init_block_bitmap()
ext4: always verify the magic number in xattr blocks
ext4: add corruption check in ext4_xattr_set_entry()
ext4: add warn_on_error mount option

+155 -96
+13 -8
fs/ext4/balloc.c
··· 184 184 unsigned int bit, bit_max; 185 185 struct ext4_sb_info *sbi = EXT4_SB(sb); 186 186 ext4_fsblk_t start, tmp; 187 - int flex_bg = 0; 188 187 189 188 J_ASSERT_BH(bh, buffer_locked(bh)); 190 189 ··· 206 207 207 208 start = ext4_group_first_block_no(sb, block_group); 208 209 209 - if (ext4_has_feature_flex_bg(sb)) 210 - flex_bg = 1; 211 - 212 210 /* Set bits for block and inode bitmaps, and inode table */ 213 211 tmp = ext4_block_bitmap(sb, gdp); 214 - if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) 212 + if (ext4_block_in_group(sb, tmp, block_group)) 215 213 ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); 216 214 217 215 tmp = ext4_inode_bitmap(sb, gdp); 218 - if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) 216 + if (ext4_block_in_group(sb, tmp, block_group)) 219 217 ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); 220 218 221 219 tmp = ext4_inode_table(sb, gdp); 222 220 for (; tmp < ext4_inode_table(sb, gdp) + 223 221 sbi->s_itb_per_group; tmp++) { 224 - if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) 222 + if (ext4_block_in_group(sb, tmp, block_group)) 225 223 ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); 226 224 } 227 225 ··· 438 442 goto verify; 439 443 } 440 444 ext4_lock_group(sb, block_group); 441 - if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 445 + if (ext4_has_group_desc_csum(sb) && 446 + (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { 447 + if (block_group == 0) { 448 + ext4_unlock_group(sb, block_group); 449 + unlock_buffer(bh); 450 + ext4_error(sb, "Block bitmap for bg 0 marked " 451 + "uninitialized"); 452 + err = -EFSCORRUPTED; 453 + goto out; 454 + } 442 455 err = ext4_init_block_bitmap(sb, bh, block_group, desc); 443 456 set_bitmap_uptodate(bh); 444 457 set_buffer_uptodate(bh);
+1 -8
fs/ext4/ext4.h
··· 1114 1114 #define EXT4_MOUNT_DIOREAD_NOLOCK 0x400000 /* Enable support for dio read nolocking */ 1115 1115 #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ 1116 1116 #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ 1117 + #define EXT4_MOUNT_WARN_ON_ERROR 0x2000000 /* Trigger WARN_ON on error */ 1117 1118 #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ 1118 1119 #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ 1119 1120 #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ ··· 1508 1507 static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) 1509 1508 { 1510 1509 return ino == EXT4_ROOT_INO || 1511 - ino == EXT4_USR_QUOTA_INO || 1512 - ino == EXT4_GRP_QUOTA_INO || 1513 - ino == EXT4_BOOT_LOADER_INO || 1514 - ino == EXT4_JOURNAL_INO || 1515 - ino == EXT4_RESIZE_INO || 1516 1510 (ino >= EXT4_FIRST_INO(sb) && 1517 1511 ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)); 1518 1512 } ··· 3014 3018 struct iomap; 3015 3019 extern int ext4_inline_data_iomap(struct inode *inode, struct iomap *iomap); 3016 3020 3017 - extern int ext4_try_to_evict_inline_data(handle_t *handle, 3018 - struct inode *inode, 3019 - int needed); 3020 3021 extern int ext4_inline_data_truncate(struct inode *inode, int *has_inline); 3021 3022 3022 3023 extern int ext4_convert_inline_data(struct inode *inode);
+1
fs/ext4/ext4_extents.h
··· 91 91 }; 92 92 93 93 #define EXT4_EXT_MAGIC cpu_to_le16(0xf30a) 94 + #define EXT4_MAX_EXTENT_DEPTH 5 94 95 95 96 #define EXT4_EXTENT_TAIL_OFFSET(hdr) \ 96 97 (sizeof(struct ext4_extent_header) + \
+6
fs/ext4/extents.c
··· 869 869 870 870 eh = ext_inode_hdr(inode); 871 871 depth = ext_depth(inode); 872 + if (depth < 0 || depth > EXT4_MAX_EXTENT_DEPTH) { 873 + EXT4_ERROR_INODE(inode, "inode has invalid extent depth: %d", 874 + depth); 875 + ret = -EFSCORRUPTED; 876 + goto err; 877 + } 872 878 873 879 if (path) { 874 880 ext4_ext_drop_refs(path);
+12 -2
fs/ext4/ialloc.c
··· 150 150 } 151 151 152 152 ext4_lock_group(sb, block_group); 153 - if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { 153 + if (ext4_has_group_desc_csum(sb) && 154 + (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT))) { 155 + if (block_group == 0) { 156 + ext4_unlock_group(sb, block_group); 157 + unlock_buffer(bh); 158 + ext4_error(sb, "Inode bitmap for bg 0 marked " 159 + "uninitialized"); 160 + err = -EFSCORRUPTED; 161 + goto out; 162 + } 154 163 memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); 155 164 ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), 156 165 sb->s_blocksize * 8, bh->b_data); ··· 1003 994 1004 995 /* recheck and clear flag under lock if we still need to */ 1005 996 ext4_lock_group(sb, group); 1006 - if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 997 + if (ext4_has_group_desc_csum(sb) && 998 + (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { 1007 999 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); 1008 1000 ext4_free_group_clusters_set(sb, gdp, 1009 1001 ext4_free_clusters_after_init(sb, group, gdp));
+2 -37
fs/ext4/inline.c
··· 437 437 438 438 memset((void *)ext4_raw_inode(&is.iloc)->i_block, 439 439 0, EXT4_MIN_INLINE_DATA_SIZE); 440 + memset(ei->i_data, 0, EXT4_MIN_INLINE_DATA_SIZE); 440 441 441 442 if (ext4_has_feature_extents(inode->i_sb)) { 442 443 if (S_ISDIR(inode->i_mode) || ··· 887 886 flags |= AOP_FLAG_NOFS; 888 887 889 888 if (ret == -ENOSPC) { 889 + ext4_journal_stop(handle); 890 890 ret = ext4_da_convert_inline_data_to_extent(mapping, 891 891 inode, 892 892 flags, 893 893 fsdata); 894 - ext4_journal_stop(handle); 895 894 if (ret == -ENOSPC && 896 895 ext4_should_retry_alloc(inode->i_sb, &retries)) 897 896 goto retry_journal; ··· 1889 1888 out: 1890 1889 up_read(&EXT4_I(inode)->xattr_sem); 1891 1890 return (error < 0 ? error : 0); 1892 - } 1893 - 1894 - /* 1895 - * Called during xattr set, and if we can sparse space 'needed', 1896 - * just create the extent tree evict the data to the outer block. 1897 - * 1898 - * We use jbd2 instead of page cache to move data to the 1st block 1899 - * so that the whole transaction can be committed as a whole and 1900 - * the data isn't lost because of the delayed page cache write. 1901 - */ 1902 - int ext4_try_to_evict_inline_data(handle_t *handle, 1903 - struct inode *inode, 1904 - int needed) 1905 - { 1906 - int error; 1907 - struct ext4_xattr_entry *entry; 1908 - struct ext4_inode *raw_inode; 1909 - struct ext4_iloc iloc; 1910 - 1911 - error = ext4_get_inode_loc(inode, &iloc); 1912 - if (error) 1913 - return error; 1914 - 1915 - raw_inode = ext4_raw_inode(&iloc); 1916 - entry = (struct ext4_xattr_entry *)((void *)raw_inode + 1917 - EXT4_I(inode)->i_inline_off); 1918 - if (EXT4_XATTR_LEN(entry->e_name_len) + 1919 - EXT4_XATTR_SIZE(le32_to_cpu(entry->e_value_size)) < needed) { 1920 - error = -ENOSPC; 1921 - goto out; 1922 - } 1923 - 1924 - error = ext4_convert_inline_data_nolock(handle, inode, &iloc); 1925 - out: 1926 - brelse(iloc.bh); 1927 - return error; 1928 1891 } 1929 1892 1930 1893 int ext4_inline_data_truncate(struct inode *inode, int *has_inline)
+4 -3
fs/ext4/inode.c
··· 402 402 if (!ext4_data_block_valid(EXT4_SB(inode->i_sb), map->m_pblk, 403 403 map->m_len)) { 404 404 ext4_error_inode(inode, func, line, map->m_pblk, 405 - "lblock %lu mapped to illegal pblock " 405 + "lblock %lu mapped to illegal pblock %llu " 406 406 "(length %d)", (unsigned long) map->m_lblk, 407 - map->m_len); 407 + map->m_pblk, map->m_len); 408 408 return -EFSCORRUPTED; 409 409 } 410 410 return 0; ··· 4506 4506 int inodes_per_block, inode_offset; 4507 4507 4508 4508 iloc->bh = NULL; 4509 - if (!ext4_valid_inum(sb, inode->i_ino)) 4509 + if (inode->i_ino < EXT4_ROOT_INO || 4510 + inode->i_ino > le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)) 4510 4511 return -EFSCORRUPTED; 4511 4512 4512 4513 iloc->block_group = (inode->i_ino - 1) / EXT4_INODES_PER_GROUP(sb);
+4 -2
fs/ext4/mballoc.c
··· 2423 2423 * initialize bb_free to be able to skip 2424 2424 * empty groups without initialization 2425 2425 */ 2426 - if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 2426 + if (ext4_has_group_desc_csum(sb) && 2427 + (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { 2427 2428 meta_group_info[i]->bb_free = 2428 2429 ext4_free_clusters_after_init(sb, group, desc); 2429 2430 } else { ··· 2990 2989 #endif 2991 2990 ext4_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start, 2992 2991 ac->ac_b_ex.fe_len); 2993 - if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 2992 + if (ext4_has_group_desc_csum(sb) && 2993 + (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) { 2994 2994 gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); 2995 2995 ext4_free_group_clusters_set(sb, gdp, 2996 2996 ext4_free_clusters_after_init(sb,
+86 -13
fs/ext4/super.c
··· 405 405 406 406 static void ext4_handle_error(struct super_block *sb) 407 407 { 408 + if (test_opt(sb, WARN_ON_ERROR)) 409 + WARN_ON_ONCE(1); 410 + 408 411 if (sb_rdonly(sb)) 409 412 return; 410 413 ··· 742 739 printk(KERN_CONT "%pV\n", &vaf); 743 740 va_end(args); 744 741 } 742 + 743 + if (test_opt(sb, WARN_ON_ERROR)) 744 + WARN_ON_ONCE(1); 745 745 746 746 if (test_opt(sb, ERRORS_CONT)) { 747 747 ext4_commit_super(sb, 0); ··· 1377 1371 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, 1378 1372 Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, 1379 1373 Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version, Opt_dax, 1380 - Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, 1374 + Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_warn_on_error, 1375 + Opt_nowarn_on_error, Opt_mblk_io_submit, 1381 1376 Opt_lazytime, Opt_nolazytime, Opt_debug_want_extra_isize, 1382 1377 Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, 1383 1378 Opt_inode_readahead_blks, Opt_journal_ioprio, ··· 1445 1438 {Opt_dax, "dax"}, 1446 1439 {Opt_stripe, "stripe=%u"}, 1447 1440 {Opt_delalloc, "delalloc"}, 1441 + {Opt_warn_on_error, "warn_on_error"}, 1442 + {Opt_nowarn_on_error, "nowarn_on_error"}, 1448 1443 {Opt_lazytime, "lazytime"}, 1449 1444 {Opt_nolazytime, "nolazytime"}, 1450 1445 {Opt_debug_want_extra_isize, "debug_want_extra_isize=%u"}, ··· 1611 1602 MOPT_EXT4_ONLY | MOPT_SET | MOPT_EXPLICIT}, 1612 1603 {Opt_nodelalloc, EXT4_MOUNT_DELALLOC, 1613 1604 MOPT_EXT4_ONLY | MOPT_CLEAR}, 1605 + {Opt_warn_on_error, EXT4_MOUNT_WARN_ON_ERROR, MOPT_SET}, 1606 + {Opt_nowarn_on_error, EXT4_MOUNT_WARN_ON_ERROR, MOPT_CLEAR}, 1614 1607 {Opt_nojournal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, 1615 1608 MOPT_EXT4_ONLY | MOPT_CLEAR}, 1616 1609 {Opt_journal_checksum, EXT4_MOUNT_JOURNAL_CHECKSUM, ··· 2342 2331 struct ext4_sb_info *sbi = EXT4_SB(sb); 2343 2332 ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); 2344 2333 ext4_fsblk_t last_block; 2334 + ext4_fsblk_t last_bg_block = sb_block + ext4_bg_num_gdb(sb, 0) + 1; 2345 2335 ext4_fsblk_t block_bitmap; 2346 2336 ext4_fsblk_t inode_bitmap; 2347 2337 ext4_fsblk_t inode_table; ··· 2375 2363 if (!sb_rdonly(sb)) 2376 2364 return 0; 2377 2365 } 2366 + if (block_bitmap >= sb_block + 1 && 2367 + block_bitmap <= last_bg_block) { 2368 + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " 2369 + "Block bitmap for group %u overlaps " 2370 + "block group descriptors", i); 2371 + if (!sb_rdonly(sb)) 2372 + return 0; 2373 + } 2378 2374 if (block_bitmap < first_block || block_bitmap > last_block) { 2379 2375 ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " 2380 2376 "Block bitmap for group %u not in group " ··· 2397 2377 if (!sb_rdonly(sb)) 2398 2378 return 0; 2399 2379 } 2380 + if (inode_bitmap >= sb_block + 1 && 2381 + inode_bitmap <= last_bg_block) { 2382 + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " 2383 + "Inode bitmap for group %u overlaps " 2384 + "block group descriptors", i); 2385 + if (!sb_rdonly(sb)) 2386 + return 0; 2387 + } 2400 2388 if (inode_bitmap < first_block || inode_bitmap > last_block) { 2401 2389 ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " 2402 2390 "Inode bitmap for group %u not in group " ··· 2416 2388 ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " 2417 2389 "Inode table for group %u overlaps " 2418 2390 "superblock", i); 2391 + if (!sb_rdonly(sb)) 2392 + return 0; 2393 + } 2394 + if (inode_table >= sb_block + 1 && 2395 + inode_table <= last_bg_block) { 2396 + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " 2397 + "Inode table for group %u overlaps " 2398 + "block group descriptors", i); 2419 2399 if (!sb_rdonly(sb)) 2420 2400 return 0; 2421 2401 } ··· 3133 3097 ext4_group_t group, ngroups = EXT4_SB(sb)->s_groups_count; 3134 3098 struct ext4_group_desc *gdp = NULL; 3135 3099 3100 + if (!ext4_has_group_desc_csum(sb)) 3101 + return ngroups; 3102 + 3136 3103 for (group = 0; group < ngroups; group++) { 3137 3104 gdp = ext4_get_group_desc(sb, group, NULL); 3138 3105 if (!gdp) 3139 3106 continue; 3140 3107 3141 - if (!(gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED))) 3108 + if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_ZEROED)) 3109 + continue; 3110 + if (group != 0) 3142 3111 break; 3112 + ext4_error(sb, "Inode table for bg 0 marked as " 3113 + "needing zeroing"); 3114 + if (sb_rdonly(sb)) 3115 + return ngroups; 3143 3116 } 3144 3117 3145 3118 return group; ··· 3787 3742 le32_to_cpu(es->s_log_block_size)); 3788 3743 goto failed_mount; 3789 3744 } 3745 + if (le32_to_cpu(es->s_log_cluster_size) > 3746 + (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { 3747 + ext4_msg(sb, KERN_ERR, 3748 + "Invalid log cluster size: %u", 3749 + le32_to_cpu(es->s_log_cluster_size)); 3750 + goto failed_mount; 3751 + } 3790 3752 3791 3753 if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) { 3792 3754 ext4_msg(sb, KERN_ERR, ··· 3858 3806 } else { 3859 3807 sbi->s_inode_size = le16_to_cpu(es->s_inode_size); 3860 3808 sbi->s_first_ino = le32_to_cpu(es->s_first_ino); 3809 + if (sbi->s_first_ino < EXT4_GOOD_OLD_FIRST_INO) { 3810 + ext4_msg(sb, KERN_ERR, "invalid first ino: %u", 3811 + sbi->s_first_ino); 3812 + goto failed_mount; 3813 + } 3861 3814 if ((sbi->s_inode_size < EXT4_GOOD_OLD_INODE_SIZE) || 3862 3815 (!is_power_of_2(sbi->s_inode_size)) || 3863 3816 (sbi->s_inode_size > blocksize)) { ··· 3939 3882 "block size (%d)", clustersize, blocksize); 3940 3883 goto failed_mount; 3941 3884 } 3942 - if (le32_to_cpu(es->s_log_cluster_size) > 3943 - (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) { 3944 - ext4_msg(sb, KERN_ERR, 3945 - "Invalid log cluster size: %u", 3946 - le32_to_cpu(es->s_log_cluster_size)); 3947 - goto failed_mount; 3948 - } 3949 3885 sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) - 3950 3886 le32_to_cpu(es->s_log_block_size); 3951 3887 sbi->s_clusters_per_group = ··· 3959 3909 } 3960 3910 } else { 3961 3911 if (clustersize != blocksize) { 3962 - ext4_warning(sb, "fragment/cluster size (%d) != " 3963 - "block size (%d)", clustersize, 3964 - blocksize); 3965 - clustersize = blocksize; 3912 + ext4_msg(sb, KERN_ERR, 3913 + "fragment/cluster size (%d) != " 3914 + "block size (%d)", clustersize, blocksize); 3915 + goto failed_mount; 3966 3916 } 3967 3917 if (sbi->s_blocks_per_group > blocksize * 8) { 3968 3918 ext4_msg(sb, KERN_ERR, ··· 4016 3966 ext4_blocks_count(es)); 4017 3967 goto failed_mount; 4018 3968 } 3969 + if ((es->s_first_data_block == 0) && (es->s_log_block_size == 0) && 3970 + (sbi->s_cluster_ratio == 1)) { 3971 + ext4_msg(sb, KERN_WARNING, "bad geometry: first data " 3972 + "block is 0 with a 1k block and cluster size"); 3973 + goto failed_mount; 3974 + } 3975 + 4019 3976 blocks_count = (ext4_blocks_count(es) - 4020 3977 le32_to_cpu(es->s_first_data_block) + 4021 3978 EXT4_BLOCKS_PER_GROUP(sb) - 1); ··· 4056 3999 if (sbi->s_group_desc == NULL) { 4057 4000 ext4_msg(sb, KERN_ERR, "not enough memory"); 4058 4001 ret = -ENOMEM; 4002 + goto failed_mount; 4003 + } 4004 + if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) != 4005 + le32_to_cpu(es->s_inodes_count)) { 4006 + ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu", 4007 + le32_to_cpu(es->s_inodes_count), 4008 + ((u64)sbi->s_groups_count * sbi->s_inodes_per_group)); 4009 + ret = -EINVAL; 4059 4010 goto failed_mount; 4060 4011 } 4061 4012 ··· 4801 4736 4802 4737 if (!sbh || block_device_ejected(sb)) 4803 4738 return error; 4739 + 4740 + /* 4741 + * The superblock bh should be mapped, but it might not be if the 4742 + * device was hot-removed. Not much we can do but fail the I/O. 4743 + */ 4744 + if (!buffer_mapped(sbh)) 4745 + return error; 4746 + 4804 4747 /* 4805 4748 * If the file system is mounted read-only, don't update the 4806 4749 * superblock write time. This avoids updating the superblock
+18 -22
fs/ext4/xattr.c
··· 230 230 { 231 231 int error = -EFSCORRUPTED; 232 232 233 - if (buffer_verified(bh)) 234 - return 0; 235 - 236 233 if (BHDR(bh)->h_magic != cpu_to_le32(EXT4_XATTR_MAGIC) || 237 234 BHDR(bh)->h_blocks != cpu_to_le32(1)) 238 235 goto errout; 236 + if (buffer_verified(bh)) 237 + return 0; 238 + 239 239 error = -EFSBADCRC; 240 240 if (!ext4_xattr_block_csum_verify(inode, bh)) 241 241 goto errout; ··· 1560 1560 handle_t *handle, struct inode *inode, 1561 1561 bool is_block) 1562 1562 { 1563 - struct ext4_xattr_entry *last; 1563 + struct ext4_xattr_entry *last, *next; 1564 1564 struct ext4_xattr_entry *here = s->here; 1565 1565 size_t min_offs = s->end - s->base, name_len = strlen(i->name); 1566 1566 int in_inode = i->in_inode; ··· 1595 1595 1596 1596 /* Compute min_offs and last. */ 1597 1597 last = s->first; 1598 - for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { 1598 + for (; !IS_LAST_ENTRY(last); last = next) { 1599 + next = EXT4_XATTR_NEXT(last); 1600 + if ((void *)next >= s->end) { 1601 + EXT4_ERROR_INODE(inode, "corrupted xattr entries"); 1602 + ret = -EFSCORRUPTED; 1603 + goto out; 1604 + } 1599 1605 if (!last->e_value_inum && last->e_value_size) { 1600 1606 size_t offs = le16_to_cpu(last->e_value_offs); 1601 1607 if (offs < min_offs) ··· 2212 2206 if (EXT4_I(inode)->i_extra_isize == 0) 2213 2207 return -ENOSPC; 2214 2208 error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */); 2215 - if (error) { 2216 - if (error == -ENOSPC && 2217 - ext4_has_inline_data(inode)) { 2218 - error = ext4_try_to_evict_inline_data(handle, inode, 2219 - EXT4_XATTR_LEN(strlen(i->name) + 2220 - EXT4_XATTR_SIZE(i->value_len))); 2221 - if (error) 2222 - return error; 2223 - error = ext4_xattr_ibody_find(inode, i, is); 2224 - if (error) 2225 - return error; 2226 - error = ext4_xattr_set_entry(i, s, handle, inode, 2227 - false /* is_block */); 2228 - } 2229 - if (error) 2230 - return error; 2231 - } 2209 + if (error) 2210 + return error; 2232 2211 header = IHDR(inode, ext4_raw_inode(&is->iloc)); 2233 2212 if (!IS_LAST_ENTRY(s->first)) { 2234 2213 header->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); ··· 2642 2651 last = IFIRST(header); 2643 2652 /* Find the entry best suited to be pushed into EA block */ 2644 2653 for (; !IS_LAST_ENTRY(last); last = EXT4_XATTR_NEXT(last)) { 2654 + /* never move system.data out of the inode */ 2655 + if ((last->e_name_len == 4) && 2656 + (last->e_name_index == EXT4_XATTR_INDEX_SYSTEM) && 2657 + !memcmp(last->e_name, "data", 4)) 2658 + continue; 2645 2659 total_size = EXT4_XATTR_LEN(last->e_name_len); 2646 2660 if (!last->e_value_inum) 2647 2661 total_size += EXT4_XATTR_SIZE(
+8 -1
fs/jbd2/transaction.c
··· 1361 1361 if (jh->b_transaction == transaction && 1362 1362 jh->b_jlist != BJ_Metadata) { 1363 1363 jbd_lock_bh_state(bh); 1364 + if (jh->b_transaction == transaction && 1365 + jh->b_jlist != BJ_Metadata) 1366 + pr_err("JBD2: assertion failure: h_type=%u " 1367 + "h_line_no=%u block_no=%llu jlist=%u\n", 1368 + handle->h_type, handle->h_line_no, 1369 + (unsigned long long) bh->b_blocknr, 1370 + jh->b_jlist); 1364 1371 J_ASSERT_JH(jh, jh->b_transaction != transaction || 1365 1372 jh->b_jlist == BJ_Metadata); 1366 1373 jbd_unlock_bh_state(bh); ··· 1387 1380 * of the transaction. This needs to be done 1388 1381 * once a transaction -bzzz 1389 1382 */ 1390 - jh->b_modified = 1; 1391 1383 if (handle->h_buffer_credits <= 0) { 1392 1384 ret = -ENOSPC; 1393 1385 goto out_unlock_bh; 1394 1386 } 1387 + jh->b_modified = 1; 1395 1388 handle->h_buffer_credits--; 1396 1389 } 1397 1390