]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: avoid issuing caps when inode is frozen
authorYan, Zheng <zheng.z.yan@intel.com>
Sat, 9 Nov 2013 03:07:27 +0000 (11:07 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Mon, 16 Dec 2013 04:15:23 +0000 (12:15 +0800)
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/Locker.cc
src/mds/Locker.h

index cded965bcb513ec4f206d898d7e0a3d3fcf6358a..b2e44dbec69e5118f1849fc61b46318fec0bf1cf 100644 (file)
@@ -2573,6 +2573,38 @@ void Locker::process_request_cap_release(MDRequest *mdr, client_t client, const
     mdr->cap_releases[in->vino()] = cap->get_last_seq();
 }
 
+class C_Locker_RetryKickIssueCaps : public Context {
+  Locker *locker;
+  CInode *in;
+  client_t client;
+  ceph_seq_t seq;
+public:
+  C_Locker_RetryKickIssueCaps(Locker *l, CInode *i, client_t c, ceph_seq_t s) :
+    locker(l), in(i), client(c), seq(s) {
+    in->get(CInode::PIN_PTRWAITER);
+  }
+  void finish(int r) {
+    locker->kick_issue_caps(in, client, seq);
+    in->put(CInode::PIN_PTRWAITER);
+  }
+};
+
+void Locker::kick_issue_caps(CInode *in, client_t client, ceph_seq_t seq)
+{
+  Capability *cap = in->get_client_cap(client);
+  if (!cap || cap->get_last_sent() != seq)
+    return;
+  if (in->is_frozen()) {
+    dout(10) << "kick_issue_caps waiting for unfreeze on " << *in << dendl;
+    in->add_waiter(CInode::WAIT_UNFREEZE,
+       new C_Locker_RetryKickIssueCaps(this, in, client, seq));
+    return;
+  }
+  dout(10) << "kick_issue_caps released at current seq " << seq
+    << ", reissuing" << dendl;
+  issue_caps(in, cap);
+}
+
 void Locker::kick_cap_releases(MDRequest *mdr)
 {
   client_t client = mdr->get_client();
@@ -2582,18 +2614,10 @@ void Locker::kick_cap_releases(MDRequest *mdr)
     CInode *in = mdcache->get_inode(p->first);
     if (!in)
       continue;
-    Capability *cap = in->get_client_cap(client);
-    if (!cap)
-      continue;
-    if (cap->get_last_sent() == p->second) {
-      dout(10) << "kick_cap_releases released at current seq " << p->second
-              << ", reissuing" << dendl;
-      issue_caps(in, cap);
-    }
+    kick_issue_caps(in, client, p->second);
   }
 }
 
-
 static uint64_t calc_bounding(uint64_t t)
 {
   t |= t >> 1;
index 0c9931a473457e79bfde577cc1c25c7b8abf9259..466f7c92f81bebc7ceb8a2aa51755e5c99394f64 100644 (file)
@@ -213,6 +213,7 @@ public:
                                   const string &dname);
 
   void kick_cap_releases(MDRequest *mdr);
+  void kick_issue_caps(CInode *in, client_t client, ceph_seq_t seq);
 
   void remove_client_cap(CInode *in, client_t client);