aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2017-05-21 22:31:23 -0400
committerTheodore Ts'o <tytso@mit.edu>2017-05-21 22:31:23 -0400
commit964edf66bf9ab70cb387b27946c0aef7b94c4d1b (patch)
tree1c7bc7711f0199abf6ccf5f87a9c45fbc1f261a8
parent08332893e37af6ae779367e78e444f8f9571511d (diff)
ext4: clear lockdep subtype for quota files on quota off
Quota files have special ranking of i_data_sem lock. We inform lockdep about it when turning on quotas however when turning quotas off, we don't clear the lockdep subclass from i_data_sem lock and thus when the inode gets later reused for a normal file or directory, lockdep gets confused and complains about possible deadlocks. Fix the problem by resetting lockdep subclass of i_data_sem on quota off. Cc: stable@vger.kernel.org Fixes: daf647d2dd58cec59570d7698a45b98e580f2076 Reported-and-tested-by: Ross Zwisler <ross.zwisler@linux.intel.com> Reviewed-by: Andreas Dilger <adilger@dilger.ca> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--fs/ext4/super.c14
1 files changed, 5 insertions, 9 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 0b177da9ea82..8f05c72bc4ec 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -848,14 +848,9 @@ static inline void ext4_quota_off_umount(struct super_block *sb)
848{ 848{
849 int type; 849 int type;
850 850
851 if (ext4_has_feature_quota(sb)) { 851 /* Use our quota_off function to clear inode flags etc. */
852 dquot_disable(sb, -1, 852 for (type = 0; type < EXT4_MAXQUOTAS; type++)
853 DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); 853 ext4_quota_off(sb, type);
854 } else {
855 /* Use our quota_off function to clear inode flags etc. */
856 for (type = 0; type < EXT4_MAXQUOTAS; type++)
857 ext4_quota_off(sb, type);
858 }
859} 854}
860#else 855#else
861static inline void ext4_quota_off_umount(struct super_block *sb) 856static inline void ext4_quota_off_umount(struct super_block *sb)
@@ -5485,7 +5480,7 @@ static int ext4_quota_off(struct super_block *sb, int type)
5485 goto out; 5480 goto out;
5486 5481
5487 err = dquot_quota_off(sb, type); 5482 err = dquot_quota_off(sb, type);
5488 if (err) 5483 if (err || ext4_has_feature_quota(sb))
5489 goto out_put; 5484 goto out_put;
5490 5485
5491 inode_lock(inode); 5486 inode_lock(inode);
@@ -5505,6 +5500,7 @@ static int ext4_quota_off(struct super_block *sb, int type)
5505out_unlock: 5500out_unlock:
5506 inode_unlock(inode); 5501 inode_unlock(inode);
5507out_put: 5502out_put:
5503 lockdep_set_quota_inode(inode, I_DATA_SEM_NORMAL);
5508 iput(inode); 5504 iput(inode);
5509 return err; 5505 return err;
5510out: 5506out: