diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 68640e6f95c5..bd8831bfbafe 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -793,6 +793,7 @@ static void ext4_put_super(struct super_block *sb) | |||
793 | { | 793 | { |
794 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 794 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
795 | struct ext4_super_block *es = sbi->s_es; | 795 | struct ext4_super_block *es = sbi->s_es; |
796 | int aborted = 0; | ||
796 | int i, err; | 797 | int i, err; |
797 | 798 | ||
798 | ext4_unregister_li_request(sb); | 799 | ext4_unregister_li_request(sb); |
@@ -802,9 +803,10 @@ static void ext4_put_super(struct super_block *sb) | |||
802 | destroy_workqueue(sbi->rsv_conversion_wq); | 803 | destroy_workqueue(sbi->rsv_conversion_wq); |
803 | 804 | ||
804 | if (sbi->s_journal) { | 805 | if (sbi->s_journal) { |
806 | aborted = is_journal_aborted(sbi->s_journal); | ||
805 | err = jbd2_journal_destroy(sbi->s_journal); | 807 | err = jbd2_journal_destroy(sbi->s_journal); |
806 | sbi->s_journal = NULL; | 808 | sbi->s_journal = NULL; |
807 | if (err < 0) | 809 | if ((err < 0) && !aborted) |
808 | ext4_abort(sb, "Couldn't clean up the journal"); | 810 | ext4_abort(sb, "Couldn't clean up the journal"); |
809 | } | 811 | } |
810 | 812 | ||
@@ -814,9 +816,8 @@ static void ext4_put_super(struct super_block *sb) | |||
814 | ext4_release_system_zone(sb); | 816 | ext4_release_system_zone(sb); |
815 | ext4_mb_release(sb); | 817 | ext4_mb_release(sb); |
816 | ext4_ext_release(sb); | 818 | ext4_ext_release(sb); |
817 | ext4_xattr_put_super(sb); | ||
818 | 819 | ||
819 | if (!(sb->s_flags & MS_RDONLY)) { | 820 | if (!(sb->s_flags & MS_RDONLY) && !aborted) { |
820 | ext4_clear_feature_journal_needs_recovery(sb); | 821 | ext4_clear_feature_journal_needs_recovery(sb); |
821 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 822 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
822 | } | 823 | } |
@@ -3663,6 +3664,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3663 | (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); | 3664 | (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); |
3664 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / | 3665 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / |
3665 | EXT4_DESC_PER_BLOCK(sb); | 3666 | EXT4_DESC_PER_BLOCK(sb); |
3667 | if (ext4_has_feature_meta_bg(sb)) { | ||
3668 | if (le32_to_cpu(es->s_first_meta_bg) > db_count) { | ||
3669 | ext4_msg(sb, KERN_WARNING, | ||
3670 | "first meta block group too large: %u " | ||
3671 | "(group descriptor block count %u)", | ||
3672 | le32_to_cpu(es->s_first_meta_bg), db_count); | ||
3673 | goto failed_mount; | ||
3674 | } | ||
3675 | } | ||
3666 | sbi->s_group_desc = ext4_kvmalloc(db_count * | 3676 | sbi->s_group_desc = ext4_kvmalloc(db_count * |
3667 | sizeof(struct buffer_head *), | 3677 | sizeof(struct buffer_head *), |
3668 | GFP_KERNEL); | 3678 | GFP_KERNEL); |
@@ -3737,7 +3747,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3737 | * root first: it may be modified in the journal! | 3747 | * root first: it may be modified in the journal! |
3738 | */ | 3748 | */ |
3739 | if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) { | 3749 | if (!test_opt(sb, NOLOAD) && ext4_has_feature_journal(sb)) { |
3740 | if (ext4_load_journal(sb, es, journal_devnum)) | 3750 | err = ext4_load_journal(sb, es, journal_devnum); |
3751 | if (err) | ||
3741 | goto failed_mount3a; | 3752 | goto failed_mount3a; |
3742 | } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && | 3753 | } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && |
3743 | ext4_has_feature_journal_needs_recovery(sb)) { | 3754 | ext4_has_feature_journal_needs_recovery(sb)) { |
@@ -3821,7 +3832,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3821 | 3832 | ||
3822 | no_journal: | 3833 | no_journal: |
3823 | if (ext4_mballoc_ready) { | 3834 | if (ext4_mballoc_ready) { |
3824 | sbi->s_mb_cache = ext4_xattr_create_cache(sb->s_id); | 3835 | sbi->s_mb_cache = ext4_xattr_create_cache(); |
3825 | if (!sbi->s_mb_cache) { | 3836 | if (!sbi->s_mb_cache) { |
3826 | ext4_msg(sb, KERN_ERR, "Failed to create an mb_cache"); | 3837 | ext4_msg(sb, KERN_ERR, "Failed to create an mb_cache"); |
3827 | goto failed_mount_wq; | 3838 | goto failed_mount_wq; |
@@ -4053,6 +4064,10 @@ failed_mount4: | |||
4053 | if (EXT4_SB(sb)->rsv_conversion_wq) | 4064 | if (EXT4_SB(sb)->rsv_conversion_wq) |
4054 | destroy_workqueue(EXT4_SB(sb)->rsv_conversion_wq); | 4065 | destroy_workqueue(EXT4_SB(sb)->rsv_conversion_wq); |
4055 | failed_mount_wq: | 4066 | failed_mount_wq: |
4067 | if (sbi->s_mb_cache) { | ||
4068 | ext4_xattr_destroy_cache(sbi->s_mb_cache); | ||
4069 | sbi->s_mb_cache = NULL; | ||
4070 | } | ||
4056 | if (sbi->s_journal) { | 4071 | if (sbi->s_journal) { |
4057 | jbd2_journal_destroy(sbi->s_journal); | 4072 | jbd2_journal_destroy(sbi->s_journal); |
4058 | sbi->s_journal = NULL; | 4073 | sbi->s_journal = NULL; |