From 0d64e31c191f04b10b5318eb6d4db9dd83b2d166 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 28 Jul 2020 09:07:49 -0400 Subject: [PATCH 1/2] librbd: ensure image cannot be closed until in-flight IO callbacks complete 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 --- src/librbd/io/AioCompletion.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/librbd/io/AioCompletion.cc b/src/librbd/io/AioCompletion.cc index cad10336424..f6015b8a942 100644 --- a/src/librbd/io/AioCompletion.cc +++ b/src/librbd/io/AioCompletion.cc @@ -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 locker(lock); - cond.notify_all(); + { + std::unique_lock 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 From 246802f91514edeb19eff04a6dbeaf778eedf1be Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 29 Jul 2020 07:30:28 -0400 Subject: [PATCH 2/2] librbd: potentially delay completion of image dispatcher spec If an AioCompletion is being completed for an external API user, ensure that the completion of image dispatcher finalizer does not race with the potential to close the image. Signed-off-by: Jason Dillaman --- src/librbd/io/AioCompletion.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librbd/io/AioCompletion.cc b/src/librbd/io/AioCompletion.cc index f6015b8a942..cd5df0e7147 100644 --- a/src/librbd/io/AioCompletion.cc +++ b/src/librbd/io/AioCompletion.cc @@ -114,10 +114,6 @@ void AioCompletion::complete() { notify_callbacks_complete(); } - if (image_dispatcher_ctx != nullptr) { - image_dispatcher_ctx->complete(rval); - } - tracepoint(librbd, aio_complete_exit); } @@ -275,6 +271,10 @@ void AioCompletion::notify_callbacks_complete() { cond.notify_all(); } + if (image_dispatcher_ctx != nullptr) { + image_dispatcher_ctx->complete(rval); + } + // note: possible for image to be closed after op marked finished if (async_op.started()) { async_op.finish_op();