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.c160
1 files changed, 118 insertions, 42 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index d4ca92aab514..6ed9aa91f27d 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);
@@ -702,8 +704,13 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
702 ei->i_allocated_meta_blocks = 0; 704 ei->i_allocated_meta_blocks = 0;
703 ei->i_delalloc_reserved_flag = 0; 705 ei->i_delalloc_reserved_flag = 0;
704 spin_lock_init(&(ei->i_block_reservation_lock)); 706 spin_lock_init(&(ei->i_block_reservation_lock));
707#ifdef CONFIG_QUOTA
708 ei->i_reserved_quota = 0;
709#endif
705 INIT_LIST_HEAD(&ei->i_aio_dio_complete_list); 710 INIT_LIST_HEAD(&ei->i_aio_dio_complete_list);
706 ei->cur_aio_dio = NULL; 711 ei->cur_aio_dio = NULL;
712 ei->i_sync_tid = 0;
713 ei->i_datasync_tid = 0;
707 714
708 return &ei->vfs_inode; 715 return &ei->vfs_inode;
709} 716}
@@ -765,9 +772,22 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
765#if defined(CONFIG_QUOTA) 772#if defined(CONFIG_QUOTA)
766 struct ext4_sb_info *sbi = EXT4_SB(sb); 773 struct ext4_sb_info *sbi = EXT4_SB(sb);
767 774
768 if (sbi->s_jquota_fmt) 775 if (sbi->s_jquota_fmt) {
769 seq_printf(seq, ",jqfmt=%s", 776 char *fmtname = "";
770 (sbi->s_jquota_fmt == QFMT_VFS_OLD) ? "vfsold" : "vfsv0"); 777
778 switch (sbi->s_jquota_fmt) {
779 case QFMT_VFS_OLD:
780 fmtname = "vfsold";
781 break;
782 case QFMT_VFS_V0:
783 fmtname = "vfsv0";
784 break;
785 case QFMT_VFS_V1:
786 fmtname = "vfsv1";
787 break;
788 }
789 seq_printf(seq, ",jqfmt=%s", fmtname);
790 }
771 791
772 if (sbi->s_qf_names[USRQUOTA]) 792 if (sbi->s_qf_names[USRQUOTA])
773 seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]); 793 seq_printf(seq, ",usrjquota=%s", sbi->s_qf_names[USRQUOTA]);
@@ -899,6 +919,12 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
899 if (test_opt(sb, NO_AUTO_DA_ALLOC)) 919 if (test_opt(sb, NO_AUTO_DA_ALLOC))
900 seq_puts(seq, ",noauto_da_alloc"); 920 seq_puts(seq, ",noauto_da_alloc");
901 921
922 if (test_opt(sb, DISCARD))
923 seq_puts(seq, ",discard");
924
925 if (test_opt(sb, NOLOAD))
926 seq_puts(seq, ",norecovery");
927
902 ext4_show_quota_options(seq, sb); 928 ext4_show_quota_options(seq, sb);
903 929
904 return 0; 930 return 0;
@@ -991,7 +1017,9 @@ static const struct dquot_operations ext4_quota_operations = {
991 .reserve_space = dquot_reserve_space, 1017 .reserve_space = dquot_reserve_space,
992 .claim_space = dquot_claim_space, 1018 .claim_space = dquot_claim_space,
993 .release_rsv = dquot_release_reserved_space, 1019 .release_rsv = dquot_release_reserved_space,
1020#ifdef CONFIG_QUOTA
994 .get_reserved_space = ext4_get_reserved_space, 1021 .get_reserved_space = ext4_get_reserved_space,
1022#endif
995 .alloc_inode = dquot_alloc_inode, 1023 .alloc_inode = dquot_alloc_inode,
996 .free_space = dquot_free_space, 1024 .free_space = dquot_free_space,
997 .free_inode = dquot_free_inode, 1025 .free_inode = dquot_free_inode,
@@ -1074,12 +1102,13 @@ enum {
1074 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 1102 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
1075 Opt_data_err_abort, Opt_data_err_ignore, 1103 Opt_data_err_abort, Opt_data_err_ignore,
1076 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 1104 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
1077 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 1105 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota,
1078 Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, 1106 Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err,
1079 Opt_usrquota, Opt_grpquota, Opt_i_version, 1107 Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version,
1080 Opt_stripe, Opt_delalloc, Opt_nodelalloc, 1108 Opt_stripe, Opt_delalloc, Opt_nodelalloc,
1081 Opt_block_validity, Opt_noblock_validity, 1109 Opt_block_validity, Opt_noblock_validity,
1082 Opt_inode_readahead_blks, Opt_journal_ioprio 1110 Opt_inode_readahead_blks, Opt_journal_ioprio,
1111 Opt_discard, Opt_nodiscard,
1083}; 1112};
1084 1113
1085static const match_table_t tokens = { 1114static const match_table_t tokens = {
@@ -1104,6 +1133,7 @@ static const match_table_t tokens = {
1104 {Opt_acl, "acl"}, 1133 {Opt_acl, "acl"},
1105 {Opt_noacl, "noacl"}, 1134 {Opt_noacl, "noacl"},
1106 {Opt_noload, "noload"}, 1135 {Opt_noload, "noload"},
1136 {Opt_noload, "norecovery"},
1107 {Opt_nobh, "nobh"}, 1137 {Opt_nobh, "nobh"},
1108 {Opt_bh, "bh"}, 1138 {Opt_bh, "bh"},
1109 {Opt_commit, "commit=%u"}, 1139 {Opt_commit, "commit=%u"},
@@ -1125,6 +1155,7 @@ static const match_table_t tokens = {
1125 {Opt_grpjquota, "grpjquota=%s"}, 1155 {Opt_grpjquota, "grpjquota=%s"},
1126 {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, 1156 {Opt_jqfmt_vfsold, "jqfmt=vfsold"},
1127 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, 1157 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
1158 {Opt_jqfmt_vfsv1, "jqfmt=vfsv1"},
1128 {Opt_grpquota, "grpquota"}, 1159 {Opt_grpquota, "grpquota"},
1129 {Opt_noquota, "noquota"}, 1160 {Opt_noquota, "noquota"},
1130 {Opt_quota, "quota"}, 1161 {Opt_quota, "quota"},
@@ -1144,6 +1175,8 @@ static const match_table_t tokens = {
1144 {Opt_auto_da_alloc, "auto_da_alloc=%u"}, 1175 {Opt_auto_da_alloc, "auto_da_alloc=%u"},
1145 {Opt_auto_da_alloc, "auto_da_alloc"}, 1176 {Opt_auto_da_alloc, "auto_da_alloc"},
1146 {Opt_noauto_da_alloc, "noauto_da_alloc"}, 1177 {Opt_noauto_da_alloc, "noauto_da_alloc"},
1178 {Opt_discard, "discard"},
1179 {Opt_nodiscard, "nodiscard"},
1147 {Opt_err, NULL}, 1180 {Opt_err, NULL},
1148}; 1181};
1149 1182
@@ -1425,6 +1458,9 @@ clear_qf_name:
1425 goto set_qf_format; 1458 goto set_qf_format;
1426 case Opt_jqfmt_vfsv0: 1459 case Opt_jqfmt_vfsv0:
1427 qfmt = QFMT_VFS_V0; 1460 qfmt = QFMT_VFS_V0;
1461 goto set_qf_format;
1462 case Opt_jqfmt_vfsv1:
1463 qfmt = QFMT_VFS_V1;
1428set_qf_format: 1464set_qf_format:
1429 if (sb_any_quota_loaded(sb) && 1465 if (sb_any_quota_loaded(sb) &&
1430 sbi->s_jquota_fmt != qfmt) { 1466 sbi->s_jquota_fmt != qfmt) {
@@ -1467,6 +1503,7 @@ set_qf_format:
1467 case Opt_offgrpjquota: 1503 case Opt_offgrpjquota:
1468 case Opt_jqfmt_vfsold: 1504 case Opt_jqfmt_vfsold:
1469 case Opt_jqfmt_vfsv0: 1505 case Opt_jqfmt_vfsv0:
1506 case Opt_jqfmt_vfsv1:
1470 ext4_msg(sb, KERN_ERR, 1507 ext4_msg(sb, KERN_ERR,
1471 "journaled quota options not supported"); 1508 "journaled quota options not supported");
1472 break; 1509 break;
@@ -1565,6 +1602,12 @@ set_qf_format:
1565 else 1602 else
1566 set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); 1603 set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);
1567 break; 1604 break;
1605 case Opt_discard:
1606 set_opt(sbi->s_mount_opt, DISCARD);
1607 break;
1608 case Opt_nodiscard:
1609 clear_opt(sbi->s_mount_opt, DISCARD);
1610 break;
1568 default: 1611 default:
1569 ext4_msg(sb, KERN_ERR, 1612 ext4_msg(sb, KERN_ERR,
1570 "Unrecognized mount option \"%s\" " 1613 "Unrecognized mount option \"%s\" "
@@ -1673,14 +1716,14 @@ static int ext4_fill_flex_info(struct super_block *sb)
1673 size_t size; 1716 size_t size;
1674 int i; 1717 int i;
1675 1718
1676 if (!sbi->s_es->s_log_groups_per_flex) { 1719 sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
1720 groups_per_flex = 1 << sbi->s_log_groups_per_flex;
1721
1722 if (groups_per_flex < 2) {
1677 sbi->s_log_groups_per_flex = 0; 1723 sbi->s_log_groups_per_flex = 0;
1678 return 1; 1724 return 1;
1679 } 1725 }
1680 1726
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 */ 1727 /* We allocate both existing and potentially added groups */
1685 flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) + 1728 flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
1686 ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) << 1729 ((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
@@ -2099,11 +2142,8 @@ static int parse_strtoul(const char *buf,
2099{ 2142{
2100 char *endp; 2143 char *endp;
2101 2144
2102 while (*buf && isspace(*buf)) 2145 *value = simple_strtoul(skip_spaces(buf), &endp, 0);
2103 buf++; 2146 endp = skip_spaces(endp);
2104 *value = simple_strtoul(buf, &endp, 0);
2105 while (*endp && isspace(*endp))
2106 endp++;
2107 if (*endp || *value > max) 2147 if (*endp || *value > max)
2108 return -EINVAL; 2148 return -EINVAL;
2109 2149
@@ -2721,26 +2761,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)) { 2761 EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) {
2722 if (ext4_load_journal(sb, es, journal_devnum)) 2762 if (ext4_load_journal(sb, es, journal_devnum))
2723 goto failed_mount3; 2763 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) && 2764 } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) &&
2745 EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { 2765 EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) {
2746 ext4_msg(sb, KERN_ERR, "required journal recovery " 2766 ext4_msg(sb, KERN_ERR, "required journal recovery "
@@ -3668,13 +3688,11 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
3668 buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; 3688 buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last;
3669 buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) - 3689 buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter) -
3670 percpu_counter_sum_positive(&sbi->s_dirtyblocks_counter); 3690 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); 3691 buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es);
3673 if (buf->f_bfree < ext4_r_blocks_count(es)) 3692 if (buf->f_bfree < ext4_r_blocks_count(es))
3674 buf->f_bavail = 0; 3693 buf->f_bavail = 0;
3675 buf->f_files = le32_to_cpu(es->s_inodes_count); 3694 buf->f_files = le32_to_cpu(es->s_inodes_count);
3676 buf->f_ffree = percpu_counter_sum_positive(&sbi->s_freeinodes_counter); 3695 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; 3696 buf->f_namelen = EXT4_NAME_LEN;
3679 fsid = le64_to_cpup((void *)es->s_uuid) ^ 3697 fsid = le64_to_cpup((void *)es->s_uuid) ^
3680 le64_to_cpup((void *)es->s_uuid + sizeof(u64)); 3698 le64_to_cpup((void *)es->s_uuid + sizeof(u64));
@@ -3966,6 +3984,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); 3984 return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
3967} 3985}
3968 3986
3987#if !defined(CONTIG_EXT2_FS) && !defined(CONFIG_EXT2_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
3988static struct file_system_type ext2_fs_type = {
3989 .owner = THIS_MODULE,
3990 .name = "ext2",
3991 .get_sb = ext4_get_sb,
3992 .kill_sb = kill_block_super,
3993 .fs_flags = FS_REQUIRES_DEV,
3994};
3995
3996static inline void register_as_ext2(void)
3997{
3998 int err = register_filesystem(&ext2_fs_type);
3999 if (err)
4000 printk(KERN_WARNING
4001 "EXT4-fs: Unable to register as ext2 (%d)\n", err);
4002}
4003
4004static inline void unregister_as_ext2(void)
4005{
4006 unregister_filesystem(&ext2_fs_type);
4007}
4008#else
4009static inline void register_as_ext2(void) { }
4010static inline void unregister_as_ext2(void) { }
4011#endif
4012
4013#if !defined(CONTIG_EXT3_FS) && !defined(CONFIG_EXT3_FS_MODULE) && defined(CONFIG_EXT4_USE_FOR_EXT23)
4014static struct file_system_type ext3_fs_type = {
4015 .owner = THIS_MODULE,
4016 .name = "ext3",
4017 .get_sb = ext4_get_sb,
4018 .kill_sb = kill_block_super,
4019 .fs_flags = FS_REQUIRES_DEV,
4020};
4021
4022static inline void register_as_ext3(void)
4023{
4024 int err = register_filesystem(&ext3_fs_type);
4025 if (err)
4026 printk(KERN_WARNING
4027 "EXT4-fs: Unable to register as ext3 (%d)\n", err);
4028}
4029
4030static inline void unregister_as_ext3(void)
4031{
4032 unregister_filesystem(&ext3_fs_type);
4033}
4034#else
4035static inline void register_as_ext3(void) { }
4036static inline void unregister_as_ext3(void) { }
4037#endif
4038
3969static struct file_system_type ext4_fs_type = { 4039static struct file_system_type ext4_fs_type = {
3970 .owner = THIS_MODULE, 4040 .owner = THIS_MODULE,
3971 .name = "ext4", 4041 .name = "ext4",
@@ -3995,11 +4065,15 @@ static int __init init_ext4_fs(void)
3995 err = init_inodecache(); 4065 err = init_inodecache();
3996 if (err) 4066 if (err)
3997 goto out1; 4067 goto out1;
4068 register_as_ext2();
4069 register_as_ext3();
3998 err = register_filesystem(&ext4_fs_type); 4070 err = register_filesystem(&ext4_fs_type);
3999 if (err) 4071 if (err)
4000 goto out; 4072 goto out;
4001 return 0; 4073 return 0;
4002out: 4074out:
4075 unregister_as_ext2();
4076 unregister_as_ext3();
4003 destroy_inodecache(); 4077 destroy_inodecache();
4004out1: 4078out1:
4005 exit_ext4_xattr(); 4079 exit_ext4_xattr();
@@ -4015,6 +4089,8 @@ out4:
4015 4089
4016static void __exit exit_ext4_fs(void) 4090static void __exit exit_ext4_fs(void)
4017{ 4091{
4092 unregister_as_ext2();
4093 unregister_as_ext3();
4018 unregister_filesystem(&ext4_fs_type); 4094 unregister_filesystem(&ext4_fs_type);
4019 destroy_inodecache(); 4095 destroy_inodecache();
4020 exit_ext4_xattr(); 4096 exit_ext4_xattr();