diff options
author | Jan Kara <jack@suse.cz> | 2014-02-20 17:02:27 +0100 |
---|---|---|
committer | Jiri Slaby <jslaby@suse.cz> | 2014-03-05 17:13:53 +0100 |
commit | d1ea22966e9187b0b92f878a02686cbad4ab0d50 (patch) | |
tree | ae33b17002fbc010259bc94d15884f5ef5d231c6 /fs/jfs | |
parent | fea84e6b1cbfec4e124e06633a0d6febe7fad69a (diff) |
quota: Fix race between dqput() and dquot_scan_active()
commit 1362f4ea20fa63688ba6026e586d9746ff13a846 upstream.
Currently last dqput() can race with dquot_scan_active() causing it to
call callback for an already deactivated dquot. The race is as follows:
CPU1 CPU2
dqput()
spin_lock(&dq_list_lock);
if (atomic_read(&dquot->dq_count) > 1) {
- not taken
if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
spin_unlock(&dq_list_lock);
->release_dquot(dquot);
if (atomic_read(&dquot->dq_count) > 1)
- not taken
dquot_scan_active()
spin_lock(&dq_list_lock);
if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
- not taken
atomic_inc(&dquot->dq_count);
spin_unlock(&dq_list_lock);
- proceeds to release dquot
ret = fn(dquot, priv);
- called for inactive dquot
Fix the problem by making sure possible ->release_dquot() is finished by
the time we call the callback and new calls to it will notice reference
dquot_scan_active() has taken and bail out.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Diffstat (limited to 'fs/jfs')
0 files changed, 0 insertions, 0 deletions