quota: Fix bogus warning in dquot_disable()
authorJan Kara <jack@suse.cz>
Mon, 19 Dec 2016 13:01:39 +0000 (14:01 +0100)
committerJan Kara <jack@suse.cz>
Mon, 19 Dec 2016 13:01:39 +0000 (14:01 +0100)
dquot_disable() was warning when sb_has_quota_loaded() was true when
invalidating page cache for quota files. The thinking behind this
warning was that we must have raced with somebody else turning quotas on
and this should not happen because all places modifying quota state must
hold s_umount exclusively now. However sb_has_quota_loaded() can be also
true at this point when we are just suspending quotas on remount
read-only. Just restore the behavior to situation before commit
c3b004460d77 ("quota: Remove dqonoff_mutex") which introduced the
warning.

The code in dquot_disable() can be further simplified with the new
locking of quota state changes however let's leave that to a separate
commit that can get more testing exposure.

Fixes: c3b004460d77bf3f980d877be539016f2df4df12
Signed-off-by: Jan Kara <jack@suse.cz>
fs/quota/dquot.c

index 550f78f2b7c7ae71479f1a3158b836f3955d285e..1ed5494aa773f354a50d26ed4e2eca063bacf80a 100644 (file)
@@ -2184,8 +2184,8 @@ int dquot_disable(struct super_block *sb, int type, unsigned int flags)
         * must also discard the blockdev buffers so that we see the
         * changes done by userspace on the next quotaon() */
        for (cnt = 0; cnt < MAXQUOTAS; cnt++)
         * must also discard the blockdev buffers so that we see the
         * changes done by userspace on the next quotaon() */
        for (cnt = 0; cnt < MAXQUOTAS; cnt++)
-               if (toputinode[cnt]) {
-                       WARN_ON_ONCE(sb_has_quota_loaded(sb, cnt));
+               /* This can happen when suspending quotas on remount-ro... */
+               if (toputinode[cnt] && !sb_has_quota_loaded(sb, cnt)) {
                        inode_lock(toputinode[cnt]);
                        toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
                                  S_NOATIME | S_NOQUOTA);
                        inode_lock(toputinode[cnt]);
                        toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
                                  S_NOATIME | S_NOQUOTA);