]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: allow AioCompletions to be blocked
authorJason Dillaman <dillaman@redhat.com>
Tue, 3 Mar 2015 02:07:01 +0000 (21:07 -0500)
committerJason Dillaman <dillaman@redhat.com>
Tue, 3 Mar 2015 02:18:39 +0000 (21:18 -0500)
Blocked AioCompletions will not fire their callback until unblocked.
This is an expansion / replacement of the previous 'building' flag
used to block completions while additional requests were added to the
completion.

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

index 4ead667d6dbf47899a0023d9fb07de1a4c81b4a8..8c38e1c95c4a5496fc044d8cdb15ea8f511805cf 100644 (file)
@@ -26,14 +26,7 @@ namespace librbd {
   void AioCompletion::finish_adding_requests(CephContext *cct)
   {
     ldout(cct, 20) << "AioCompletion::finish_adding_requests " << (void*)this << " pending " << pending_count << dendl;
-    lock.Lock();
-    assert(building);
-    building = false;
-    if (!pending_count) {
-      finalize(cct, rval);
-      complete();
-    }
-    lock.Unlock();
+    unblock(cct);
   }
 
   int AioCompletion::wait_for_complete() {
@@ -89,6 +82,7 @@ namespace librbd {
       break;
     }
 
+    // note: possible for image to be closed after op marked finished
     async_op.finish_op();
 
     if (complete_cb) {
@@ -113,7 +107,7 @@ namespace librbd {
     }
     assert(pending_count);
     int count = --pending_count;
-    if (!count && !building) {
+    if (!count && blockers == 0) {
       finalize(cct, rval);
       complete();
     }
index 41c89f2f0b934e918ed145aa6b734a0850b04488..cef8388e6202b70eb8d28b541eb886ea34ade6b2 100644 (file)
@@ -50,7 +50,7 @@ namespace librbd {
     void *complete_arg;
     rbd_completion_t rbd_comp;
     int pending_count;   ///< number of requests
-    bool building;       ///< true if we are still building this completion
+    uint32_t blockers;
     int ref;
     bool released;
     ImageCtx *ictx;
@@ -67,7 +67,7 @@ namespace librbd {
     AioCompletion() : lock("AioCompletion::lock", true),
                      done(false), rval(0), complete_cb(NULL),
                      complete_arg(NULL), rbd_comp(NULL),
-                     pending_count(0), building(true),
+                     pending_count(0), blockers(1),
                      ref(1), released(false), ictx(NULL),
                      aio_type(AIO_TYPE_NONE),
                      read_bl(NULL), read_buf(NULL), read_buf_len(0) {
@@ -134,6 +134,20 @@ namespace librbd {
       if (!n)
        delete this;
     }
+
+    void block() {
+      Mutex::Locker l(lock);
+      ++blockers;
+    }
+    void unblock(CephContext *cct) {
+      Mutex::Locker l(lock);
+      assert(blockers > 0);
+      --blockers;
+      if (pending_count == 0 && blockers == 0) {
+        finalize(cct, rval);
+        complete();
+      }
+    }
   };
 
   class C_AioRead : public Context {