From: lixiaoy1 Date: Fri, 11 Sep 2020 14:23:22 +0000 (-0400) Subject: librbd/io: add invalidate_cache X-Git-Tag: v16.1.0~714^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e649699655af2aafd5498ba66e07d2158a160604;p=ceph.git librbd/io: add invalidate_cache Add invalidate_cache in ImageDispatch and ImageDispatcher. Signed-off-by: Li, Xiaoyan --- diff --git a/src/librbd/cache/WriteLogImageDispatch.cc b/src/librbd/cache/WriteLogImageDispatch.cc index 3fa04aac6fd..ce93d7ee83c 100644 --- a/src/librbd/cache/WriteLogImageDispatch.cc +++ b/src/librbd/cache/WriteLogImageDispatch.cc @@ -218,7 +218,6 @@ bool WriteLogImageDispatch::list_snaps( return false; } - template bool WriteLogImageDispatch::preprocess_length( io::AioCompletion* aio_comp, io::Extents &image_extents) const { @@ -230,6 +229,12 @@ bool WriteLogImageDispatch::preprocess_length( return false; } +template +bool WriteLogImageDispatch::invalidate_cache(Context* on_finish) { + m_image_cache->invalidate(on_finish); + return true; +} + } // namespace io } // namespace librbd diff --git a/src/librbd/cache/WriteLogImageDispatch.h b/src/librbd/cache/WriteLogImageDispatch.h index 86d3f70afcd..d0fb106e3a5 100644 --- a/src/librbd/cache/WriteLogImageDispatch.h +++ b/src/librbd/cache/WriteLogImageDispatch.h @@ -86,6 +86,8 @@ public: io::DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) override; + bool invalidate_cache(Context* on_finish) override; + private: ImageCtxT* m_image_ctx; pwl::AbstractWriteLog *m_image_cache; diff --git a/src/librbd/exclusive_lock/ImageDispatch.h b/src/librbd/exclusive_lock/ImageDispatch.h index c6c0058949c..77c101973ef 100644 --- a/src/librbd/exclusive_lock/ImageDispatch.h +++ b/src/librbd/exclusive_lock/ImageDispatch.h @@ -99,6 +99,10 @@ public: return false; } + bool invalidate_cache(Context* on_finish) override { + return false; + } + private: typedef std::list Contexts; typedef std::unordered_set Tids; diff --git a/src/librbd/io/Dispatcher.h b/src/librbd/io/Dispatcher.h index 60c7c802cf3..7dc9357bac9 100644 --- a/src/librbd/io/Dispatcher.h +++ b/src/librbd/io/Dispatcher.h @@ -10,6 +10,7 @@ #include "common/dout.h" #include "common/AsyncOpTracker.h" #include "librbd/Utils.h" +#include "librbd/io/DispatcherInterface.h" #include "librbd/io/Types.h" #include @@ -32,7 +33,7 @@ public: : m_image_ctx(image_ctx), m_lock(ceph::make_shared_mutex( librbd::util::unique_lock_name("librbd::io::Dispatcher::lock", - this))) { + this))) { } virtual ~Dispatcher() { @@ -153,6 +154,65 @@ protected: virtual bool send_dispatch(Dispatch* dispatch, DispatchSpec* dispatch_spec) = 0; +protected: + struct C_LayerIterator : public Context { + Dispatcher* dispatcher; + Context* on_finish; + DispatchLayer dispatch_layer; + + C_LayerIterator(Dispatcher* dispatcher, + DispatchLayer start_layer, + Context* on_finish) + : dispatcher(dispatcher), on_finish(on_finish), dispatch_layer(start_layer) { + } + + void complete(int r) override { + while (true) { + dispatcher->m_lock.lock_shared(); + auto it = dispatcher->m_dispatches.upper_bound(dispatch_layer); + if (it == dispatcher->m_dispatches.end()) { + dispatcher->m_lock.unlock_shared(); + Context::complete(r); + return; + } + + auto& dispatch_meta = it->second; + auto dispatch = dispatch_meta.dispatch; + + // prevent recursive locking back into the dispatcher while handling IO + dispatch_meta.async_op_tracker->start_op(); + dispatcher->m_lock.unlock_shared(); + + // next loop should start after current layer + dispatch_layer = dispatch->get_dispatch_layer(); + + auto handled = execute(dispatch, this); + dispatch_meta.async_op_tracker->finish_op(); + + if (handled) { + break; + } + } + } + + void finish(int r) override { + on_finish->complete(0); + } + virtual bool execute(Dispatch* dispatch, + Context* on_finish) = 0; + }; + + struct C_InvalidateCache : public C_LayerIterator { + C_InvalidateCache(Dispatcher* dispatcher, DispatchLayer start_layer, Context* on_finish) + : C_LayerIterator(dispatcher, start_layer, on_finish) { + } + + bool execute(Dispatch* dispatch, + Context* on_finish) override { + return dispatch->invalidate_cache(on_finish); + } + }; + private: void shut_down_dispatch(DispatchMeta& dispatch_meta, Context** on_finish) { diff --git a/src/librbd/io/ImageDispatch.cc b/src/librbd/io/ImageDispatch.cc index 2413b16b994..cc8519abeee 100644 --- a/src/librbd/io/ImageDispatch.cc +++ b/src/librbd/io/ImageDispatch.cc @@ -6,6 +6,7 @@ #include "librbd/ImageCtx.h" #include "librbd/io/AioCompletion.h" #include "librbd/io/ImageRequest.h" +#include "librbd/io/ObjectDispatcherInterface.h" #define dout_subsys ceph_subsys_rbd #undef dout_prefix @@ -167,6 +168,16 @@ bool ImageDispatch::list_snaps( return true; } +template +bool ImageDispatch::invalidate_cache(Context* on_finish) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << dendl; + + std::shared_lock owner_lock{m_image_ctx->owner_lock}; + m_image_ctx->io_object_dispatcher->invalidate_cache(on_finish); + return true; +} + } // namespace io } // namespace librbd diff --git a/src/librbd/io/ImageDispatch.h b/src/librbd/io/ImageDispatch.h index 512f28e2420..3d302e9a62a 100644 --- a/src/librbd/io/ImageDispatch.h +++ b/src/librbd/io/ImageDispatch.h @@ -81,6 +81,8 @@ public: DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) override; + bool invalidate_cache(Context* on_finish) override; + private: ImageCtxT* m_image_ctx; diff --git a/src/librbd/io/ImageDispatchInterface.h b/src/librbd/io/ImageDispatchInterface.h index 1e563a634fe..205c18c474f 100644 --- a/src/librbd/io/ImageDispatchInterface.h +++ b/src/librbd/io/ImageDispatchInterface.h @@ -79,6 +79,7 @@ struct ImageDispatchInterface { DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) = 0; + virtual bool invalidate_cache(Context* on_finish) = 0; }; } // namespace io diff --git a/src/librbd/io/ImageDispatcher.cc b/src/librbd/io/ImageDispatcher.cc index 49f3bfc5ad0..fb5908b01c0 100644 --- a/src/librbd/io/ImageDispatcher.cc +++ b/src/librbd/io/ImageDispatcher.cc @@ -6,8 +6,6 @@ #include "common/AsyncOpTracker.h" #include "common/dout.h" #include "librbd/ImageCtx.h" -#include "librbd/Utils.h" -#include "librbd/io/AsyncOperation.h" #include "librbd/io/ImageDispatch.h" #include "librbd/io/ImageDispatchInterface.h" #include "librbd/io/ImageDispatchSpec.h" @@ -196,6 +194,17 @@ ImageDispatcher::ImageDispatcher(I* image_ctx) this->register_dispatch(m_write_block_dispatch); } +template +void ImageDispatcher::invalidate_cache(Context* on_finish) { + auto image_ctx = this->m_image_ctx; + auto cct = image_ctx->cct; + ldout(cct, 5) << dendl; + + auto ctx = new C_InvalidateCache( + this, IMAGE_DISPATCH_LAYER_NONE, on_finish); + ctx->complete(0); +} + template void ImageDispatcher::shut_down(Context* on_finish) { // TODO ensure all IOs are executed via a dispatcher diff --git a/src/librbd/io/ImageDispatcher.h b/src/librbd/io/ImageDispatcher.h index 7ab248abdf7..26efd9d8124 100644 --- a/src/librbd/io/ImageDispatcher.h +++ b/src/librbd/io/ImageDispatcher.h @@ -30,6 +30,8 @@ class ImageDispatcher : public Dispatcher { public: ImageDispatcher(ImageCtxT* image_ctx); + void invalidate_cache(Context* on_finish) override; + void shut_down(Context* on_finish) override; void apply_qos_schedule_tick_min(uint64_t tick) override; @@ -52,6 +54,8 @@ private: struct SendVisitor; struct PreprocessVisitor; + using typename Dispatcher::C_InvalidateCache; + std::atomic m_next_tid{0}; QosImageDispatch* m_qos_image_dispatch = nullptr; diff --git a/src/librbd/io/ImageDispatcherInterface.h b/src/librbd/io/ImageDispatcherInterface.h index 78f90977d78..8bff8566ed2 100644 --- a/src/librbd/io/ImageDispatcherInterface.h +++ b/src/librbd/io/ImageDispatcherInterface.h @@ -27,6 +27,8 @@ public: virtual void unblock_writes() = 0; virtual void wait_on_writes_unblocked(Context *on_unblocked) = 0; + + virtual void invalidate_cache(Context* on_finish) = 0; }; } // namespace io diff --git a/src/librbd/io/ObjectDispatcher.cc b/src/librbd/io/ObjectDispatcher.cc index 16cc1722f0c..3bc55a57fd6 100644 --- a/src/librbd/io/ObjectDispatcher.cc +++ b/src/librbd/io/ObjectDispatcher.cc @@ -20,72 +20,10 @@ namespace librbd { namespace io { -template -struct ObjectDispatcher::C_LayerIterator : public Context { - ObjectDispatcher* object_dispatcher; - Context* on_finish; - - ObjectDispatchLayer object_dispatch_layer = OBJECT_DISPATCH_LAYER_NONE; - - C_LayerIterator(ObjectDispatcher* object_dispatcher, - Context* on_finish) - : object_dispatcher(object_dispatcher), on_finish(on_finish) { - } - - void complete(int r) override { - while (true) { - object_dispatcher->m_lock.lock_shared(); - auto it = object_dispatcher->m_dispatches.upper_bound( - object_dispatch_layer); - if (it == object_dispatcher->m_dispatches.end()) { - object_dispatcher->m_lock.unlock_shared(); - Context::complete(r); - return; - } - - auto& object_dispatch_meta = it->second; - auto object_dispatch = object_dispatch_meta.dispatch; - - // prevent recursive locking back into the dispatcher while handling IO - object_dispatch_meta.async_op_tracker->start_op(); - object_dispatcher->m_lock.unlock_shared(); - - // next loop should start after current layer - object_dispatch_layer = object_dispatch->get_dispatch_layer(); - - auto handled = execute(object_dispatch, this); - object_dispatch_meta.async_op_tracker->finish_op(); - - if (handled) { - break; - } - } - } - - void finish(int r) override { - on_finish->complete(0); - } - - virtual bool execute(ObjectDispatchInterface* object_dispatch, - Context* on_finish) = 0; -}; - -template -struct ObjectDispatcher::C_InvalidateCache : public C_LayerIterator { - C_InvalidateCache(ObjectDispatcher* object_dispatcher, Context* on_finish) - : C_LayerIterator(object_dispatcher, on_finish) { - } - - bool execute(ObjectDispatchInterface* object_dispatch, - Context* on_finish) override { - return object_dispatch->invalidate_cache(on_finish); - } -}; - template struct ObjectDispatcher::C_ResetExistenceCache : public C_LayerIterator { C_ResetExistenceCache(ObjectDispatcher* object_dispatcher, Context* on_finish) - : C_LayerIterator(object_dispatcher, on_finish) { + : C_LayerIterator(object_dispatcher, OBJECT_DISPATCH_LAYER_NONE, on_finish) { } bool execute(ObjectDispatchInterface* object_dispatch, @@ -201,7 +139,8 @@ void ObjectDispatcher::invalidate_cache(Context* on_finish) { ldout(cct, 5) << dendl; on_finish = util::create_async_context_callback(*image_ctx, on_finish); - auto ctx = new C_InvalidateCache(this, on_finish); + auto ctx = new C_InvalidateCache( + this, OBJECT_DISPATCH_LAYER_NONE, on_finish); ctx->complete(0); } diff --git a/src/librbd/io/ObjectDispatcher.h b/src/librbd/io/ObjectDispatcher.h index 2cb5904de8e..7b356afe6de 100644 --- a/src/librbd/io/ObjectDispatcher.h +++ b/src/librbd/io/ObjectDispatcher.h @@ -38,13 +38,15 @@ public: uint64_t object_no, SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override; + using typename Dispatcher::C_LayerIterator; + + using typename Dispatcher::C_InvalidateCache; + protected: bool send_dispatch(ObjectDispatchInterface* object_dispatch, ObjectDispatchSpec* object_dispatch_spec) override; private: - struct C_LayerIterator; - struct C_InvalidateCache; struct C_ResetExistenceCache; struct SendVisitor; diff --git a/src/librbd/io/QosImageDispatch.h b/src/librbd/io/QosImageDispatch.h index 8ea12d64b83..baf16da02be 100644 --- a/src/librbd/io/QosImageDispatch.h +++ b/src/librbd/io/QosImageDispatch.h @@ -100,6 +100,10 @@ public: return false; } + bool invalidate_cache(Context* on_finish) override { + return false; + } + private: ImageCtxT* m_image_ctx; diff --git a/src/librbd/io/QueueImageDispatch.h b/src/librbd/io/QueueImageDispatch.h index ec94b61d846..60ee467502d 100644 --- a/src/librbd/io/QueueImageDispatch.h +++ b/src/librbd/io/QueueImageDispatch.h @@ -87,6 +87,10 @@ public: return false; } + bool invalidate_cache(Context* on_finish) override { + return false; + } + private: ImageCtxT* m_image_ctx; diff --git a/src/librbd/io/RefreshImageDispatch.h b/src/librbd/io/RefreshImageDispatch.h index 144d97bafe8..1bcb3c312cf 100644 --- a/src/librbd/io/RefreshImageDispatch.h +++ b/src/librbd/io/RefreshImageDispatch.h @@ -83,6 +83,10 @@ public: return false; } + bool invalidate_cache(Context* on_finish) override { + return false; + } + private: ImageCtxT* m_image_ctx; diff --git a/src/librbd/io/WriteBlockImageDispatch.h b/src/librbd/io/WriteBlockImageDispatch.h index e8b9407cf54..9d200fb9753 100644 --- a/src/librbd/io/WriteBlockImageDispatch.h +++ b/src/librbd/io/WriteBlockImageDispatch.h @@ -119,6 +119,10 @@ private: Context** on_finish, Context* on_dispatched); void flush_io(Context* on_finish); + bool invalidate_cache(Context* on_finish) override { + return false; + } + void handle_blocked_writes(int r); }; diff --git a/src/librbd/migration/ImageDispatch.h b/src/librbd/migration/ImageDispatch.h index 490ea2d3987..03bb3aa5213 100644 --- a/src/librbd/migration/ImageDispatch.h +++ b/src/librbd/migration/ImageDispatch.h @@ -81,6 +81,10 @@ public: io::DispatchResult* dispatch_result, Context** on_finish, Context* on_dispatched) override; + bool invalidate_cache(Context* on_finish) override { + return false; + } + private: ImageCtxT* m_image_ctx; std::unique_ptr m_format; diff --git a/src/test/librbd/mock/io/MockImageDispatch.h b/src/test/librbd/mock/io/MockImageDispatch.h index ebd2d829f6f..02dff3487b6 100644 --- a/src/test/librbd/mock/io/MockImageDispatch.h +++ b/src/test/librbd/mock/io/MockImageDispatch.h @@ -87,6 +87,10 @@ public: return false; } + bool invalidate_cache(Context* on_finish) override { + return false; + } + }; } // namespace io diff --git a/src/test/librbd/mock/io/MockImageDispatcher.h b/src/test/librbd/mock/io/MockImageDispatcher.h index 249967d9fd2..14669133048 100644 --- a/src/test/librbd/mock/io/MockImageDispatcher.h +++ b/src/test/librbd/mock/io/MockImageDispatcher.h @@ -23,6 +23,7 @@ public: MOCK_METHOD1(register_dispatch, void(ImageDispatchInterface*)); MOCK_METHOD2(shut_down_dispatch, void(ImageDispatchLayer, Context*)); + MOCK_METHOD1(invalidate_cache, void(Context *)); MOCK_METHOD1(send, void(ImageDispatchSpec*)); MOCK_METHOD3(finish, void(int r, ImageDispatchLayer, uint64_t));