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
}
}
+ 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();
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();
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;
}