From 70eb9c751b5165f2b9e094828dde0e66de7cefaa Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 26 Aug 2020 19:40:39 -0400 Subject: [PATCH] librbd: flush all incomplete in-flight IOs upon image close Fixes: https://tracker.ceph.com/issues/46875 Signed-off-by: Jason Dillaman --- src/librbd/image/CloseRequest.cc | 57 +++++++++++++++-------------- src/librbd/image/CloseRequest.h | 23 ++++++------ src/librbd/io/QueueImageDispatch.cc | 4 -- 3 files changed, 41 insertions(+), 43 deletions(-) diff --git a/src/librbd/image/CloseRequest.cc b/src/librbd/image/CloseRequest.cc index a5543ff38bd..c12cecd52d7 100644 --- a/src/librbd/image/CloseRequest.cc +++ b/src/librbd/image/CloseRequest.cc @@ -90,6 +90,34 @@ void CloseRequest::handle_shut_down_update_watchers(int r) { << dendl; } + send_flush(); +} + +template +void CloseRequest::send_flush() { + CephContext *cct = m_image_ctx->cct; + ldout(cct, 10) << this << " " << __func__ << dendl; + + std::shared_lock owner_locker{m_image_ctx->owner_lock}; + auto ctx = create_context_callback< + CloseRequest, &CloseRequest::handle_flush>(this); + auto aio_comp = io::AioCompletion::create_and_start(ctx, m_image_ctx, + io::AIO_TYPE_FLUSH); + auto req = io::ImageDispatchSpec::create_flush( + *m_image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp, + io::FLUSH_SOURCE_INTERNAL, {}); + req->send(); +} + +template +void CloseRequest::handle_flush(int r) { + CephContext *cct = m_image_ctx->cct; + ldout(cct, 10) << this << " " << __func__ << ": r=" << r << dendl; + + if (r < 0) { + lderr(cct) << "failed to flush IO: " << cpp_strerror(r) << dendl; + } + send_shut_down_exclusive_lock(); } @@ -108,7 +136,7 @@ void CloseRequest::send_shut_down_exclusive_lock() { } if (m_exclusive_lock == nullptr) { - send_flush(); + send_unregister_image_watcher(); return; } @@ -148,33 +176,6 @@ void CloseRequest::handle_shut_down_exclusive_lock(int r) { send_unregister_image_watcher(); } -template -void CloseRequest::send_flush() { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << dendl; - - std::shared_lock owner_locker{m_image_ctx->owner_lock}; - auto ctx = create_context_callback< - CloseRequest, &CloseRequest::handle_flush>(this); - auto aio_comp = io::AioCompletion::create_and_start(ctx, m_image_ctx, - io::AIO_TYPE_FLUSH); - auto req = io::ImageDispatchSpec::create_flush( - *m_image_ctx, io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp, - io::FLUSH_SOURCE_INTERNAL, {}); - req->send(); -} - -template -void CloseRequest::handle_flush(int r) { - CephContext *cct = m_image_ctx->cct; - ldout(cct, 10) << this << " " << __func__ << ": r=" << r << dendl; - - if (r < 0) { - lderr(cct) << "failed to flush IO: " << cpp_strerror(r) << dendl; - } - send_unregister_image_watcher(); -} - template void CloseRequest::send_unregister_image_watcher() { if (m_image_ctx->image_watcher == nullptr) { diff --git a/src/librbd/image/CloseRequest.h b/src/librbd/image/CloseRequest.h index 7f9f0d52ea6..ee298aa9d07 100644 --- a/src/librbd/image/CloseRequest.h +++ b/src/librbd/image/CloseRequest.h @@ -33,14 +33,15 @@ private: * BLOCK_IMAGE_WATCHER (skip if R/O) * | * v - * SHUT_DOWN_UPDATE_WATCHERS . . - * | . (exclusive lock disabled) - * v v - * SHUT_DOWN_EXCLUSIVE_LOCK FLUSH - * | . - * | . . . . . . . . . . . - * | . - * v v + * SHUT_DOWN_UPDATE_WATCHERS + * | + * v + * FLUSH + * | + * v (skip if disabled) + * SHUT_DOWN_EXCLUSIVE_LOCK + * | + * v * UNREGISTER_IMAGE_WATCHER (skip if R/O) * | * v @@ -82,12 +83,12 @@ private: void send_shut_down_update_watchers(); void handle_shut_down_update_watchers(int r); - void send_shut_down_exclusive_lock(); - void handle_shut_down_exclusive_lock(int r); - void send_flush(); void handle_flush(int r); + void send_shut_down_exclusive_lock(); + void handle_shut_down_exclusive_lock(int r); + void send_unregister_image_watcher(); void handle_unregister_image_watcher(int r); diff --git a/src/librbd/io/QueueImageDispatch.cc b/src/librbd/io/QueueImageDispatch.cc index 607d35df3f7..a07557aa278 100644 --- a/src/librbd/io/QueueImageDispatch.cc +++ b/src/librbd/io/QueueImageDispatch.cc @@ -107,10 +107,6 @@ bool QueueImageDispatch::flush( auto cct = m_image_ctx->cct; ldout(cct, 20) << "tid=" << tid << dendl; - if (flush_source != FLUSH_SOURCE_USER) { - return false; - } - *dispatch_result = DISPATCH_RESULT_CONTINUE; m_flush_tracker->flush(on_dispatched); return true; -- 2.39.5