Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
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 fixes from Ted Ts'o:
"A large number of ext4 bug fixes, mostly buffer and memory leaks on
error return cleanup paths"

* tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: missing !bh check in ext4_xattr_inode_write()
ext4: fix buffer leak in __ext4_read_dirblock() on error path
ext4: fix buffer leak in ext4_expand_extra_isize_ea() on error path
ext4: fix buffer leak in ext4_xattr_move_to_block() on error path
ext4: release bs.bh before re-using in ext4_xattr_block_find()
ext4: fix buffer leak in ext4_xattr_get_block() on error path
ext4: fix possible leak of s_journal_flag_rwsem in error path
ext4: fix possible leak of sbi->s_group_desc_leak in error path
ext4: remove unneeded brelse call in ext4_xattr_inode_update_ref()
ext4: avoid possible double brelse() in add_new_gdb() on error path
ext4: avoid buffer leak in ext4_orphan_add() after prior errors
ext4: avoid buffer leak on shutdown in ext4_mark_iloc_dirty()
ext4: fix possible inode leak in the retry loop of ext4_resize_fs()
ext4: fix missing cleanup if ext4_alloc_flex_bg_array() fails while resizing
ext4: add missing brelse() update_backups()'s error path
ext4: add missing brelse() add_new_gdb_meta_bg()'s error path
ext4: add missing brelse() in set_flexbg_block_bitmap()'s error path
ext4: avoid potential extra brelse in setup_new_flex_group_blocks()

