aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c118
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
1085static const match_table_t tokens = { 1096static 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)
3968static 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
3976static 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
3984static inline void unregister_as_ext2(void)
3985{
3986 unregister_filesystem(&ext2_fs_type);
3987}
3988#else
3989static inline void register_as_ext2(void) { }
3990static 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)
3994static 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
4002static 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
4010static inline void unregister_as_ext3(void)
4011{
4012 unregister_filesystem(&ext3_fs_type);
4013}
4014#else
4015static inline void register_as_ext3(void) { }
4016static inline void unregister_as_ext3(void) { }
4017#endif
4018
3969static struct file_system_type ext4_fs_type = { 4019static 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;
4002out: 4054out:
4055 unregister_as_ext2();
4056 unregister_as_ext3();
4003 destroy_inodecache(); 4057 destroy_inodecache();
4004out1: 4058out1:
4005 exit_ext4_xattr(); 4059 exit_ext4_xattr();
@@ -4015,6 +4069,8 @@ out4:
4015 4069
4016static void __exit exit_ext4_fs(void) 4070static 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();