]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/io: add invalidate_cache
authorlixiaoy1 <xiaoyan.li@intel.com>
Fri, 11 Sep 2020 14:23:22 +0000 (10:23 -0400)
committerlixiaoy1 <xiaoyan.li@intel.com>
Tue, 27 Oct 2020 10:08:45 +0000 (18:08 +0800)
Add invalidate_cache in ImageDispatch and ImageDispatcher.

Signed-off-by: Li, Xiaoyan <xiaoyan.li@intel.com>
19 files changed:
src/librbd/cache/WriteLogImageDispatch.cc
src/librbd/cache/WriteLogImageDispatch.h
src/librbd/exclusive_lock/ImageDispatch.h
src/librbd/io/Dispatcher.h
src/librbd/io/ImageDispatch.cc
src/librbd/io/ImageDispatch.h
src/librbd/io/ImageDispatchInterface.h
src/librbd/io/ImageDispatcher.cc
src/librbd/io/ImageDispatcher.h
src/librbd/io/ImageDispatcherInterface.h
src/librbd/io/ObjectDispatcher.cc
src/librbd/io/ObjectDispatcher.h
src/librbd/io/QosImageDispatch.h
src/librbd/io/QueueImageDispatch.h
src/librbd/io/RefreshImageDispatch.h
src/librbd/io/WriteBlockImageDispatch.h
src/librbd/migration/ImageDispatch.h
src/test/librbd/mock/io/MockImageDispatch.h
src/test/librbd/mock/io/MockImageDispatcher.h

index 3fa04aac6fd061c3d471bf7dce011cd22a6aa173..ce93d7ee83c53358e509b0c173bb707ef062ad9f 100644 (file)
@@ -218,7 +218,6 @@ bool WriteLogImageDispatch<I>::list_snaps(
   return false;
 }
 
-
 template <typename I>
 bool WriteLogImageDispatch<I>::preprocess_length(
     io::AioCompletion* aio_comp, io::Extents &image_extents) const {
@@ -230,6 +229,12 @@ bool WriteLogImageDispatch<I>::preprocess_length(
   return false;
 }
 
+template <typename I>
+bool WriteLogImageDispatch<I>::invalidate_cache(Context* on_finish) {
+  m_image_cache->invalidate(on_finish);
+  return true;
+}
+
 } // namespace io
 } // namespace librbd
 
index 86d3f70afcd8905f3c49d84f14d1ed6d2f45aa0c..d0fb106e3a583fa0a47e2f822264a0e43a6d7eb5 100644 (file)
@@ -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<ImageCtx> *m_image_cache;
index c6c0058949c6de57be32c336fa49fee66815b5f3..77c101973efe3e5722194622702e33ace621f68f 100644 (file)
@@ -99,6 +99,10 @@ public:
     return false;
   }
 
+  bool invalidate_cache(Context* on_finish) override {
+    return false;
+  }
+
 private:
   typedef std::list<Context*> Contexts;
   typedef std::unordered_set<uint64_t> Tids;
index 60c7c802cf3a1d92a641d44a1c9ebd10a102587a..7dc9357bac971107670c964a85c2a48950dd90f9 100644 (file)
@@ -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 <map>
 
@@ -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) {
index 2413b16b994b185a18748d9aa8362845dd6bcd99..cc8519abeeeb88193f1811f6a21157a93f1b331e 100644 (file)
@@ -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<I>::list_snaps(
   return true;
 }
 
+template <typename I>
+bool ImageDispatch<I>::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
 
index 512f28e2420de25b68eea925e7fd07fc72523f0c..3d302e9a62a0465739b8e14fb506b7daa327a251 100644 (file)
@@ -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;
 
index 1e563a634fe2cd25177a5771b4f7b64020ffa338..205c18c474fa724b7885e522636287ab68832b57 100644 (file)
@@ -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
index 49f3bfc5ad04cfcbd85bd0f988a036fc971d95da..fb5908b01c0d62719b80cdd010babd0f2425eab8 100644 (file)
@@ -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<I>::ImageDispatcher(I* image_ctx)
   this->register_dispatch(m_write_block_dispatch);
 }
 
