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.c155
1 files changed, 113 insertions, 42 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index d4ca92aab514..827bde1f2594 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}
@@ -765,9 +769,22 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
765#if defined(CONFIG_QUOTA) 769#if defined(CONFIG_QUOTA)
766 struct ext4_sb_info *sbi = EXT4_SB(sb); 770 struct ext4_sb_info *sbi = EXT4_SB(sb);
767 771
768 if (sbi->s_jquota_fmt) 772 if (sbi->s_jquota_fmt) {
769 seq_printf(seq, ",jqfmt=%s", 773 char *fmtname = "";
770 (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold" : "vfsv0"); 774
775 switch (sbi->s_jquota_fmt) {
776 case QFMT_VFS_OLD:
777 fmtname = "vfsold";
778 break;
779 case QFMT_VFS_V0:
780 fmtname = "vfsv0";
781 break;
782 case QFMT_VFS_V1:
783 fmtname = "vfsv1";
784 break;
785 }
786 seq_printf(seq, ",jqfmt=%s", fmtname);
787 }
771 788
772 if (sbi->s_qf_names[USRQUOTA]) 789 if (sbi->s_qf_names[USRQUOTA])
773 seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); 790 seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
@@ -899,6 +916,12 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
899 if (test_opt(sb, NO_AUTO_DA_ALLOC)) 916 if (test_opt(sb, NO_AUTO_DA_ALLOC))
900 seq_puts(seq, ",noauto_da_alloc"); 917 seq_puts(seq, ",noauto_da_alloc");
901 918
919 if (test_opt(sb, DISCARD))
920 seq_puts(seq, ",discard");
921
922 if (test_opt(sb, NOLOAD))
923 seq_puts(seq, ",norecovery");
924
902 ext4_show_quota_options(seq, sb); 925 ext4_show_quota_options(seq, sb);
903 926
904 return 0; 927 return 0;
@@ -1074,12 +1097,13 @@ enum {
1074 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 1097 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
1075 Opt_data_err_abort, Opt_data_err_ignore, 1098 Opt_data_err_abort, Opt_data_err_ignore,
1076 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 1099 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
1077 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 1100 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
1078 Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, 1101 Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
1079 Opt_usrquota, Opt_grpquota, Opt_i_version, 1102 Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
1080 Opt_stripe, Opt_delalloc, Opt_nodelalloc, 1103 Opt_stripe, Opt_delalloc, Opt_nodelalloc,
1081 Opt_block_validity, Opt_noblock_validity, 1104 Opt_block_validity, Opt_noblock_validity,
1082 Opt_inode_readahead_blks, Opt_journal_ioprio 1105 Opt_inode_readahead_blks, Opt_journal_ioprio,
1106 Opt_discard, Opt_nodiscard,
1083}; 1107};
1084 1108
1085static const match_table_t tokens = { 1109static const match_table_t tokens = {
@@ -1104,6 +1128,7 @@ static const match_table_t tokens = {
1104 {Opt_acl, "acl"}, 1128 {Opt_acl, "acl"},
1105 {Opt_noacl, "noacl"}, 1129 {Opt_noacl, "noacl"},
1106 {Opt_noload, "noload"}, 1130 {Opt_noload, "noload"},
1131 {Opt_noload, "norecovery"},
1107 {Opt_nobh, "nobh"}, 1132 {Opt_nobh, "nobh"},
1108 {Opt_bh, "bh"}, 1133 {Opt_bh, "bh"},
1109 {Opt_commit, "commit=%u"}, 1134 {Opt_commit, "commit=%u"},
@@ -1125,6 +1150,7 @@ static const match_table_t tokens = {
1125 {Opt_grpjquota, "grpjquota=%s"}, 1150 {Opt_grpjquota, "grpjquota=%s"},
1126 {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, 1151 {Opt_jqfmt_vfsold, "jqfmt=vfsold"},
1127 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, 1152 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
1153 {Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
1128 {Opt_grpquota, "grpquota"}, 1154 {Opt_grpquota, "grpquota"},
1129 {Opt_noquota, "noquota"}, 1155 {Opt_noquota, "noquota"},
1130 {Opt_quota, "quota"}, 1156 {Opt_quota, "quota"},
@@ -1144,6 +1170,8 @@ static const match_table_t tokens = {
1144 {Opt_auto_da_alloc, "auto_da_alloc=%u"}, 1170 {Opt_auto_da_alloc, "auto_da_alloc=%u"},
1145 {Opt_auto_da_alloc, "auto_da_alloc"}, 1171 {Opt_auto_da_alloc, "auto_da_alloc"},
1146 {Opt_noauto_da_alloc, "noauto_da_alloc"}, 1172 {Opt_noauto_da_alloc, "noauto_da_alloc"},
1173 {Opt_discard, "discard"},
1174 {Opt_nodiscard, "nodiscard"},
1147 {Opt_err, NULL}, 1175 {Opt_err, NULL},
1148}; 1176};
1149 1177
@@ -1425,6 +1453,9 @@ clear_qf_name:
1425 goto set_qf_format; 1453 goto set_qf_format;
1426 case Opt_jqfmt_vfsv0: 1454 case Opt_jqfmt_vfsv0:
1427 qfmt = QFMT_VFS_V0; 1455 qfmt = QFMT_VFS_V0;
1456 goto set_qf_format;
1457 case Opt_jqfmt_vfsv1:
1458 qfmt = QFMT_VFS_V1;
1428set_qf_format: 1459set_qf_format:
1429 if (sb_any_quota_loaded(sb) && 1460 if (sb_any_quota_loaded(sb) &&
1430 sbi->s_jquota_fmt != qfmt) { 1461 sbi->s_jquota_fmt != qfmt) {
@@ -1467,6 +1498,7 @@ set_qf_format:
1467 case Opt_offgrpjquota: 1498 case Opt_offgrpjquota:
1468 case Opt_jqfmt_vfsold: 1499 case Opt_jqfmt_vfsold:
1469 case Opt_jqfmt_vfsv0: 1500 case Opt_jqfmt_vfsv0:
1501 case Opt_jqfmt_vfsv1:
1470 ext4_msg(sb, KERN_ERR, 1502 ext4_msg(sb, KERN_ERR,
1471 "journaled quota options not supported"); 1503 "journaled quota options not supported");
1472 break; 1504 break;
@@ -1565,6 +1597,12 @@ set_qf_format:
1565 else 1597 else
1566 set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); 1598 set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);
1567 break; 1599 break;
1600 case Opt_discard:
1601 set_opt(sbi->s_mount_opt, DISCARD);
1602 break;
1603 case Opt_nodiscard:
1604 clear_opt(sbi->s_mount_opt, DISCARD);
1605 break;
1568 default: 1606 default:
1569 ext4_msg(sb, KERN_ERR, 1607 ext4_msg(sb, KERN_ERR,
1570 "Unrecognized mount option \"%s\" " 1608 "Unrecognized mount option \"%s\" "
@@ -1673,14 +1711,14 @@ static int ext4_fill_flex_info(struct super_block *sb)
1673 size_t size; 1711 size_t size;
1674 int i; 1712 int i;
1675 1713
1676 if (!sbi->s_es->s_log_groups_per_flex) { 1714 sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
1715 groups_per_flex = 1 << sbi->s_log_groups_per_flex;
1716
1717 if (groups_per_flex < 2) {
1677 sbi->s_log_groups_per_flex = 0; 1718 sbi->s_log_groups_per_flex = 0;
1678 return 1; 1719 return 1;
1679 } 1720 }
1680 1721
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 */ 1722 /* We allocate both existing and potentially added groups */
1685 flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + 1723 flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
1686 ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << 1724 ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
@@ -2099,11 +2137,8 @@ static int parse_strtoul(const char *buf,
2099{ 2137{
2100 char *endp; 2138 char *endp;
2101 2139
2102 while (*buf && isspace(*buf)) 2140 *value = simple_strtoul(skip_spaces(buf), &endp, 0);
2103 buf++; 2141 endp = skip_spaces(endp);
2104 *value = simple_strtoul(buf, &endp, 0);
2105 while (*endp && isspace(*endp))
2106 endp++;
2107 if (*endp || *value > max) 2142 if (*endp || *value > max)
2108 return -EINVAL; 2143 return -EINVAL;
2109 2144
@@ -2721,26 +2756,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)) { 2756 EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
2722 if (ext4_load_journal(sb, es, journal_devnum)) 2757 if (ext4_load_journal(sb, es, journal_devnum))
2723 goto failed_mount3; 2758 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) && 2759 } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
2745 EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { 2760 EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
2746 ext4_msg(sb, KERN_ERR, "required journal recovery " 2761 ext4_msg(sb, KERN_ERR, "required journal recovery "
@@ -3668,13 +3683,11 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
3668 buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; 3683 buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last;
3669 buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) - 3684 buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) -
3670 percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter); 3685 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); 3686 buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
3673 if (buf->f_bfree < ext4_r_blocks_count(es)) 3687 if (buf->f_bfree < ext4_r_blocks_count(es))
3674 buf->f_bavail = 0; 3688 buf->f_bavail = 0;
3675 buf->f_files = le32_to_cpu(es->s_inodes_count); 3689 buf->f_files = le32_to_cpu(es->s_inodes_count);
3676 buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter); 3690 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; 3691 buf->f_namelen = EXT4_NAME_LEN;
3679 fsid = le64_to_cpup((void *)es->s_uuid) ^ 3692 fsid = le64_to_cpup((void *)es->s_uuid) ^
3680 le64_to_cpup((void *)es->s_uuid + sizeof(u64)); 3693 le64_to_cpup((void *)es->s_uuid + sizeof(u64));
@@ -3966,6 +3979,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); 3979 return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
3967} 3980}
3968 3981
3982#if !defined(CONTIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
3983static struct file_system_type ext2_fs_type = {
3984 .owner = THIS_MODULE,
3985 .name = "ext2",
3986 .get_sb = ext4_get_sb,
3987 .kill_sb = kill_block_super,
3988 .fs_flags = FS_REQUIRES_DEV,
3989};
3990
3991static inline void register_as_ext2(void)
3992{
3993 int err = register_filesystem(&ext2_fs_type);
3994 if (err)
3995 printk(KERN_WARNING
3996 "EXT4-fs: Unable to register as ext2 (%d)\n", err);
3997}
3998
3999static inline void unregister_as_ext2(void)
4000{
4001 unregister_filesystem(&ext2_fs_type);
4002}
4003#else
4004static inline void register_as_ext2(void) { }
4005static inline void unregister_as_ext2(void) { }
4006#endif
4007
4008#if !defined(CONTIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
4009static struct file_system_type ext3_fs_type = {
4010 .owner = THIS_MODULE,
4011 .name = "ext3",
4012 .get_sb = ext4_get_sb,
4013 .kill_sb = kill_block_super,
4014 .fs_flags = FS_REQUIRES_DEV,
4015};
4016
4017static inline void register_as_ext3(void)
4018{
4019 int err = register_filesystem(&ext3_fs_type);
4020 if (err)
4021 printk(KERN_WARNING
4022 "EXT4-fs: Unable to register as ext3 (%d)\n", err);
4023}
4024
4025static inline void unregister_as_ext3(void)
4026{
4027 unregister_filesystem(&ext3_fs_type);
4028}
4029#else
4030static inline void register_as_ext3(void) { }
4031static inline void unregister_as_ext3(void) { }
4032#endif
4033
3969static struct file_system_type ext4_fs_type = { 4034static struct file_system_type ext4_fs_type = {
3970 .owner = THIS_MODULE, 4035 .owner = THIS_MODULE,
3971 .name = "ext4", 4036 .name = "ext4",
@@ -3995,11 +4060,15 @@ static int __init init_ext4_fs(void)
3995 err = init_inodecache(); 4060 err = init_inodecache();
3996 if (err) 4061 if (err)
3997 goto out1; 4062 goto out1;
4063 register_as_ext2();
4064 register_as_ext3();
3998 err = register_filesystem(&ext4_fs_type); 4065 err = register_filesystem(&ext4_fs_type);
3999 if (err) 4066 if (err)
4000 goto out; 4067 goto out;
4001 return 0; 4068 return 0;
4002out: 4069out:
4070 unregister_as_ext2();
4071 unregister_as_ext3();
4003 destroy_inodecache(); 4072 destroy_inodecache();
4004out1: 4073out1:
4005 exit_ext4_xattr(); 4074 exit_ext4_xattr();
@@ -4015,6 +4084,8 @@ out4:
4015 4084
4016static void __exit exit_ext4_fs(void) 4085static void __exit exit_ext4_fs(void)
4017{ 4086{
4087 unregister_as_ext2();
4088 unregister_as_ext3();
4018 unregister_filesystem(&ext4_fs_type); 4089 unregister_filesystem(&ext4_fs_type);
4019 destroy_inodecache(); 4090 destroy_inodecache();
4020 exit_ext4_xattr(); 4091 exit_ext4_xattr();