diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 118 |
1 files changed, 87 insertions, 31 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index d4ca92aab514..8b58a144c31b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -603,10 +603,6 @@ static void ext4_put_super(struct super_block *sb) | |||
603 | if (sb->s_dirt) | 603 | if (sb->s_dirt) |
604 | ext4_commit_super(sb, 1); | 604 | ext4_commit_super(sb, 1); |
605 | 605 | ||
606 | ext4_release_system_zone(sb); | ||
607 | ext4_mb_release(sb); | ||
608 | ext4_ext_release(sb); | ||
609 | ext4_xattr_put_super(sb); | ||
610 | if (sbi->s_journal) { | 606 | if (sbi->s_journal) { |
611 | err = jbd2_journal_destroy(sbi->s_journal); | 607 | err = jbd2_journal_destroy(sbi->s_journal); |
612 | sbi->s_journal = NULL; | 608 | sbi->s_journal = NULL; |
@@ -614,6 +610,12 @@ static void ext4_put_super(struct super_block *sb) | |||
614 | ext4_abort(sb, __func__, | 610 | ext4_abort(sb, __func__, |
615 | "Couldn't clean up the journal"); | 611 | "Couldn't clean up the journal"); |
616 | } | 612 | } |
613 | |||
614 | ext4_release_system_zone(sb); | ||
615 | ext4_mb_release(sb); | ||
616 | ext4_ext_release(sb); | ||
617 | ext4_xattr_put_super(sb); | ||
618 | |||
617 | if (!(sb->s_flags & MS_RDONLY)) { | 619 | if (!(sb->s_flags & MS_RDONLY)) { |
618 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); | 620 | EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); |
619 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 621 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
@@ -704,6 +706,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
704 | spin_lock_init(&(ei->i_block_reservation_lock)); | 706 | spin_lock_init(&(ei->i_block_reservation_lock)); |
705 | INIT_LIST_HEAD(&ei->i_aio_dio_complete_list); | 707 | INIT_LIST_HEAD(&ei->i_aio_dio_complete_list); |
706 | ei->cur_aio_dio = NULL; | 708 | ei->cur_aio_dio = NULL; |
709 | ei->i_sync_tid = 0; | ||
710 | ei->i_datasync_tid = 0; | ||
707 | 711 | ||
708 | return &ei->vfs_inode; | 712 | return &ei->vfs_inode; |
709 | } | 713 | } |
@@ -899,6 +903,12 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
899 | if (test_opt(sb, NO_AUTO_DA_ALLOC)) | 903 | if (test_opt(sb, NO_AUTO_DA_ALLOC)) |
900 | seq_puts(seq, ",noauto_da_alloc"); | 904 | seq_puts(seq, ",noauto_da_alloc"); |
901 | 905 | ||
906 | if (test_opt(sb, DISCARD)) | ||
907 | seq_puts(seq, ",discard"); | ||
908 | |||
909 | if (test_opt(sb, NOLOAD)) | ||
910 | seq_puts(seq, ",norecovery"); | ||
911 | |||
902 | ext4_show_quota_options(seq, sb); | 912 | ext4_show_quota_options(seq, sb); |
903 | 913 | ||
904 | return 0; | 914 | return 0; |
@@ -1079,7 +1089,8 @@ enum { | |||
1079 | Opt_usrquota, Opt_grpquota, Opt_i_version, | 1089 | Opt_usrquota, Opt_grpquota, Opt_i_version, |
1080 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1090 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
1081 | Opt_block_validity, Opt_noblock_validity, | 1091 | Opt_block_validity, Opt_noblock_validity, |
1082 | Opt_inode_readahead_blks, Opt_journal_ioprio | 1092 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
1093 | Opt_discard, Opt_nodiscard, | ||
1083 | }; | 1094 | }; |
1084 | 1095 | ||
1085 | static const match_table_t tokens = { | 1096 | static const match_table_t tokens = { |
@@ -1104,6 +1115,7 @@ static const match_table_t tokens = { | |||
1104 | {Opt_acl, "acl"}, | 1115 | {Opt_acl, "acl"}, |
1105 | {Opt_noacl, "noacl"}, | 1116 | {Opt_noacl, "noacl"}, |
1106 | {Opt_noload, "noload"}, | 1117 | {Opt_noload, "noload"}, |
1118 | {Opt_noload, "norecovery"}, | ||
1107 | {Opt_nobh, "nobh"}, | 1119 | {Opt_nobh, "nobh"}, |
1108 | {Opt_bh, "bh"}, | 1120 | {Opt_bh, "bh"}, |
1109 | {Opt_commit, "commit=%u"}, | 1121 | {Opt_commit, "commit=%u"}, |
@@ -1144,6 +1156,8 @@ static const match_table_t tokens = { | |||
1144 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, | 1156 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, |
1145 | {Opt_auto_da_alloc, "auto_da_alloc"}, | 1157 | {Opt_auto_da_alloc, "auto_da_alloc"}, |
1146 | {Opt_noauto_da_alloc, "noauto_da_alloc"}, | 1158 | {Opt_noauto_da_alloc, "noauto_da_alloc"}, |
1159 | {Opt_discard, "discard"}, | ||
1160 | {Opt_nodiscard, "nodiscard"}, | ||
1147 | {Opt_err, NULL}, | 1161 | {Opt_err, NULL}, |
1148 | }; | 1162 | }; |
1149 | 1163 | ||
@@ -1565,6 +1579,12 @@ set_qf_format: | |||
1565 | else | 1579 | else |
1566 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); | 1580 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); |
1567 | break; | 1581 | break; |
1582 | case Opt_discard: | ||
1583 | set_opt(sbi->s_mount_opt, DISCARD); | ||
1584 | break; | ||
1585 | case Opt_nodiscard: | ||
1586 | clear_opt(sbi->s_mount_opt, DISCARD); | ||
1587 | break; | ||
1568 | default: | 1588 | default: |
1569 | ext4_msg(sb, KERN_ERR, | 1589 | ext4_msg(sb, KERN_ERR, |
1570 | "Unrecognized mount option \"%s\" " | 1590 | "Unrecognized mount option \"%s\" " |
@@ -1673,14 +1693,14 @@ static int ext4_fill_flex_info(struct super_block *sb) | |||
1673 | size_t size; | 1693 | size_t size; |
1674 | int i; | 1694 | int i; |
1675 | 1695 | ||
1676 | if (!sbi->s_es->s_log_groups_per_flex) { | 1696 | sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; |
1697 | groups_per_flex = 1 << sbi->s_log_groups_per_flex; | ||
1698 | |||
1699 | if (groups_per_flex < 2) { | ||
1677 | sbi->s_log_groups_per_flex = 0; | 1700 | sbi->s_log_groups_per_flex = 0; |
1678 | return 1; | 1701 | return 1; |
1679 | } | 1702 | } |
1680 | 1703 | ||
1681 | sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex; | ||
1682 | groups_per_flex = 1 << sbi->s_log_groups_per_flex; | ||
1683 | |||
1684 | /* We allocate both existing and potentially added groups */ | 1704 | /* We allocate both existing and potentially added groups */ |
1685 | flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + | 1705 | flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + |
1686 | ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << | 1706 | ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << |
@@ -2721,26 +2741,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2721 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { | 2741 | EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { |
2722 | if (ext4_load_journal(sb, es, journal_devnum)) | 2742 | if (ext4_load_journal(sb, es, journal_devnum)) |
2723 | goto failed_mount3; | 2743 | goto failed_mount3; |
2724 | if (!(sb->s_flags & MS_RDONLY) && | ||
2725 | EXT4_SB(sb)->s_journal->j_failed_commit) { | ||
2726 | ext4_msg(sb, KERN_CRIT, "error: " | ||
2727 | "ext4_fill_super: Journal transaction " | ||
2728 | "%u is corrupt", | ||
2729 | EXT4_SB(sb)->s_journal->j_failed_commit); | ||
2730 | if (test_opt(sb, ERRORS_RO)) { | ||
2731 | ext4_msg(sb, KERN_CRIT, | ||
2732 | "Mounting filesystem read-only"); | ||
2733 | sb->s_flags |= MS_RDONLY; | ||
2734 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
2735 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
2736 | } | ||
2737 | if (test_opt(sb, ERRORS_PANIC)) { | ||
2738 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | ||
2739 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | ||
2740 | ext4_commit_super(sb, 1); | ||
2741 | goto failed_mount4; | ||
2742 | } | ||
2743 | } | ||
2744 | } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && | 2744 | } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && |
2745 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { | 2745 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { |
2746 | ext4_msg(sb, KERN_ERR, "required journal recovery " | 2746 | ext4_msg(sb, KERN_ERR, "required journal recovery " |
@@ -3668,13 +3668,11 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
3668 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; | 3668 | buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; |
3669 | buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) - | 3669 | buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) - |
3670 | percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter); | 3670 | percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter); |
3671 | ext4_free_blocks_count_set(es, buf->f_bfree); | ||
3672 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); | 3671 | buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); |
3673 | if (buf->f_bfree < ext4_r_blocks_count(es)) | 3672 | if (buf->f_bfree < ext4_r_blocks_count(es)) |
3674 | buf->f_bavail = 0; | 3673 | buf->f_bavail = 0; |
3675 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 3674 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
3676 | buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter); | 3675 | buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter); |
3677 | es->s_free_inodes_count = cpu_to_le32(buf->f_ffree); | ||
3678 | buf->f_namelen = EXT4_NAME_LEN; | 3676 | buf->f_namelen = EXT4_NAME_LEN; |
3679 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | 3677 | fsid = le64_to_cpup((void *)es->s_uuid) ^ |
3680 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | 3678 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); |
@@ -3966,6 +3964,58 @@ static int ext4_get_sb(struct file_system_type *fs_type, int flags, | |||
3966 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); | 3964 | return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt); |
3967 | } | 3965 | } |
3968 | 3966 | ||
3967 | #if !defined(CONTIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | ||
3968 | static struct file_system_type ext2_fs_type = { | ||
3969 | .owner = THIS_MODULE, | ||
3970 | .name = "ext2", | ||
3971 | .get_sb = ext4_get_sb, | ||
3972 | .kill_sb = kill_block_super, | ||
3973 | .fs_flags = FS_REQUIRES_DEV, | ||
3974 | }; | ||
3975 | |||
3976 | static inline void register_as_ext2(void) | ||
3977 | { | ||
3978 | int err = register_filesystem(&ext2_fs_type); | ||
3979 | if (err) | ||
3980 | printk(KERN_WARNING | ||
3981 | "EXT4-fs: Unable to register as ext2 (%d)\n", err); | ||
3982 | } | ||
3983 | |||
3984 | static inline void unregister_as_ext2(void) | ||
3985 | { | ||
3986 | unregister_filesystem(&ext2_fs_type); | ||
3987 | } | ||
3988 | #else | ||
3989 | static inline void register_as_ext2(void) { } | ||
3990 | static inline void unregister_as_ext2(void) { } | ||
3991 | #endif | ||
3992 | |||
3993 | #if !defined(CONTIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23) | ||
3994 | static struct file_system_type ext3_fs_type = { | ||
3995 | .owner = THIS_MODULE, | ||
3996 | .name = "ext3", | ||
3997 | .get_sb = ext4_get_sb, | ||
3998 | .kill_sb = kill_block_super, | ||
3999 | .fs_flags = FS_REQUIRES_DEV, | ||
4000 | }; | ||
4001 | |||
4002 | static inline void register_as_ext3(void) | ||
4003 | { | ||
4004 | int err = register_filesystem(&ext3_fs_type); | ||
4005 | if (err) | ||
4006 | printk(KERN_WARNING | ||
4007 | "EXT4-fs: Unable to register as ext3 (%d)\n", err); | ||
4008 | } | ||
4009 | |||
4010 | static inline void unregister_as_ext3(void) | ||
4011 | { | ||
4012 | unregister_filesystem(&ext3_fs_type); | ||
4013 | } | ||
4014 | #else | ||
4015 | static inline void register_as_ext3(void) { } | ||
4016 | static inline void unregister_as_ext3(void) { } | ||
4017 | #endif | ||
4018 | |||
3969 | static struct file_system_type ext4_fs_type = { | 4019 | static struct file_system_type ext4_fs_type = { |
3970 | .owner = THIS_MODULE, | 4020 | .owner = THIS_MODULE, |
3971 | .name = "ext4", | 4021 | .name = "ext4", |
@@ -3995,11 +4045,15 @@ static int __init init_ext4_fs(void) | |||
3995 | err = init_inodecache(); | 4045 | err = init_inodecache(); |
3996 | if (err) | 4046 | if (err) |
3997 | goto out1; | 4047 | goto out1; |
4048 | register_as_ext2(); | ||
4049 | register_as_ext3(); | ||
3998 | err = register_filesystem(&ext4_fs_type); | 4050 | err = register_filesystem(&ext4_fs_type); |
3999 | if (err) | 4051 | if (err) |
4000 | goto out; | 4052 | goto out; |
4001 | return 0; | 4053 | return 0; |
4002 | out: | 4054 | out: |
4055 | unregister_as_ext2(); | ||
4056 | unregister_as_ext3(); | ||
4003 | destroy_inodecache(); | 4057 | destroy_inodecache(); |
4004 | out1: | 4058 | out1: |
4005 | exit_ext4_xattr(); | 4059 | exit_ext4_xattr(); |
@@ -4015,6 +4069,8 @@ out4: | |||
4015 | 4069 | ||
4016 | static void __exit exit_ext4_fs(void) | 4070 | static void __exit exit_ext4_fs(void) |
4017 | { | 4071 | { |
4072 | unregister_as_ext2(); | ||
4073 | unregister_as_ext3(); | ||
4018 | unregister_filesystem(&ext4_fs_type); | 4074 | unregister_filesystem(&ext4_fs_type); |
4019 | destroy_inodecache(); | 4075 | destroy_inodecache(); |
4020 | exit_ext4_xattr(); | 4076 | exit_ext4_xattr(); |