+51 -31
+3 -2
fs/ext4/inode.c
··· 5835 5835 { 5836 5836 int err = 0; 5837 5837 5838 - if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) 5838 + if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) { 5839 + put_bh(iloc->bh); 5839 5840 return -EIO; 5840 - 5841 + } 5841 5842 if (IS_I_VERSION(inode)) 5842 5843 inode_inc_iversion(inode); 5843 5844
+4 -1
fs/ext4/namei.c
··· 126 126 if (!is_dx_block && type == INDEX) { 127 127 ext4_error_inode(inode, func, line, block, 128 128 "directory leaf block found instead of index block"); 129 + brelse(bh); 129 130 return ERR_PTR(-EFSCORRUPTED); 130 131 } 131 132 if (!ext4_has_metadata_csum(inode->i_sb) || ··· 2812 2811 list_del_init(&EXT4_I(inode)->i_orphan); 2813 2812 mutex_unlock(&sbi->s_orphan_lock); 2814 2813 } 2815 - } 2814 + } else 2815 + brelse(iloc.bh); 2816 + 2816 2817 jbd_debug(4, "superblock will point to %lu\n", inode->i_ino); 2817 2818 jbd_debug(4, "orphan inode %lu will point to %d\n", 2818 2819 inode->i_ino, NEXT_ORPHAN(inode));
+16 -12
fs/ext4/resize.c
··· 459 459 460 460 BUFFER_TRACE(bh, "get_write_access"); 461 461 err = ext4_journal_get_write_access(handle, bh); 462 - if (err) 462 + if (err) { 463 + brelse(bh); 463 464 return err; 465 + } 464 466 ext4_debug("mark block bitmap %#04llx (+%llu/%u)\n", 465 467 first_cluster, first_cluster - start, count2); 466 468 ext4_set_bits(bh->b_data, first_cluster - start, count2); 467 469 468 470 err = ext4_handle_dirty_metadata(handle, NULL, bh); 471 + brelse(bh); 469 472 if (unlikely(err)) 470 473 return err; 471 - brelse(bh); 472 474 } 473 475 474 476 return 0; ··· 607 605 bh = bclean(handle, sb, block); 608 606 if (IS_ERR(bh)) { 609 607 err = PTR_ERR(bh); 610 - bh = NULL; 611 608 goto out; 612 609 } 613 610 overhead = ext4_group_overhead_blocks(sb, group); ··· 619 618 ext4_mark_bitmap_end(EXT4_B2C(sbi, group_data[i].blocks_count), 620 619 sb->s_blocksize * 8, bh->b_data); 621 620 err = ext4_handle_dirty_metadata(handle, NULL, bh); 621 + brelse(bh); 622 622 if (err) 623 623 goto out; 624 - brelse(bh); 625 624 626 625 handle_ib: 627 626 if (bg_flags[i] & EXT4_BG_INODE_UNINIT) ··· 636 635 bh = bclean(handle, sb, block); 637 636 if (IS_ERR(bh)) { 638 637 err = PTR_ERR(bh); 639 - bh = NULL; 640 638 goto out; 641 639 } 642 640 643 641 ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), 644 642 sb->s_blocksize * 8, bh->b_data); 645 643 err = ext4_handle_dirty_metadata(handle, NULL, bh); 644 + brelse(bh); 646 645 if (err) 647 646 goto out; 648 - brelse(bh); 649 647 } 650 - bh = NULL; 651 648 652 649 /* Mark group tables in block bitmap */ 653 650 for (j = 0; j < GROUP_TABLE_COUNT; j++) { ··· 684 685 } 685 686 686 687 out: 687 - brelse(bh); 688 688 err2 = ext4_journal_stop(handle); 689 689 if (err2 && !err) 690 690 err = err2; ··· 871 873 err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh); 872 874 if (unlikely(err)) { 873 875 ext4_std_error(sb, err); 876 + iloc.bh = NULL; 874 877 goto exit_inode; 875 878 } 876 879 brelse(dind); ··· 923 924 sizeof(struct buffer_head *), 924 925 GFP_NOFS); 925 926 if (!n_group_desc) { 927 + brelse(gdb_bh); 926 928 err = -ENOMEM; 927 929 ext4_warning(sb, "not enough memory for %lu groups", 928 930 gdb_num + 1); ··· 939 939 kvfree(o_group_desc); 940 940 BUFFER_TRACE(gdb_bh, "get_write_access"); 941 941 err = ext4_journal_get_write_access(handle, gdb_bh); 942 - if (unlikely(err)) 943 - brelse(gdb_bh); 944 942 return err; 945 943 } 946 944 ··· 1122 1124 backup_block, backup_block - 1123 1125 ext4_group_first_block_no(sb, group)); 1124 1126 BUFFER_TRACE(bh, "get_write_access"); 1125 - if ((err = ext4_journal_get_write_access(handle, bh))) 1127 + if ((err = ext4_journal_get_write_access(handle, bh))) { 1128 + brelse(bh); 1126 1129 break; 1130 + } 1127 1131 lock_buffer(bh); 1128 1132 memcpy(bh->b_data, data, size); 1129 1133 if (rest) ··· 2023 2023 2024 2024 err = ext4_alloc_flex_bg_array(sb, n_group + 1); 2025 2025 if (err) 2026 - return err; 2026 + goto out; 2027 2027 2028 2028 err = ext4_mb_alloc_groupinfo(sb, n_group + 1); 2029 2029 if (err) ··· 2059 2059 n_blocks_count_retry = 0; 2060 2060 free_flex_gd(flex_gd); 2061 2061 flex_gd = NULL; 2062 + if (resize_inode) { 2063 + iput(resize_inode); 2064 + resize_inode = NULL; 2065 + } 2062 2066 goto retry; 2063 2067 } 2064 2068
+9 -8
fs/ext4/super.c
··· 4075 4075 sbi->s_groups_count = blocks_count; 4076 4076 sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count, 4077 4077 (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); 4078 + if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) != 4079 + le32_to_cpu(es->s_inodes_count)) { 4080 + ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu", 4081 + le32_to_cpu(es->s_inodes_count), 4082 + ((u64)sbi->s_groups_count * sbi->s_inodes_per_group)); 4083 + ret = -EINVAL; 4084 + goto failed_mount; 4085 + } 4078 4086 db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / 4079 4087 EXT4_DESC_PER_BLOCK(sb); 4080 4088 if (ext4_has_feature_meta_bg(sb)) { ··· 4100 4092 if (sbi->s_group_desc == NULL) { 4101 4093 ext4_msg(sb, KERN_ERR, "not enough memory"); 4102 4094 ret = -ENOMEM; 4103 - goto failed_mount; 4104 - } 4105 - if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) != 4106 - le32_to_cpu(es->s_inodes_count)) { 4107 - ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu", 4108 - le32_to_cpu(es->s_inodes_count), 4109 - ((u64)sbi->s_groups_count * sbi->s_inodes_per_group)); 4110 - ret = -EINVAL; 4111 4095 goto failed_mount; 4112 4096 } 4113 4097 ··· 4510 4510 percpu_counter_destroy(&sbi->s_freeinodes_counter); 4511 4511 percpu_counter_destroy(&sbi->s_dirs_counter); 4512 4512 percpu_counter_destroy(&sbi->s_dirtyclusters_counter); 4513 + percpu_free_rwsem(&sbi->s_journal_flag_rwsem); 4513 4514 failed_mount5: 4514 4515 ext4_ext_release(sb); 4515 4516 ext4_release_system_zone(sb);
+19 -8
fs/ext4/xattr.c
··· 1031 1031 inode_lock(ea_inode); 1032 1032 1033 1033 ret = ext4_reserve_inode_write(handle, ea_inode, &iloc); 1034 - if (ret) { 1035 - iloc.bh = NULL; 1034 + if (ret) 1036 1035 goto out; 1037 - } 1038 1036 1039 1037 ref_count = ext4_xattr_inode_get_ref(ea_inode); 1040 1038 ref_count += ref_change; ··· 1078 1080 } 1079 1081 1080 1082 ret = ext4_mark_iloc_dirty(handle, ea_inode, &iloc); 1081 - iloc.bh = NULL; 1082 1083 if (ret) 1083 1084 ext4_warning_inode(ea_inode, 1084 1085 "ext4_mark_iloc_dirty() failed ret=%d", ret); 1085 1086 out: 1086 - brelse(iloc.bh); 1087 1087 inode_unlock(ea_inode); 1088 1088 return ret; 1089 1089 } ··· 1384 1388 bh = ext4_getblk(handle, ea_inode, block, 0); 1385 1389 if (IS_ERR(bh)) 1386 1390 return PTR_ERR(bh); 1391 + if (!bh) { 1392 + WARN_ON_ONCE(1); 1393 + EXT4_ERROR_INODE(ea_inode, 1394 + "ext4_getblk() return bh = NULL"); 1395 + return -EFSCORRUPTED; 1396 + } 1387 1397 ret = ext4_journal_get_write_access(handle, bh); 1388 1398 if (ret) 1389 1399 goto out; ··· 2278 2276 if (!bh) 2279 2277 return ERR_PTR(-EIO); 2280 2278 error = ext4_xattr_check_block(inode, bh); 2281 - if (error) 2279 + if (error) { 2280 + brelse(bh); 2282 2281 return ERR_PTR(error); 2282 + } 2283 2283 return bh; 2284 2284 } 2285 2285 ··· 2401 2397 error = ext4_xattr_block_set(handle, inode, &i, &bs); 2402 2398 } else if (error == -ENOSPC) { 2403 2399 if (EXT4_I(inode)->i_file_acl && !bs.s.base) { 2400 + brelse(bs.bh); 2401 + bs.bh = NULL; 2404 2402 error = ext4_xattr_block_find(inode, &i, &bs); 2405 2403 if (error) 2406 2404 goto cleanup; ··· 2623 2617 kfree(buffer); 2624 2618 if (is) 2625 2619 brelse(is->iloc.bh); 2620 + if (bs) 2621 + brelse(bs->bh); 2626 2622 kfree(is); 2627 2623 kfree(bs); 2628 2624 ··· 2704 2696 struct ext4_inode *raw_inode, handle_t *handle) 2705 2697 { 2706 2698 struct ext4_xattr_ibody_header *header; 2707 - struct buffer_head *bh; 2708 2699 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 2709 2700 static unsigned int mnt_count; 2710 2701 size_t min_offs; ··· 2744 2737 * EA block can hold new_extra_isize bytes. 2745 2738 */ 2746 2739 if (EXT4_I(inode)->i_file_acl) { 2740 + struct buffer_head *bh; 2741 + 2747 2742 bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); 2748 2743 error = -EIO; 2749 2744 if (!bh) 2750 2745 goto cleanup; 2751 2746 error = ext4_xattr_check_block(inode, bh); 2752 - if (error) 2747 + if (error) { 2748 + brelse(bh); 2753 2749 goto cleanup; 2750 + } 2754 2751 base = BHDR(bh); 2755 2752 end = bh->b_data + bh->b_size; 2756 2753 min_offs = end - base;