]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: async version of AioImageRequestWQ::block_writes
authorJason Dillaman <dillaman@redhat.com>
Fri, 31 Jul 2015 01:34:51 +0000 (21:34 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 17 Nov 2015 19:56:23 +0000 (14:56 -0500)
Snapshot create will uses the async version to block write ops
prior to creating the new snapshot context.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/AioImageRequestWQ.cc
src/librbd/AioImageRequestWQ.h

index 789865348bb36521644460fbdf971c9f83ecea7d..ff9d8e4a3e1fd3870c39fda994db0445986502c1 100644 (file)
@@ -152,17 +152,25 @@ void AioImageRequestWQ::aio_flush(AioCompletion *c) {
 }
 
 void AioImageRequestWQ::block_writes() {
+  C_SaferCond cond_ctx;
+  block_writes(&cond_ctx);
+  cond_ctx.wait();
+}
+
+void AioImageRequestWQ::block_writes(Context *on_blocked) {
   CephContext *cct = m_image_ctx.cct;
 
-  Mutex::Locker locker(m_lock);
-  ++m_write_blockers;
-  ldout(cct, 5) << __func__ << ": " << &m_image_ctx << ", "
-                << "num=" << m_write_blockers << dendl;
-  if (m_write_blockers == 1) {
-    while (m_in_progress_writes > 0) {
-      m_cond.Wait(m_lock);
+  {
+    Mutex::Locker locker(m_lock);
+    ++m_write_blockers;
+    ldout(cct, 5) << __func__ << ": " << &m_image_ctx << ", "
+                  << "num=" << m_write_blockers << dendl;
+    if (m_in_progress_writes > 0) {
+      m_write_blocker_contexts.push_back(on_blocked);
+      return;
     }
   }
+  on_blocked->complete(0);
 }
 
 void AioImageRequestWQ::unblock_writes() {
@@ -222,6 +230,7 @@ void AioImageRequestWQ::process(AioImageRequest *req) {
     req->send();
   }
 
+  Contexts contexts;
   {
     Mutex::Locker locker(m_lock);
     if (req->is_write_op()) {
@@ -230,11 +239,15 @@ void AioImageRequestWQ::process(AioImageRequest *req) {
 
       assert(m_in_progress_writes > 0);
       if (--m_in_progress_writes == 0) {
-        m_cond.Signal();
+        contexts.swap(m_write_blocker_contexts);
       }
     }
   }
   delete req;
+
+  for (Contexts::iterator it = contexts.begin(); it != contexts.end(); ++it) {
+    (*it)->complete(0);
+  }
 }
 
 bool AioImageRequestWQ::is_journal_required() const {
index 20169f59002278f9c7107f08fe6ee6aa1a23c8bc..f668c9f03f12111f3c38a86c6e74d6a00839292d 100644 (file)
@@ -45,6 +45,7 @@ public:
   }
 
   void block_writes();
+  void block_writes(Context *on_blocked);
   void unblock_writes();
 
   void register_lock_listener();
@@ -54,6 +55,8 @@ protected:
   virtual void process(AioImageRequest *req);
 
 private:
+  typedef std::list<Context *> Contexts;
+
   struct LockListener : public ImageWatcher::Listener {
     AioImageRequestWQ *aio_work_queue;
     LockListener(AioImageRequestWQ *_aio_work_queue)
@@ -70,7 +73,7 @@ private:
 
   ImageCtx &m_image_ctx;
   mutable Mutex m_lock;
-  Cond m_cond;
+  Contexts m_write_blocker_contexts;
   uint32_t m_write_blockers;
   uint32_t m_in_progress_writes;
   uint32_t m_queued_writes;