]> 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>
Tue, 1 Oct 2019 11:37:06 +0000 (07:37 -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 ad88b0a71e2de445a11d8555f2394ef646d893f5..79321d6920bc28c135dc5bd9e5b03b730c19183d 100644 (file)
@@ -82,6 +82,13 @@ void AioCompletion::complete() {
     }
   }
 
+  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();
@@ -89,7 +96,7 @@ void AioCompletion::complete() {
     lock.Lock();
   }
 
-  if (event_notify && ictx->event_socket.is_valid()) {
+  if (ictx != nullptr && event_notify && ictx->event_socket.is_valid()) {
     ictx->completed_reqs_lock.Lock();
     ictx->completed_reqs.push_back(&m_xlist_item);
     ictx->completed_reqs_lock.Unlock();
index dddf3c8c244e7e046d2dbcebf8247c265121cf9e..e009d25ed01d7eac0a7a9076bb74f33b92ab5382 100644 (file)
@@ -167,16 +167,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;
     }