]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: ensure image cannot be closed until in-flight IO callbacks complete
authorJason Dillaman <dillaman@redhat.com>
Tue, 28 Jul 2020 13:07:49 +0000 (09:07 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 28 Jul 2020 13:07:49 +0000 (09:07 -0400)
If a librbd client attempts to close the image while it still has in-flight IO
pending, it's possible for the AsyncOperation tracker which prevents the image
from being closed to be completed before the actual AioCompletion callback
fires. This can result in the now destructed ImageCtx being de-referenced by
the AioCompletion.

Fixes: https://tracker.ceph.com/issues/46737
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/librbd/io/AioCompletion.cc

index cad103364244c1a1f4a970a86c679dee4d3c2f72..f6015b8a942d8c6906e9dd1a18f50201bf50e3ae 100644 (file)
@@ -118,10 +118,6 @@ void AioCompletion::complete() {
     image_dispatcher_ctx->complete(rval);
   }
 
-  // note: possible for image to be closed after op marked finished
-  if (async_op.started()) {
-    async_op.finish_op();
-  }
   tracepoint(librbd, aio_complete_exit);
 }
 
@@ -274,8 +270,15 @@ void AioCompletion::complete_event_socket() {
 void AioCompletion::notify_callbacks_complete() {
   state = AIO_STATE_COMPLETE;
 
-  std::unique_lock<std::mutex> locker(lock);
-  cond.notify_all();
+  {
+    std::unique_lock<std::mutex> locker(lock);
+    cond.notify_all();
+  }
+
+  // note: possible for image to be closed after op marked finished
+  if (async_op.started()) {
+    async_op.finish_op();
+  }
 }
 
 } // namespace io