From: "Yan, Zheng" <zheng.z.yan@xxxxxxxxx> Current code allows multiple MDRequests to concurrently acquire a remote lock. But a lock ACK message wakes all requests because they were all put to the same waiting queue. One request gets the lock, the rest requests will re-send the OP_WRLOCK/OPWRLOCK slave requests and trigger assertion on remote MDS. The fix is disable concurrently acquiring remote lock, send OP_WRLOCK/OPWRLOCK slave request only if there is no on-going slave request. Signed-off-by: Yan, Zheng <zheng.z.yan@xxxxxxxxx> --- src/mds/Locker.cc | 54 ++++++++++++++++++++++++++++++++---------------------- src/mds/Server.cc | 2 ++ 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index dbf4452..cba894b 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -532,14 +532,18 @@ void Locker::cancel_locking(Mutation *mut, set<CInode*> *pneed_issue) assert(lock); dout(10) << "cancel_locking " << *lock << " on " << *mut << dendl; - if (lock->get_type() != CEPH_LOCK_DN) { - bool need_issue = false; - if (lock->get_state() == LOCK_PREXLOCK) - _finish_xlock(lock, &need_issue); - if (lock->is_stable()) - eval(lock, &need_issue); - if (need_issue) - pneed_issue->insert((CInode *)lock->get_parent()); + if (lock->get_parent()->is_auth()) { + if (lock->get_type() != CEPH_LOCK_DN) { + bool need_issue = false; + if (lock->get_state() == LOCK_PREXLOCK) + _finish_xlock(lock, &need_issue); + if (lock->is_stable()) + eval(lock, &need_issue); + if (need_issue) + pneed_issue->insert((CInode *)lock->get_parent()); + } + } else { + lock->finish_waiters(SimpleLock::WAIT_REMOTEXLOCK); } mut->finish_locking(lock); } @@ -1314,14 +1318,17 @@ void Locker::remote_wrlock_start(SimpleLock *lock, int target, MDRequest *mut) new C_MDS_RetryRequest(mdcache, mut)); return; } - + // send lock request - mut->more()->slaves.insert(target); - MMDSSlaveRequest *r = new MMDSSlaveRequest(mut->reqid, mut->attempt, - MMDSSlaveRequest::OP_WRLOCK); - r->set_lock_type(lock->get_type()); - lock->get_parent()->set_object_info(r->get_object_info()); - mds->send_message_mds(r, target); + if (!lock->is_waiter_for(SimpleLock::WAIT_REMOTEXLOCK)) { + mut->start_locking(lock); + mut->more()->slaves.insert(target); + MMDSSlaveRequest *r = new MMDSSlaveRequest(mut->reqid, mut->attempt, + MMDSSlaveRequest::OP_WRLOCK); + r->set_lock_type(lock->get_type()); + lock->get_parent()->set_object_info(r->get_object_info()); + mds->send_message_mds(r, target); + } // wait lock->add_waiter(SimpleLock::WAIT_REMOTEXLOCK, new C_MDS_RetryRequest(mdcache, mut)); @@ -1398,13 +1405,16 @@ bool Locker::xlock_start(SimpleLock *lock, MDRequest *mut) } // send lock request - int auth = lock->get_parent()->authority().first; - mut->more()->slaves.insert(auth); - MMDSSlaveRequest *r = new MMDSSlaveRequest(mut->reqid, mut->attempt, - MMDSSlaveRequest::OP_XLOCK); - r->set_lock_type(lock->get_type()); - lock->get_parent()->set_object_info(r->get_object_info()); - mds->send_message_mds(r, auth); + if (!lock->is_waiter_for(SimpleLock::WAIT_REMOTEXLOCK)) { + mut->start_locking(lock); + int auth = lock->get_parent()->authority().first; + mut->more()->slaves.insert(auth); + MMDSSlaveRequest *r = new MMDSSlaveRequest(mut->reqid, mut->attempt, + MMDSSlaveRequest::OP_XLOCK); + r->set_lock_type(lock->get_type()); + lock->get_parent()->set_object_info(r->get_object_info()); + mds->send_message_mds(r, auth); + } // wait lock->add_waiter(SimpleLock::WAIT_REMOTEXLOCK, new C_MDS_RetryRequest(mdcache, mut)); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index c5793e5..517339f 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -1324,6 +1324,7 @@ void Server::handle_slave_request_reply(MMDSSlaveRequest *m) dout(10) << "got remote xlock on " << *lock << " on " << *lock->get_parent() << dendl; mdr->xlocks.insert(lock); mdr->locks.insert(lock); + mdr->finish_locking(lock); lock->get_xlock(mdr, mdr->get_client()); lock->finish_waiters(SimpleLock::WAIT_REMOTEXLOCK); } @@ -1338,6 +1339,7 @@ void Server::handle_slave_request_reply(MMDSSlaveRequest *m) dout(10) << "got remote wrlock on " << *lock << " on " << *lock->get_parent() << dendl; mdr->remote_wrlocks[lock] = from; mdr->locks.insert(lock); + mdr->finish_locking(lock); lock->finish_waiters(SimpleLock::WAIT_REMOTEXLOCK); } break; -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html