aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 22:33:21 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 22:33:21 -0500
commita7c1120d2dcc83691bafa034d98f70285757e826 (patch)
tree56779f292c2dea78feff290c3ce26724d33b3f3e /fs/ext4/super.c
parent6ec40b423032ca769c96fbf9a080db822821893d (diff)
parent9b2ff35753c0512bc8c6adae9e9c87cbeee86f82 (diff)
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 bug fixes from Ted Ts'o: "Various bug fixes for ext4. The most important is a fix for the new extent cache's slab shrinker which can cause significant, user-visible pauses when the system is under memory pressure." * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: ext4: enable quotas before orphan cleanup ext4: don't allow quota mount options when quota feature enabled ext4: fix a warning from sparse check for ext4_dir_llseek ext4: convert number of blocks to clusters properly ext4: fix possible memory leak in ext4_remount() jbd2: fix ERR_PTR dereference in jbd2__journal_start ext4: use percpu counter for extent cache count ext4: optimize ext4_es_shrink()
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 620cf5615ba2..5e6c87836193 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -783,6 +783,7 @@ static void ext4_put_super(struct super_block *sb)
783 percpu_counter_destroy(&sbi->s_freeinodes_counter); 783 percpu_counter_destroy(&sbi->s_freeinodes_counter);
784 percpu_counter_destroy(&sbi->s_dirs_counter); 784 percpu_counter_destroy(&sbi->s_dirs_counter);
785 percpu_counter_destroy(&sbi->s_dirtyclusters_counter); 785 percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
786 percpu_counter_destroy(&sbi->s_extent_cache_cnt);
786 brelse(sbi->s_sbh); 787 brelse(sbi->s_sbh);
787#ifdef CONFIG_QUOTA 788#ifdef CONFIG_QUOTA
788 for (i = 0; i < MAXQUOTAS; i++) 789 for (i = 0; i < MAXQUOTAS; i++)
@@ -1247,6 +1248,11 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
1247 "quota options when quota turned on"); 1248 "quota options when quota turned on");
1248 return -1; 1249 return -1;
1249 } 1250 }
1251 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) {
1252 ext4_msg(sb, KERN_ERR, "Cannot set journaled quota options "
1253 "when QUOTA feature is enabled");
1254 return -1;
1255 }
1250 qname = match_strdup(args); 1256 qname = match_strdup(args);
1251 if (!qname) { 1257 if (!qname) {
1252 ext4_msg(sb, KERN_ERR, 1258 ext4_msg(sb, KERN_ERR,
@@ -1544,6 +1550,13 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
1544 "quota options when quota turned on"); 1550 "quota options when quota turned on");
1545 return -1; 1551 return -1;
1546 } 1552 }
1553 if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
1554 EXT4_FEATURE_RO_COMPAT_QUOTA)) {
1555 ext4_msg(sb, KERN_ERR,
1556 "Cannot set journaled quota options "
1557 "when QUOTA feature is enabled");
1558 return -1;
1559 }
1547 sbi->s_jquota_fmt = m->mount_opt; 1560 sbi->s_jquota_fmt = m->mount_opt;
1548#endif 1561#endif
1549 } else { 1562 } else {
@@ -1592,6 +1605,12 @@ static int parse_options(char *options, struct super_block *sb,
1592 return 0; 1605 return 0;
1593 } 1606 }
1594#ifdef CONFIG_QUOTA 1607#ifdef CONFIG_QUOTA
1608 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
1609 (test_opt(sb, USRQUOTA) || test_opt(sb, GRPQUOTA))) {
1610 ext4_msg(sb, KERN_ERR, "Cannot set quota options when QUOTA "
1611 "feature is enabled");
1612 return 0;
1613 }
1595 if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { 1614 if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
1596 if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) 1615 if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA])
1597 clear_opt(sb, USRQUOTA); 1616 clear_opt(sb, USRQUOTA);
@@ -3161,7 +3180,7 @@ int ext4_calculate_overhead(struct super_block *sb)
3161 } 3180 }
3162 /* Add the journal blocks as well */ 3181 /* Add the journal blocks as well */
3163 if (sbi->s_journal) 3182 if (sbi->s_journal)
3164 overhead += EXT4_B2C(sbi, sbi->s_journal->j_maxlen); 3183 overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_maxlen);
3165 3184
3166 sbi->s_overhead = overhead; 3185 sbi->s_overhead = overhead;
3167 smp_wmb(); 3186 smp_wmb();
@@ -3688,6 +3707,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3688 if (!err) { 3707 if (!err) {
3689 err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0); 3708 err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0);
3690 } 3709 }
3710 if (!err) {
3711 err = percpu_counter_init(&sbi->s_extent_cache_cnt, 0);
3712 }
3691 if (err) { 3713 if (err) {
3692 ext4_msg(sb, KERN_ERR, "insufficient memory"); 3714 ext4_msg(sb, KERN_ERR, "insufficient memory");
3693 goto failed_mount3; 3715 goto failed_mount3;
@@ -3711,13 +3733,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3711 sb->s_export_op = &ext4_export_ops; 3733 sb->s_export_op = &ext4_export_ops;
3712 sb->s_xattr = ext4_xattr_handlers; 3734 sb->s_xattr = ext4_xattr_handlers;
3713#ifdef CONFIG_QUOTA 3735#ifdef CONFIG_QUOTA
3714 sb->s_qcop = &ext4_qctl_operations;
3715 sb->dq_op = &ext4_quota_operations; 3736 sb->dq_op = &ext4_quota_operations;
3716 3737 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
3717 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) {
3718 /* Use qctl operations for hidden quota files. */
3719 sb->s_qcop = &ext4_qctl_sysfile_operations; 3738 sb->s_qcop = &ext4_qctl_sysfile_operations;
3720 } 3739 else
3740 sb->s_qcop = &ext4_qctl_operations;
3721#endif 3741#endif
3722 memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid)); 3742 memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
3723 3743
@@ -3913,6 +3933,16 @@ no_journal:
3913 if (err) 3933 if (err)
3914 goto failed_mount7; 3934 goto failed_mount7;
3915 3935
3936#ifdef CONFIG_QUOTA
3937 /* Enable quota usage during mount. */
3938 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
3939 !(sb->s_flags & MS_RDONLY)) {
3940 err = ext4_enable_quotas(sb);
3941 if (err)
3942 goto failed_mount8;
3943 }
3944#endif /* CONFIG_QUOTA */
3945
3916 EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS; 3946 EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
3917 ext4_orphan_cleanup(sb, es); 3947 ext4_orphan_cleanup(sb, es);
3918 EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS; 3948 EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
@@ -3930,16 +3960,6 @@ no_journal:
3930 } else 3960 } else
3931 descr = "out journal"; 3961 descr = "out journal";
3932 3962
3933#ifdef CONFIG_QUOTA
3934 /* Enable quota usage during mount. */
3935 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
3936 !(sb->s_flags & MS_RDONLY)) {
3937 err = ext4_enable_quotas(sb);
3938 if (err)
3939 goto failed_mount8;
3940 }
3941#endif /* CONFIG_QUOTA */
3942
3943 if (test_opt(sb, DISCARD)) { 3963 if (test_opt(sb, DISCARD)) {
3944 struct request_queue *q = bdev_get_queue(sb->s_bdev); 3964 struct request_queue *q = bdev_get_queue(sb->s_bdev);
3945 if (!blk_queue_discard(q)) 3965 if (!blk_queue_discard(q))
@@ -3993,6 +4013,7 @@ failed_mount3:
3993 percpu_counter_destroy(&sbi->s_freeinodes_counter); 4013 percpu_counter_destroy(&sbi->s_freeinodes_counter);
3994 percpu_counter_destroy(&sbi->s_dirs_counter); 4014 percpu_counter_destroy(&sbi->s_dirs_counter);
3995 percpu_counter_destroy(&sbi->s_dirtyclusters_counter); 4015 percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
4016 percpu_counter_destroy(&sbi->s_extent_cache_cnt);
3996 if (sbi->s_mmp_tsk) 4017 if (sbi->s_mmp_tsk)
3997 kthread_stop(sbi->s_mmp_tsk); 4018 kthread_stop(sbi->s_mmp_tsk);
3998failed_mount2: 4019failed_mount2:
@@ -4538,6 +4559,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
4538 if (!old_opts.s_qf_names[i]) { 4559 if (!old_opts.s_qf_names[i]) {
4539 for (j = 0; j < i; j++) 4560 for (j = 0; j < i; j++)
4540 kfree(old_opts.s_qf_names[j]); 4561 kfree(old_opts.s_qf_names[j]);
4562 kfree(orig_data);
4541 return -ENOMEM; 4563 return -ENOMEM;
4542 } 4564 }
4543 } else 4565 } else
@@ -4816,9 +4838,12 @@ static int ext4_release_dquot(struct dquot *dquot)
4816 4838
4817static int ext4_mark_dquot_dirty(struct dquot *dquot) 4839static int ext4_mark_dquot_dirty(struct dquot *dquot)
4818{ 4840{
4841 struct super_block *sb = dquot->dq_sb;
4842 struct ext4_sb_info *sbi = EXT4_SB(sb);
4843
4819 /* Are we journaling quotas? */ 4844 /* Are we journaling quotas? */
4820 if (EXT4_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] || 4845 if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) ||
4821 EXT4_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) { 4846 sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) {
4822 dquot_mark_dquot_dirty(dquot); 4847 dquot_mark_dquot_dirty(dquot);
4823 return ext4_write_dquot(dquot); 4848 return ext4_write_dquot(dquot);
4824 } else { 4849 } else {