From: Jason Dillaman Date: Thu, 18 Apr 2019 17:17:56 +0000 (-0400) Subject: librbd: async open/close should free ImageCtx before issuing callback X-Git-Tag: v12.2.13~213^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=86d7f39b50f3efde928d77a9f8392c34f0918a4c;p=ceph.git librbd: async open/close should free ImageCtx before issuing callback 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 (cherry picked from commit be419a1d6fd1e176ab4fdebfaa17726bb63d6ac8) Conflicts: src/librbd/io/AioCompletion.cc: assert->ceph_assert confict --- diff --git a/src/librbd/io/AioCompletion.cc b/src/librbd/io/AioCompletion.cc index d58d4f35597..82ed60faa93 100644 --- a/src/librbd/io/AioCompletion.cc +++ b/src/librbd/io/AioCompletion.cc @@ -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); diff --git a/src/librbd/io/AioCompletion.h b/src/librbd/io/AioCompletion.h index a3edb141423..6673b66c70f 100644 --- a/src/librbd/io/AioCompletion.h +++ b/src/librbd/io/AioCompletion.h @@ -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; }