Commit e93ab40
committed
quota: Fix race of dquot_scan_active() with quota deactivation
dquot_scan_active() can race with quota deactivation in
quota_release_workfn() like:
CPU0 (quota_release_workfn) CPU1 (dquot_scan_active)
============================== ==============================
spin_lock(&dq_list_lock);
list_replace_init(
&releasing_dquots, &rls_head);
/* dquot X on rls_head,
dq_count == 0,
DQ_ACTIVE_B still set */
spin_unlock(&dq_list_lock);
synchronize_srcu(&dquot_srcu);
spin_lock(&dq_list_lock);
list_for_each_entry(dquot,
&inuse_list, dq_inuse) {
/* finds dquot X */
dquot_active(X) -> true
atomic_inc(&X->dq_count);
}
spin_unlock(&dq_list_lock);
spin_lock(&dq_list_lock);
dquot = list_first_entry(&rls_head);
WARN_ON_ONCE(atomic_read(&dquot->dq_count));
The problem is not only a cosmetic one as under memory pressure the
caller of dquot_scan_active() can end up working on freed dquot.
Fix the problem by making sure the dquot is removed from releasing list
when we acquire a reference to it.
Fixes: 869b6ea ("quota: Fix slow quotaoff")
Reported-by: Sam Sun <[email protected]>
Link: https://lore.kernel.org/all/CAEkJfYPTt3uP1vAYnQ5V2ZWn5O9PLhhGi5HbOcAzyP9vbXyjeg@mail.gmail.com
Signed-off-by: Jan Kara <[email protected]>1 parent 08841b0 commit e93ab40
2 files changed
Lines changed: 31 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
363 | 363 | | |
364 | 364 | | |
365 | 365 | | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
366 | 391 | | |
367 | 392 | | |
368 | 393 | | |
| |||
641 | 666 | | |
642 | 667 | | |
643 | 668 | | |
644 | | - | |
645 | | - | |
| 669 | + | |
646 | 670 | | |
647 | 671 | | |
648 | 672 | | |
649 | 673 | | |
650 | 674 | | |
651 | | - | |
652 | | - | |
| 675 | + | |
| 676 | + | |
653 | 677 | | |
654 | 678 | | |
655 | 679 | | |
| |||
717 | 741 | | |
718 | 742 | | |
719 | 743 | | |
720 | | - | |
| 744 | + | |
721 | 745 | | |
722 | 746 | | |
723 | 747 | | |
| |||
963 | 987 | | |
964 | 988 | | |
965 | 989 | | |
966 | | - | |
967 | | - | |
968 | | - | |
| 990 | + | |
969 | 991 | | |
970 | 992 | | |
971 | 993 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
| 47 | + | |
55 | 48 | | |
56 | 49 | | |
57 | 50 | | |
| |||
0 commit comments