aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
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
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')
-rw-r--r--fs/ext4/balloc.c2
-rw-r--r--fs/ext4/dir.c2
-rw-r--r--fs/ext4/ext4.h1
-rw-r--r--fs/ext4/extents_status.c39
-rw-r--r--fs/ext4/mballoc.c8
-rw-r--r--fs/ext4/resize.c6
-rw-r--r--fs/ext4/super.c61
7 files changed, 66 insertions, 53 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 2f2e0da1a6b7..92e68b33fffd 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -635,7 +635,7 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb)
635 brelse(bitmap_bh); 635 brelse(bitmap_bh);
636 printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu" 636 printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu"
637 ", computed = %llu, %llu\n", 637 ", computed = %llu, %llu\n",
638 EXT4_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)), 638 EXT4_NUM_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)),
639 desc_count, bitmap_count); 639 desc_count, bitmap_count);
640 return bitmap_count; 640 return bitmap_count;
641#else 641#else
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 6dda04f05ef4..d8cd1f0f4661 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -334,7 +334,7 @@ static inline loff_t ext4_get_htree_eof(struct file *filp)
334 * 334 *
335 * For non-htree, ext4_llseek already chooses the proper max offset. 335 * For non-htree, ext4_llseek already chooses the proper max offset.
336 */ 336 */
337loff_t ext4_dir_llseek(struct file *file, loff_t offset, int whence) 337static loff_t ext4_dir_llseek(struct file *file, loff_t offset, int whence)
338{ 338{
339 struct inode *inode = file->f_mapping->host; 339 struct inode *inode = file->f_mapping->host;
340 int dx_dir = is_dx_dir(inode); 340 int dx_dir = is_dx_dir(inode);
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 6e16c1867959..4a01ba315262 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1309,6 +1309,7 @@ struct ext4_sb_info {
1309 /* Reclaim extents from extent status tree */ 1309 /* Reclaim extents from extent status tree */
1310 struct shrinker s_es_shrinker; 1310 struct shrinker s_es_shrinker;
1311 struct list_head s_es_lru; 1311 struct list_head s_es_lru;
1312 struct percpu_counter s_extent_cache_cnt;
1312 spinlock_t s_es_lru_lock ____cacheline_aligned_in_smp; 1313 spinlock_t s_es_lru_lock ____cacheline_aligned_in_smp;
1313}; 1314};
1314 1315
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c
index f768f4a98a2b..95796a1b7522 100644
--- a/fs/ext4/extents_status.c
+++ b/fs/ext4/extents_status.c
@@ -147,11 +147,12 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
147 ext4_lblk_t end); 147 ext4_lblk_t end);
148static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, 148static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei,
149 int nr_to_scan); 149 int nr_to_scan);
150static int ext4_es_reclaim_extents_count(struct super_block *sb);
151 150
152int __init ext4_init_es(void) 151int __init ext4_init_es(void)
153{ 152{
154 ext4_es_cachep = KMEM_CACHE(extent_status, SLAB_RECLAIM_ACCOUNT); 153 ext4_es_cachep = kmem_cache_create("ext4_extent_status",
154 sizeof(struct extent_status),
155 0, (SLAB_RECLAIM_ACCOUNT), NULL);
155 if (ext4_es_cachep == NULL) 156 if (ext4_es_cachep == NULL)
156 return -ENOMEM; 157 return -ENOMEM;
157 return 0; 158 return 0;
@@ -302,8 +303,10 @@ ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len,
302 /* 303 /*
303 * We don't count delayed extent because we never try to reclaim them 304 * We don't count delayed extent because we never try to reclaim them
304 */ 305 */
305 if (!ext4_es_is_delayed(es)) 306 if (!ext4_es_is_delayed(es)) {
306 EXT4_I(inode)->i_es_lru_nr++; 307 EXT4_I(inode)->i_es_lru_nr++;
308 percpu_counter_inc(&EXT4_SB(inode->i_sb)->s_extent_cache_cnt);
309 }
307 310
308 return es; 311 return es;
309} 312}
@@ -314,6 +317,7 @@ static void ext4_es_free_extent(struct inode *inode, struct extent_status *es)
314 if (!ext4_es_is_delayed(es)) { 317 if (!ext4_es_is_delayed(es)) {
315 BUG_ON(EXT4_I(inode)->i_es_lru_nr == 0); 318 BUG_ON(EXT4_I(inode)->i_es_lru_nr == 0);
316 EXT4_I(inode)->i_es_lru_nr--; 319 EXT4_I(inode)->i_es_lru_nr--;
320 percpu_counter_dec(&EXT4_SB(inode->i_sb)->s_extent_cache_cnt);
317 } 321 }
318 322
319 kmem_cache_free(ext4_es_cachep, es); 323 kmem_cache_free(ext4_es_cachep, es);
@@ -674,10 +678,11 @@ static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc)
674 int nr_to_scan = sc->nr_to_scan; 678 int nr_to_scan = sc->nr_to_scan;
675 int ret, nr_shrunk = 0; 679 int ret, nr_shrunk = 0;
676 680
677 trace_ext4_es_shrink_enter(sbi->s_sb, nr_to_scan); 681 ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt);
682 trace_ext4_es_shrink_enter(sbi->s_sb, nr_to_scan, ret);
678 683
679 if (!nr_to_scan) 684 if (!nr_to_scan)
680 return ext4_es_reclaim_extents_count(sbi->s_sb); 685 return ret;
681 686
682 INIT_LIST_HEAD(&scanned); 687 INIT_LIST_HEAD(&scanned);
683 688
@@ -705,9 +710,10 @@ static int ext4_es_shrink(struct shrinker *shrink, struct shrink_control *sc)
705 } 710 }
706 list_splice_tail(&scanned, &sbi->s_es_lru); 711 list_splice_tail(&scanned, &sbi->s_es_lru);
707 spin_unlock(&sbi->s_es_lru_lock); 712 spin_unlock(&sbi->s_es_lru_lock);
708 trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk);
709 713
710 return ext4_es_reclaim_extents_count(sbi->s_sb); 714 ret = percpu_counter_read_positive(&sbi->s_extent_cache_cnt);
715 trace_ext4_es_shrink_exit(sbi->s_sb, nr_shrunk, ret);
716 return ret;
711} 717}
712 718
713void ext4_es_register_shrinker(struct super_block *sb) 719void ext4_es_register_shrinker(struct super_block *sb)
@@ -751,25 +757,6 @@ void ext4_es_lru_del(struct inode *inode)
751 spin_unlock(&sbi->s_es_lru_lock); 757 spin_unlock(&sbi->s_es_lru_lock);
752} 758}
753 759
754static int ext4_es_reclaim_extents_count(struct super_block *sb)
755{
756 struct ext4_sb_info *sbi = EXT4_SB(sb);
757 struct ext4_inode_info *ei;
758 struct list_head *cur;
759 int nr_cached = 0;
760
761 spin_lock(&sbi->s_es_lru_lock);
762 list_for_each(cur, &sbi->s_es_lru) {
763 ei = list_entry(cur, struct ext4_inode_info, i_es_lru);
764 read_lock(&ei->i_es_lock);
765 nr_cached += ei->i_es_lru_nr;
766 read_unlock(&ei->i_es_lock);
767 }
768 spin_unlock(&sbi->s_es_lru_lock);
769 trace_ext4_es_reclaim_extents_count(sb, nr_cached);
770 return nr_cached;
771}
772
773static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei, 760static int __es_try_to_reclaim_extents(struct ext4_inode_info *ei,
774 int nr_to_scan) 761 int nr_to_scan)
775{ 762{
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 6540ebe058e3..7bb713a46fe4 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -3419,7 +3419,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
3419 win = offs; 3419 win = offs;
3420 3420
3421 ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical - 3421 ac->ac_b_ex.fe_logical = ac->ac_o_ex.fe_logical -
3422 EXT4_B2C(sbi, win); 3422 EXT4_NUM_B2C(sbi, win);
3423 BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical); 3423 BUG_ON(ac->ac_o_ex.fe_logical < ac->ac_b_ex.fe_logical);
3424 BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len); 3424 BUG_ON(ac->ac_o_ex.fe_len > ac->ac_b_ex.fe_len);
3425 } 3425 }
@@ -4565,7 +4565,7 @@ do_more:
4565 EXT4_BLOCKS_PER_GROUP(sb); 4565 EXT4_BLOCKS_PER_GROUP(sb);
4566 count -= overflow; 4566 count -= overflow;
4567 } 4567 }
4568 count_clusters = EXT4_B2C(sbi, count); 4568 count_clusters = EXT4_NUM_B2C(sbi, count);
4569 bitmap_bh = ext4_read_block_bitmap(sb, block_group); 4569 bitmap_bh = ext4_read_block_bitmap(sb, block_group);
4570 if (!bitmap_bh) { 4570 if (!bitmap_bh) {
4571 err = -EIO; 4571 err = -EIO;
@@ -4807,11 +4807,11 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
4807 ext4_group_desc_csum_set(sb, block_group, desc); 4807 ext4_group_desc_csum_set(sb, block_group, desc);
4808 ext4_unlock_group(sb, block_group); 4808 ext4_unlock_group(sb, block_group);
4809 percpu_counter_add(&sbi->s_freeclusters_counter, 4809 percpu_counter_add(&sbi->s_freeclusters_counter,
4810 EXT4_B2C(sbi, blocks_freed)); 4810 EXT4_NUM_B2C(sbi, blocks_freed));
4811 4811
4812 if (sbi->s_log_groups_per_flex) { 4812 if (sbi->s_log_groups_per_flex) {
4813 ext4_group_t flex_group = ext4_flex_group(sbi, block_group); 4813 ext4_group_t flex_group = ext4_flex_group(sbi, block_group);
4814 atomic_add(EXT4_B2C(sbi, blocks_freed), 4814 atomic_add(EXT4_NUM_B2C(sbi, blocks_freed),
4815 &sbi->s_flex_groups[flex_group].free_clusters); 4815 &sbi->s_flex_groups[flex_group].free_clusters);
4816 } 4816 }
4817 4817
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index c7f4d7584669..b2c8ee56eb98 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1247,7 +1247,7 @@ static int ext4_setup_new_descs(handle_t *handle, struct super_block *sb,
1247 1247
1248 ext4_inode_table_set(sb, gdp, group_data->inode_table); 1248 ext4_inode_table_set(sb, gdp, group_data->inode_table);
1249 ext4_free_group_clusters_set(sb, gdp, 1249 ext4_free_group_clusters_set(sb, gdp,
1250 EXT4_B2C(sbi, group_data->free_blocks_count)); 1250 EXT4_NUM_B2C(sbi, group_data->free_blocks_count));
1251 ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb)); 1251 ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
1252 if (ext4_has_group_desc_csum(sb)) 1252 if (ext4_has_group_desc_csum(sb))
1253 ext4_itable_unused_set(sb, gdp, 1253 ext4_itable_unused_set(sb, gdp,
@@ -1349,7 +1349,7 @@ static void ext4_update_super(struct super_block *sb,
1349 1349
1350 /* Update the free space counts */ 1350 /* Update the free space counts */
1351 percpu_counter_add(&sbi->s_freeclusters_counter, 1351 percpu_counter_add(&sbi->s_freeclusters_counter,
1352 EXT4_B2C(sbi, free_blocks)); 1352 EXT4_NUM_B2C(sbi, free_blocks));
1353 percpu_counter_add(&sbi->s_freeinodes_counter, 1353 percpu_counter_add(&sbi->s_freeinodes_counter,
1354 EXT4_INODES_PER_GROUP(sb) * flex_gd->count); 1354 EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
1355 1355
@@ -1360,7 +1360,7 @@ static void ext4_update_super(struct super_block *sb,
1360 sbi->s_log_groups_per_flex) { 1360 sbi->s_log_groups_per_flex) {
1361 ext4_group_t flex_group; 1361 ext4_group_t flex_group;
1362 flex_group = ext4_flex_group(sbi, group_data[0].group); 1362 flex_group = ext4_flex_group(sbi, group_data[0].group);
1363 atomic_add(EXT4_B2C(sbi, free_blocks), 1363 atomic_add(EXT4_NUM_B2C(sbi, free_blocks),
1364 &sbi->s_flex_groups[flex_group].free_clusters); 1364 &sbi->s_flex_groups[flex_group].free_clusters);
1365 atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count, 1365 atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count,
1366 &sbi->s_flex_groups[flex_group].free_inodes); 1366 &sbi->s_flex_groups[flex_group].free_inodes);
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 {