From 18e849f01c23b73d42ca3cd5047e56e93551f2fb Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 22 Mar 2016 18:50:43 -0400 Subject: [PATCH] rbd-mirror: only delete ImageCtx after open failure The image is already closed -- it just needs to be destroyed in a thread context outside of librbd. Signed-off-by: Jason Dillaman --- src/test/rbd_mirror/test_mock_ImageReplayer.cc | 2 +- .../rbd_mirror/image_replayer/CloseImageRequest.cc | 10 ++++++++-- .../rbd_mirror/image_replayer/CloseImageRequest.h | 10 ++++++---- .../image_replayer/OpenLocalImageRequest.cc | 12 ++++++------ .../image_replayer/OpenLocalImageRequest.h | 2 +- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/test/rbd_mirror/test_mock_ImageReplayer.cc b/src/test/rbd_mirror/test_mock_ImageReplayer.cc index 36ad1733e8a..9b78c070c7a 100644 --- a/src/test/rbd_mirror/test_mock_ImageReplayer.cc +++ b/src/test/rbd_mirror/test_mock_ImageReplayer.cc @@ -83,7 +83,7 @@ struct CloseImageRequest { Context *on_finish = nullptr; static CloseImageRequest* create(librbd::MockImageReplayerImageCtx **image_ctx, - ContextWQ *work_queue, + ContextWQ *work_queue, bool destroy_only, Context *on_finish) { assert(s_instance != nullptr); s_instance->on_finish = on_finish; diff --git a/src/tools/rbd_mirror/image_replayer/CloseImageRequest.cc b/src/tools/rbd_mirror/image_replayer/CloseImageRequest.cc index 37512455ca7..a2a39a6c94d 100644 --- a/src/tools/rbd_mirror/image_replayer/CloseImageRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/CloseImageRequest.cc @@ -22,8 +22,9 @@ using librbd::util::create_context_callback; template CloseImageRequest::CloseImageRequest(I **image_ctx, ContextWQ *work_queue, - Context *on_finish) - : m_image_ctx(image_ctx), m_work_queue(work_queue), m_on_finish(on_finish) { + bool destroy_only, Context *on_finish) + : m_image_ctx(image_ctx), m_work_queue(work_queue), + m_destroy_only(destroy_only), m_on_finish(on_finish) { } template @@ -33,6 +34,11 @@ void CloseImageRequest::send() { template void CloseImageRequest::close_image() { + if (m_destroy_only) { + switch_thread_context(); + return; + } + dout(20) << dendl; Context *ctx = create_context_callback< diff --git a/src/tools/rbd_mirror/image_replayer/CloseImageRequest.h b/src/tools/rbd_mirror/image_replayer/CloseImageRequest.h index 8c432970621..dddad47220e 100644 --- a/src/tools/rbd_mirror/image_replayer/CloseImageRequest.h +++ b/src/tools/rbd_mirror/image_replayer/CloseImageRequest.h @@ -20,12 +20,13 @@ template class CloseImageRequest { public: static CloseImageRequest* create(ImageCtxT **image_ctx, ContextWQ *work_queue, - Context *on_finish) { - return new CloseImageRequest(image_ctx, work_queue, on_finish); + bool destroy_only, Context *on_finish) { + return new CloseImageRequest(image_ctx, work_queue, destroy_only, + on_finish); } CloseImageRequest(ImageCtxT **image_ctx, ContextWQ *work_queue, - Context *on_finish); + bool destroy_only, Context *on_finish); void send(); @@ -36,7 +37,7 @@ private: * * | * v - * CLOSE_IMAGE + * CLOSE_IMAGE (skip if not needed) * | * v * SWITCH_CONTEXT @@ -48,6 +49,7 @@ private: */ ImageCtxT **m_image_ctx; ContextWQ *m_work_queue; + bool m_destroy_only; Context *m_on_finish; void close_image(); diff --git a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc index 846f9c4dfd2..0d2b2871e54 100644 --- a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc +++ b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc @@ -98,11 +98,11 @@ void OpenLocalImageRequest::handle_open_image(int r) { if (r < 0) { derr << "failed to open image '" << m_local_image_id << "': " << cpp_strerror(r) << dendl; - send_close_image(r); + send_close_image(true, r); return; } else if ((*m_local_image_ctx)->exclusive_lock == nullptr) { derr << "image does not support exclusive lock" << dendl; - send_close_image(-EINVAL); + send_close_image(false, -EINVAL); return; } @@ -128,12 +128,12 @@ void OpenLocalImageRequest::handle_lock_image(int r) { if (r < 0) { derr << "failed to lock image '" << m_local_image_id << "': " << cpp_strerror(r) << dendl; - send_close_image(r); + send_close_image(false, r); return; } else if ((*m_local_image_ctx)->exclusive_lock == nullptr || !(*m_local_image_ctx)->exclusive_lock->is_lock_owner()) { derr << "image is not locked" << dendl; - send_close_image(-EBUSY); + send_close_image(false, -EBUSY); return; } @@ -141,7 +141,7 @@ void OpenLocalImageRequest::handle_lock_image(int r) { } template -void OpenLocalImageRequest::send_close_image(int r) { +void OpenLocalImageRequest::send_close_image(bool destroy_only, int r) { dout(20) << dendl; if (m_ret_val == 0 && r < 0) { @@ -152,7 +152,7 @@ void OpenLocalImageRequest::send_close_image(int r) { OpenLocalImageRequest, &OpenLocalImageRequest::handle_close_image>( this); CloseImageRequest *request = CloseImageRequest::create( - m_local_image_ctx, m_work_queue, ctx); + m_local_image_ctx, m_work_queue, destroy_only, ctx); request->send(); } diff --git a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h index daf5c0aff62..a8db813bcab 100644 --- a/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h +++ b/src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h @@ -71,7 +71,7 @@ private: void send_lock_image(); void handle_lock_image(int r); - void send_close_image(int r); + void send_close_image(bool destroy_only, int r); void handle_close_image(int r); void finish(int r);