]> git.baikalelectronics.ru Git - kernel.git/commitdiff
quota: Generate warnings for DQUOT_SPACE_NOFAIL allocations
authorJan Kara <jack@suse.cz>
Tue, 10 Oct 2017 12:40:42 +0000 (14:40 +0200)
committerJan Kara <jack@suse.cz>
Tue, 10 Oct 2017 15:24:46 +0000 (17:24 +0200)
Eryu has reported that since commit cecf2d53cd45 "quota: Reduce
contention on dq_data_lock" test generic/233 occasionally fails. This is
caused by the fact that since that commit we don't generate warning and
set grace time for quota allocations that have DQUOT_SPACE_NOFAIL set
(these are for example some metadata allocations in ext4). We need these
allocations to behave regularly wrt warning generation and grace time
setting so fix the code to return to the original behavior.

Reported-and-tested-by: Eryu Guan <eguan@redhat.com>
CC: stable@vger.kernel.org
Fixes: cecf2d53cd456288b4d3c8b7de59cc98dadad2ac
Signed-off-by: Jan Kara <jack@suse.cz>
fs/quota/dquot.c

index 50b0556a124f2508531ce9e6fc61721aeb179cc8..52ad15192e724c00db1a6a3e2d49d0842b62ce6a 100644 (file)
@@ -1297,21 +1297,18 @@ static int dquot_add_space(struct dquot *dquot, qsize_t space,
        spin_lock(&dquot->dq_dqb_lock);
        if (!sb_has_quota_limits_enabled(sb, dquot->dq_id.type) ||
            test_bit(DQ_FAKE_B, &dquot->dq_flags))
-               goto add;
+               goto finish;
 
        tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace
                + space + rsv_space;
 
-       if (flags & DQUOT_SPACE_NOFAIL)
-               goto add;
-
        if (dquot->dq_dqb.dqb_bhardlimit &&
            tspace > dquot->dq_dqb.dqb_bhardlimit &&
             !ignore_hardlimit(dquot)) {
                if (flags & DQUOT_SPACE_WARN)
                        prepare_warning(warn, dquot, QUOTA_NL_BHARDWARN);
                ret = -EDQUOT;
-               goto out;
+               goto finish;
        }
 
        if (dquot->dq_dqb.dqb_bsoftlimit &&
@@ -1322,7 +1319,7 @@ static int dquot_add_space(struct dquot *dquot, qsize_t space,
                if (flags & DQUOT_SPACE_WARN)
                        prepare_warning(warn, dquot, QUOTA_NL_BSOFTLONGWARN);
                ret = -EDQUOT;
-               goto out;
+               goto finish;
        }
 
        if (dquot->dq_dqb.dqb_bsoftlimit &&
@@ -1338,13 +1335,21 @@ static int dquot_add_space(struct dquot *dquot, qsize_t space,
                         * be always printed
                         */
                        ret = -EDQUOT;
-                       goto out;
+                       goto finish;
                }
        }
-add:
-       dquot->dq_dqb.dqb_rsvspace += rsv_space;
-       dquot->dq_dqb.dqb_curspace += space;
-out:
+finish:
+       /*
+        * We have to be careful and go through warning generation & grace time
+        * setting even if DQUOT_SPACE_NOFAIL is set. That's why we check it
+        * only here...
+        */
+       if (flags & DQUOT_SPACE_NOFAIL)
+               ret = 0;
+       if (!ret) {
+               dquot->dq_dqb.dqb_rsvspace += rsv_space;
+               dquot->dq_dqb.dqb_curspace += space;
+       }
        spin_unlock(&dquot->dq_dqb_lock);
        return ret;
 }