diff options
author | Yan, Zheng <zyan@redhat.com> | 2017-06-03 06:06:10 +0200 |
---|---|---|
committer | Yan, Zheng <zyan@redhat.com> | 2017-06-03 06:27:00 +0200 |
commit | 0d71c6120e61f31b803c3fb6488fc7e97134e348 (patch) | |
tree | 93643e2a60528f5f3e639f652ba56baa741a2993 /src/mds/flock.cc | |
parent | mds/flock: properly update ceph_lock_state_t::client_waiting_lock_counts (diff) | |
download | ceph-0d71c6120e61f31b803c3fb6488fc7e97134e348.tar.xz ceph-0d71c6120e61f31b803c3fb6488fc7e97134e348.zip |
mds/flock: properly remove item from global_waiting_locks
ceph_lock_state_t::remove_waiting() uses wrong key to search
global_waiting_locks. It should use item in waiting_locks as
key.
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Diffstat (limited to 'src/mds/flock.cc')
-rw-r--r-- | src/mds/flock.cc | 53 |
1 files changed, 20 insertions, 33 deletions
diff --git a/src/mds/flock.cc b/src/mds/flock.cc index a34dc9153fc..2382322bce4 100644 --- a/src/mds/flock.cc +++ b/src/mds/flock.cc @@ -10,20 +10,25 @@ static multimap<ceph_filelock, ceph_lock_state_t*> global_waiting_locks; +static void remove_global_waiting(ceph_filelock &fl, ceph_lock_state_t *lock_state) +{ + for (auto p = global_waiting_locks.find(fl); + p != global_waiting_locks.end(); ) { + if (p->first != fl) + break; + if (p->second == lock_state) { + global_waiting_locks.erase(p); + break; + } + ++p; + } +} + ceph_lock_state_t::~ceph_lock_state_t() { if (type == CEPH_LOCK_FCNTL) { for (auto p = waiting_locks.begin(); p != waiting_locks.end(); ++p) { - for (auto q = global_waiting_locks.find(p->second); - q != global_waiting_locks.end(); ) { - if (q->first != p->second) - break; - if (q->second == this) { - global_waiting_locks.erase(q); - break; - } - ++q; - } + remove_global_waiting(p->second, this); } } } @@ -50,6 +55,9 @@ void ceph_lock_state_t::remove_waiting(const ceph_filelock& fl) break; if (p->second.length == fl.length && ceph_filelock_owner_equal(p->second, fl)) { + if (type == CEPH_LOCK_FCNTL) { + remove_global_waiting(p->second, this); + } waiting_locks.erase(p); --client_waiting_lock_counts[(client_t)fl.client]; if (!client_waiting_lock_counts[(client_t)fl.client]) { @@ -59,19 +67,6 @@ void ceph_lock_state_t::remove_waiting(const ceph_filelock& fl) } ++p; } - - if (type == CEPH_LOCK_FCNTL) { - for (auto q = global_waiting_locks.find(fl); - q != global_waiting_locks.end(); ) { - if (q->first != fl) - break; - if (q->second == this) { - global_waiting_locks.erase(q); - break; - } - ++q; - } - } } bool ceph_lock_state_t::is_deadlock(const ceph_filelock& fl, @@ -319,16 +314,8 @@ bool ceph_lock_state_t::remove_all_from (client_t client) ++iter; continue; } - - for (auto p = global_waiting_locks.find(iter->second); - p != global_waiting_locks.end(); ) { - if (p->first != iter->second) - break; - if (p->second == this) { - global_waiting_locks.erase(p); - break; - } - ++p; + if (type == CEPH_LOCK_FCNTL) { + remove_global_waiting(iter->second, this); } waiting_locks.erase(iter++); } |