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: daf647d2dd
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>
This commit is contained in:
Jan Kara 2017-05-21 22:31:23 -04:00 committed by Theodore Ts'o
parent 08332893e3
commit 964edf66bf

View File

@ -848,14 +848,9 @@ static inline void ext4_quota_off_umount(struct super_block *sb)
{
int type;
if (ext4_has_feature_quota(sb)) {
dquot_disable(sb, -1,
DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
} else {
/* Use our quota_off function to clear inode flags etc. */
for (type = 0; type < EXT4_MAXQUOTAS; type++)
ext4_quota_off(sb, type);
}
/* Use our quota_off function to clear inode flags etc. */
for (type = 0; type < EXT4_MAXQUOTAS; type++)
ext4_quota_off(sb, type);
}
#else
static 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)
goto out;
err = dquot_quota_off(sb, type);
if (err)
if (err || ext4_has_feature_quota(sb))
goto out_put;
inode_lock(inode);
@ -5505,6 +5500,7 @@ static int ext4_quota_off(struct super_block *sb, int type)
out_unlock:
inode_unlock(inode);
out_put:
lockdep_set_quota_inode(inode, I_DATA_SEM_NORMAL);
iput(inode);
return err;
out: