summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2013-07-17 13:52:18 +0800
committerYan, Zheng <zheng.z.yan@intel.com>2013-08-05 11:09:07 +0800
commitf86828d149f0ae89f49faa83f2a04ee711a22b23 (patch)
tree5b5b1c711248d2698d706767896202c7898c51ea
parent63a21b41340a236a258e9ae82a823c24c30cf0dd (diff)
downloadceph-f86828d149f0ae89f49faa83f2a04ee711a22b23.tar.gz
mds: handle "state == LOCK_LOCK_XLOCK" when cancelling xlock
If we find lock state is LOCK_LOCK_XLOCK when cancelling xlock, set lock state to LOCK_XLOCK_DONE and call Locker::eval_gather(). This makes sure the lock will eventually transit to a stable state. (LOCK_XLOCK_DONE's next state is stable) Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
-rw-r--r--src/mds/Locker.cc12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc
index d2d47fbb55d..efb5a741362 100644
--- a/src/mds/Locker.cc
+++ b/src/mds/Locker.cc
@@ -544,8 +544,13 @@ void Locker::cancel_locking(Mutation *mut, set<CInode*> *pneed_issue)
if (lock->get_parent()->is_auth()) {
bool need_issue = false;
- if (lock->get_state() == LOCK_PREXLOCK)
+ if (lock->get_state() == LOCK_PREXLOCK) {
_finish_xlock(lock, -1, &need_issue);
+ } else if (lock->get_state() == LOCK_LOCK_XLOCK &&
+ lock->get_num_xlocks() == 0) {
+ lock->set_state(LOCK_XLOCKDONE);
+ eval_gather(lock, true, &need_issue);
+ }
if (need_issue)
pneed_issue->insert(static_cast<CInode *>(lock->get_parent()));
}
@@ -1516,8 +1521,11 @@ void Locker::xlock_finish(SimpleLock *lock, Mutation *mut, bool *pneed_issue)
SimpleLock::WAIT_WR |
SimpleLock::WAIT_RD, 0);
} else {
- if (lock->get_num_xlocks() == 0)
+ if (lock->get_num_xlocks() == 0) {
+ if (lock->get_state() == LOCK_LOCK_XLOCK)
+ lock->set_state(LOCK_XLOCKDONE);
_finish_xlock(lock, xlocker, &do_issue);
+ }
}
if (do_issue) {