summaryrefslogtreecommitdiffstats
path: root/src/mds/flock.cc
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2017-06-03 06:06:10 +0200
committerYan, Zheng <zyan@redhat.com>2017-06-03 06:27:00 +0200
commit0d71c6120e61f31b803c3fb6488fc7e97134e348 (patch)
tree93643e2a60528f5f3e639f652ba56baa741a2993 /src/mds/flock.cc
parentmds/flock: properly update ceph_lock_state_t::client_waiting_lock_counts (diff)
downloadceph-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.cc53
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++);
}