]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: wait for client to release shared cap when re-acquiring xlock 27024/head
authorYan, Zheng <zyan@redhat.com>
Thu, 28 Feb 2019 13:36:28 +0000 (21:36 +0800)
committerPrashant D <pdhange@redhat.com>
Mon, 18 Mar 2019 00:17:19 +0000 (20:17 -0400)
MDS may revoke shared cap from xlocker client during 'LOCK_XLOCKDONE ->
LOCK_LOCK_XLOCK' state transition.

Fixes: http://tracker.ceph.com/issues/38491
Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
(cherry picked from commit 218e784f2eb1eec6bbb7910b5432f7f36263dbe7)

Conflicts:
src/mds/SimpleLock.h : Resovled in put_xlock

src/mds/Locker.cc
src/mds/SimpleLock.h

index ce50715973a95b428b7293353f4e9c587a633d53..b2b4c21dc45cd936c539cf5c0cb099122e70e6f1 100644 (file)
@@ -759,8 +759,7 @@ void Locker::cancel_locking(MutationImpl *mut, set<CInode*> *pneed_issue)
     bool need_issue = false;
     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) {
+    } else if (lock->get_state() == LOCK_LOCK_XLOCK) {
       lock->set_state(LOCK_XLOCKDONE);
       eval_gather(lock, true, &need_issue);
     }
@@ -1644,11 +1643,17 @@ bool Locker::xlock_start(SimpleLock *lock, MDRequestRef& mut)
   dout(7) << "xlock_start on " << *lock << " on " << *lock->get_parent() << dendl;
   client_t client = mut->get_client();
 
+  CInode *in = nullptr;
+  if (lock->get_cap_shift())
+    in = static_cast<CInode *>(lock->get_parent());
+
   // auth?
   if (lock->get_parent()->is_auth()) {
     // auth
     while (1) {
-      if (lock->can_xlock(client)) {
+      if (lock->can_xlock(client) &&
+         !(lock->get_state() == LOCK_LOCK_XLOCK &&     // client is not xlocker or
+           in && in->issued_caps_need_gather(lock))) { // xlocker does not hold shared cap
        lock->set_state(LOCK_XLOCK);
        lock->get_xlock(mut, client);
        mut->xlocks.insert(lock);
@@ -1657,11 +1662,9 @@ bool Locker::xlock_start(SimpleLock *lock, MDRequestRef& mut)
        return true;
       }
       
-      if (lock->get_type() == CEPH_LOCK_IFILE) {
-       CInode *in = static_cast<CInode*>(lock->get_parent());
-       if (in->state_test(CInode::STATE_RECOVERING)) {
-         mds->mdcache->recovery_queue.prioritize(in);
-       }
+      if (lock->get_type() == CEPH_LOCK_IFILE &&
+         in->state_test(CInode::STATE_RECOVERING)) {
+       mds->mdcache->recovery_queue.prioritize(in);
       }
 
       if (!lock->is_stable() && (lock->get_state() != LOCK_XLOCKDONE ||
@@ -1782,9 +1785,8 @@ void Locker::xlock_finish(SimpleLock *lock, MutationImpl *mut, bool *pneed_issue
                         SimpleLock::WAIT_WR | 
                         SimpleLock::WAIT_RD, 0); 
   } else {
-    if (lock->get_num_xlocks() == 0) {
-      if (lock->get_state() == LOCK_LOCK_XLOCK)
-       lock->set_state(LOCK_XLOCKDONE);
+    if (lock->get_num_xlocks() == 0 &&
+        lock->get_state() != LOCK_LOCK_XLOCK) { // no one is taking xlock
       _finish_xlock(lock, xlocker, &do_issue);
     }
   }
index 2c0ff9327c3a48d8425c4601a032babb36b69277..8e5c828fb201941720b50eb1da18c9aa46a1b05b 100644 (file)
@@ -506,8 +506,9 @@ public:
   }
   void put_xlock() {
     assert(state == LOCK_XLOCK || state == LOCK_XLOCKDONE ||
-          state == LOCK_XLOCKSNAP || is_locallock() ||
-          state == LOCK_LOCK /* if we are a master of a slave */);
+          state == LOCK_XLOCKSNAP || state == LOCK_LOCK_XLOCK ||
+          state == LOCK_LOCK  || /* if we are a master of a slave */
+          is_locallock());
     --more()->num_xlock;
     parent->put(MDSCacheObject::PIN_LOCK);
     if (more()->num_xlock == 0) {