+template <typename I>
+void ImageDispatcher<I>::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 <typename I>
 void ImageDispatcher<I>::shut_down(Context* on_finish) {
   // TODO ensure all IOs are executed via a dispatcher
index 7ab248abdf7c4dc72a9e5873e7b9494fb460715e..26efd9d8124b8d6fdf5d0cd691b3425c46346bda 100644 (file)
@@ -30,6 +30,8 @@ class ImageDispatcher : public Dispatcher<ImageCtxT, ImageDispatcherInterface> {
 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<ImageCtxT, ImageDispatcherInterface>::C_InvalidateCache;
+
   std::atomic<uint64_t> m_next_tid{0};
 
   QosImageDispatch<ImageCtxT>* m_qos_image_dispatch = nullptr;
index 78f90977d7805701ca27351a503dcd86a0169ffb..8bff8566ed24578bfc4f3338841e1600cf1f6dbc 100644 (file)
@@ -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
index 16cc1722f0c37f7b26c163489c7775e40c835169..3bc55a57fd64213f9611e90f1a0756a1b04e053a 100644 (file)
 namespace librbd {
 namespace io {
 
-template <typename I>
-struct ObjectDispatcher<I>::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 <typename I>
-struct ObjectDispatcher<I>::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 <typename I>
 struct ObjectDispatcher<I>::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<I>::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);
 }
 
index 2cb5904de8e1a2b402f3b4b785a00a3a9412c352..7b356afe6de144679bfa79f1bc6e29b5ff053af7 100644 (file)
@@ -38,13 +38,15 @@ public:
       uint64_t object_no,
       SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override;
 
+  using typename Dispatcher<ImageCtxT, ObjectDispatcherInterface>::C_LayerIterator;
+
+  using typename Dispatcher<ImageCtxT, ObjectDispatcherInterface>::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;
 
index 8ea12d64b8373abe95e27946f226f6b312c8fb09..baf16da02be0e9c73d5b9c8c95982cdbec323fc4 100644 (file)
@@ -100,6 +100,10 @@ public:
     return false;
   }
 
+  bool invalidate_cache(Context* on_finish) override {
+    return false;
+  }
+
 private:
   ImageCtxT* m_image_ctx;
 
index ec94b61d84624496fb066728b96176925c6417f8..60ee467502dad5e0fed87fe43e6e9b87409c6cf4 100644 (file)
@@ -87,6 +87,10 @@ public:
     return false;
   }
 
+  bool invalidate_cache(Context* on_finish) override {
+    return false;
+  }
+
 private:
   ImageCtxT* m_image_ctx;
 
index 144d97bafe8e0bc2c9d664b75c90478a7af742c6..1bcb3c312cf7ae7997be8b10919bacea011d90d5 100644 (file)
@@ -83,6 +83,10 @@ public:
     return false;
   }
 
+  bool invalidate_cache(Context* on_finish) override {
+    return false;
+  }
+
 private:
   ImageCtxT* m_image_ctx;
 
index e8b9407cf543373b9219f10e558a75101ab27010..9d200fb975306c624696eda3f1f1f9ca95d70aa5 100644 (file)
@@ -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);
 
 };
index 490ea2d3987f57992c7ecc21856320b2c5b6d20b..03bb3aa5213739060ff7dde38ea285a12f533384 100644 (file)
@@ -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<FormatInterface> m_format;
index ebd2d829f6f296a9ff1893d4f673b4d124a81fd9..02dff3487b6a98fb1eea9d847680c3835d500718 100644 (file)
@@ -87,6 +87,10 @@ public:
     return false;
   }
 
+  bool invalidate_cache(Context* on_finish) override {
+    return false;
+  }
+
 };
 
 } // namespace io
index 249967d9fd27393fb489a4c8fa44222fc9192a64..14669133048ab6f745eac1da5146b8d926e05c44 100644 (file)
@@ -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));