]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: async open/close should free ImageCtx before issuing callback
authorJason Dillaman <dillaman@redhat.com>
Thu, 18 Apr 2019 17:17:56 +0000 (13:17 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 15 May 2019 19:43:38 +0000 (15:43 -0400)
The destructor for ImageCtx attempts to access librados::IoCtx objects
that might have been destroyed immediately after the async open (failure)
and close actions completed.

Fixes: http://tracker.ceph.com/issues/39031
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit be419a1d6fd1e176ab4fdebfaa17726bb63d6ac8)

Conflicts:
src/librbd/io/AioCompletion.cc: assert->ceph_assert confict

src/librbd/io/AioCompletion.cc
src/librbd/io/AioCompletion.h

index d58d4f35597cdecb60a0227d8533fdefc37dbf5b..82ed60faa932325c903c787139c16f4df0746ada 100644 (file)
@@ -87,6 +87,13 @@ void AioCompletion::complete() {
     ictx->journal->commit_io_event(journal_tid, rval);
   }
 
+  if ((aio_type == AIO_TYPE_CLOSE) ||
+      (aio_type == AIO_TYPE_OPEN && rval < 0)) {
+    // must destroy ImageCtx prior to invoking callback
+    delete ictx;
+    ictx = nullptr;
+  }
+
   state = AIO_STATE_CALLBACK;
   if (complete_cb) {
     lock.Unlock();
@@ -124,6 +131,12 @@ void AioCompletion::start_op(bool ignore_type) {
   Mutex::Locker locker(lock);
   assert(ictx != nullptr);
   assert(!async_op.started());
+
+  if (aio_type == AIO_TYPE_OPEN || aio_type == AIO_TYPE_CLOSE) {
+    // no need to track async open/close operations
+    return;
+  }
+
   if (state == AIO_STATE_PENDING &&
       (ignore_type || aio_type != AIO_TYPE_FLUSH)) {
     async_op.start_op(*ictx);
index a3edb1414236ed3bc43da8ccc6f534795d6c76d0..6673b66c70f31c3acb1b3513c9a5242dd097c2c5 100644 (file)
@@ -169,16 +169,10 @@ struct AioCompletion {
     int n = --ref;
     lock.Unlock();
     if (!n) {
-      if (ictx) {
-        if (event_notify) {
-          ictx->completed_reqs_lock.Lock();
-          m_xlist_item.remove_myself();
-          ictx->completed_reqs_lock.Unlock();
-        }
-        if (aio_type == AIO_TYPE_CLOSE ||
-            (aio_type == AIO_TYPE_OPEN && rval < 0)) {
-          delete ictx;
-        }
+      if (ictx != nullptr && event_notify) {
+        ictx->completed_reqs_lock.Lock();
+        m_xlist_item.remove_myself();
+        ictx->completed_reqs_lock.Unlock();
       }
       delete this;
     }