ext4: Disable dirty list tracking of dquots when journalling quotas
[sfrench/cifs-2.6.git] / fs / ext4 / super.c
index 0886fe82e9c49202311922680a33723c513c9983..16a877a0f30934467b897e624c7969c0f024f18d 100644 (file)
@@ -978,8 +978,6 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
        ei->i_es_shk_nr = 0;
        ei->i_es_shrink_lblk = 0;
        ei->i_reserved_data_blocks = 0;
-       ei->i_reserved_meta_blocks = 0;
-       ei->i_allocated_meta_blocks = 0;
        ei->i_da_metadata_calc_len = 0;
        ei->i_da_metadata_calc_last_lblock = 0;
        spin_lock_init(&(ei->i_block_reservation_lock));
@@ -5265,18 +5263,13 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
        return 0;
 }
 
-/* Helper function for writing quotas on sync - we need to start transaction
- * before quota file is locked for write. Otherwise the are possible deadlocks:
- * Process 1                         Process 2
- * ext4_create()                     quota_sync()
- *   jbd2_journal_start()                  write_dquot()
- *   dquot_initialize()                         down(dqio_mutex)
- *     down(dqio_mutex)                    jbd2_journal_start()
- *
- */
 
 #ifdef CONFIG_QUOTA
 
+/*
+ * Helper functions so that transaction is started before we acquire dqio_sem
+ * to keep correct lock ordering of transaction > dqio_sem
+ */
 static inline struct inode *dquot_to_inode(struct dquot *dquot)
 {
        return sb_dqopt(dquot->dq_sb)->files[dquot->dq_id.type];
@@ -5411,6 +5404,13 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
                        ext4_msg(sb, KERN_WARNING,
                                "Quota file not on filesystem root. "
                                "Journaled quota will not work");
+               sb_dqopt(sb)->flags |= DQUOT_NOLIST_DIRTY;
+       } else {
+               /*
+                * Clear the flag just in case mount options changed since
+                * last time.
+                */
+               sb_dqopt(sb)->flags &= ~DQUOT_NOLIST_DIRTY;
        }
 
        /*
@@ -5507,7 +5507,7 @@ static int ext4_enable_quotas(struct super_block *sb)
                test_opt(sb, PRJQUOTA),
        };
 
-       sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
+       sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE | DQUOT_NOLIST_DIRTY;
        for (type = 0; type < EXT4_MAXQUOTAS; type++) {
                if (qf_inums[type]) {
                        err = ext4_quota_enable(sb, type, QFMT_VFS_V1,