]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: move generic IO dispatcher logic to base class
authorJason Dillaman <dillaman@redhat.com>
Wed, 29 Apr 2020 03:38:18 +0000 (23:38 -0400)
committerJason Dillaman <dillaman@redhat.com>
Thu, 14 May 2020 15:56:45 +0000 (11:56 -0400)
This will allow re-use between the existing ObjectDispatcher and
the ImageDispatcher that will be added in a future commit.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
36 files changed:
src/librbd/ImageCtx.cc
src/librbd/ImageCtx.h
src/librbd/Journal.cc
src/librbd/cache/ObjectCacherObjectDispatch.cc
src/librbd/cache/ObjectCacherObjectDispatch.h
src/librbd/cache/ObjectCacherWriteback.cc
src/librbd/cache/ParentCacheObjectDispatch.cc
src/librbd/cache/ParentCacheObjectDispatch.h
src/librbd/cache/WriteAroundObjectDispatch.cc
src/librbd/cache/WriteAroundObjectDispatch.h
src/librbd/exclusive_lock/PreReleaseRequest.cc
src/librbd/image/CloseRequest.cc
src/librbd/image/RefreshParentRequest.cc
src/librbd/internal.cc
src/librbd/io/Dispatcher.h [new file with mode: 0644]
src/librbd/io/DispatcherInterface.h [new file with mode: 0644]
src/librbd/io/ImageRequest.cc
src/librbd/io/ObjectDispatch.h
src/librbd/io/ObjectDispatchInterface.h
src/librbd/io/ObjectDispatchSpec.cc
src/librbd/io/ObjectDispatchSpec.h
src/librbd/io/ObjectDispatcher.cc
src/librbd/io/ObjectDispatcher.h
src/librbd/io/ObjectDispatcherInterface.h [new file with mode: 0644]
src/librbd/io/SimpleSchedulerObjectDispatch.cc
src/librbd/io/SimpleSchedulerObjectDispatch.h
src/librbd/io/Types.h
src/librbd/journal/ObjectDispatch.cc
src/librbd/journal/ObjectDispatch.h
src/librbd/operation/ResizeRequest.cc
src/librbd/operation/SnapshotRollbackRequest.cc
src/librbd/operation/TrimRequest.cc
src/test/librbd/cache/test_mock_ParentImageCache.cc
src/test/librbd/mock/io/MockObjectDispatch.h
src/test/librbd/mock/io/MockObjectDispatcher.h
src/test/librbd/test_mock_Journal.cc

index 4026fb934595af9651644dc871979d6ee0ec50dd..1a583aeeb51bb04e76c821fa9131a04a0e0dae30 100644 (file)
@@ -141,7 +141,7 @@ public:
       this, "librbd::io_work_queue",
       cct->_conf.get_val<uint64_t>("rbd_op_thread_timeout"),
       thread_pool);
-    io_object_dispatcher = new io::ObjectDispatcher<>(this);
+    io_object_dispatcher = new io::ObjectDispatcher<ImageCtx>(this);
 
     if (cct->_conf.get_val<bool>("rbd_auto_exclusive_lock_until_manual_request")) {
       exclusive_lock_policy = new exclusive_lock::AutomaticPolicy(this);
index 11f33b1d40c669ac7b0753da4ccb8284fef0099e..74feaafd34af39b55937b34a066f40d758608295 100644 (file)
@@ -59,7 +59,7 @@ namespace librbd {
   class AsyncOperation;
   template <typename> class CopyupRequest;
   template <typename> class ImageRequestWQ;
-  template <typename> class ObjectDispatcher;
+  struct ObjectDispatcherInterface;
   }
   namespace journal { struct Policy; }
 
@@ -181,7 +181,7 @@ namespace librbd {
     xlist<operation::ResizeRequest<ImageCtx>*> resize_reqs;
 
     io::ImageRequestWQ<ImageCtx> *io_work_queue;
-    io::ObjectDispatcher<ImageCtx> *io_object_dispatcher = nullptr;
+    io::ObjectDispatcherInterface *io_object_dispatcher = nullptr;
 
     ContextWQ *op_work_queue;
 
index 66849c461fad21b87eff0092d5822aae68075001..df459af73e1a8e5b64ef0697e39d54d94d8b82f4 100644 (file)
@@ -16,7 +16,7 @@
 #include "librbd/ImageCtx.h"
 #include "librbd/io/ImageRequestWQ.h"
 #include "librbd/io/ObjectDispatchSpec.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/journal/CreateRequest.h"
 #include "librbd/journal/DemoteRequest.h"
 #include "librbd/journal/ObjectDispatch.h"
@@ -572,7 +572,7 @@ void Journal<I>::open(Context *on_finish) {
   on_finish = create_async_context_callback(m_image_ctx, on_finish);
 
   // inject our handler into the object dispatcher chain
-  m_image_ctx.io_object_dispatcher->register_object_dispatch(
+  m_image_ctx.io_object_dispatcher->register_dispatch(
     journal::ObjectDispatch<I>::create(&m_image_ctx, this));
 
   std::lock_guard locker{m_lock};
@@ -593,7 +593,7 @@ void Journal<I>::close(Context *on_finish) {
       auto ctx = new LambdaContext([on_finish, r](int _) {
           on_finish->complete(r);
         });
-      m_image_ctx.io_object_dispatcher->shut_down_object_dispatch(
+      m_image_ctx.io_object_dispatcher->shut_down_dispatch(
         io::OBJECT_DISPATCH_LAYER_JOURNAL, ctx);
     });
   on_finish = create_async_context_callback(m_image_ctx, on_finish);
index 26a75856cb6e38cf88cb9ac3f39a1e743ee6e749..9d304c54a05201809ede97051104fd18fc580df6 100644 (file)
@@ -9,7 +9,7 @@
 #include "librbd/Utils.h"
 #include "librbd/cache/ObjectCacherWriteback.h"
 #include "librbd/io/ObjectDispatchSpec.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/io/Types.h"
 #include "librbd/io/Utils.h"
 #include "osd/osd_types.h"
@@ -151,7 +151,7 @@ void ObjectCacherObjectDispatch<I>::init() {
   if (m_max_dirty > 0) {
     m_image_ctx->disable_zero_copy = true;
   }
-  m_image_ctx->io_object_dispatcher->register_object_dispatch(this);
+  m_image_ctx->io_object_dispatcher->register_dispatch(this);
 }
 
 template <typename I>
index 2c62e31f07ce694bf093767b8b0c12b38f34a092..c6d7af0cd7ae922ab265c14cf713feffac088ffd 100644 (file)
@@ -34,7 +34,7 @@ public:
                              bool writethrough_until_flush);
   ~ObjectCacherObjectDispatch() override;
 
-  io::ObjectDispatchLayer get_object_dispatch_layer() const override {
+  io::ObjectDispatchLayer get_dispatch_layer() const override {
     return io::OBJECT_DISPATCH_LAYER_CACHE;
   }
 
index c6e26506a3a1b386ba36754c0181fbf499dd5f49..169b99a4ce0143ead209fc257c112caac6dbf10e 100644 (file)
@@ -21,7 +21,7 @@
 #include "librbd/Utils.h"
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/ObjectDispatchSpec.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/io/ReadResult.h"
 
 #include "include/ceph_assert.h"
index b405989dc1130f83173663d4a27683dc7cc1cd62..bb8a1aa056cacb3ef9065e7ea54058f3a4810468 100644 (file)
@@ -6,7 +6,7 @@
 #include "librbd/Journal.h"
 #include "librbd/Utils.h"
 #include "librbd/io/ObjectDispatchSpec.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/io/Utils.h"
 #include "librbd/cache/ParentCacheObjectDispatch.h"
 #include "osd/osd_types.h"
@@ -60,7 +60,7 @@ void ParentCacheObjectDispatch<I>::init(Context* on_finish) {
   m_connecting.store(true);
   create_cache_session(create_session_ctx, false);
 
-  m_image_ctx->io_object_dispatcher->register_object_dispatch(this);
+  m_image_ctx->io_object_dispatcher->register_dispatch(this);
   m_initialized = true;
 }
 
index 475a5ad15fe9ecacdfe5a84d2990d3f392309f55..42222dd9d2b865b187737efce4f819da991d6c90 100644 (file)
@@ -29,7 +29,7 @@ public:
   ParentCacheObjectDispatch(ImageCtxT* image_ctx);
   ~ParentCacheObjectDispatch() override;
 
-  io::ObjectDispatchLayer get_object_dispatch_layer() const override {
+  io::ObjectDispatchLayer get_dispatch_layer() const override {
     return io::OBJECT_DISPATCH_LAYER_PARENT_CACHE;
   }
 
index 3a6d315813d9c51e9a18d6032e2bba377fc94062..cdd8ea27160839608a8d3e7e11cea5f692210793 100644 (file)
@@ -8,7 +8,7 @@
 #include "librbd/ImageCtx.h"
 #include "librbd/Utils.h"
 #include "librbd/io/ObjectDispatchSpec.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
@@ -44,7 +44,7 @@ void WriteAroundObjectDispatch<I>::init() {
   if (m_init_max_dirty > 0) {
     m_image_ctx->disable_zero_copy = true;
   }
-  m_image_ctx->io_object_dispatcher->register_object_dispatch(this);
+  m_image_ctx->io_object_dispatcher->register_dispatch(this);
 }
 
 template <typename I>
index ce217d2cf45228b26e5f8669f2e1eaf6fb0a2229..f32e3b4d0f252d421c3798c974ee349cb62e7e15 100644 (file)
@@ -34,7 +34,7 @@ public:
                             bool writethrough_until_flush);
   ~WriteAroundObjectDispatch() override;
 
-  io::ObjectDispatchLayer get_object_dispatch_layer() const override {
+  io::ObjectDispatchLayer get_dispatch_layer() const override {
     return io::OBJECT_DISPATCH_LAYER_CACHE;
   }
 
index fc833a1c80bcac398d7263735b71aa1d70bbcfd0..571af209493303684169c3e730c2c3976347c719 100644 (file)
@@ -12,7 +12,7 @@
 #include "librbd/ObjectMap.h"
 #include "librbd/Utils.h"
 #include "librbd/io/ImageRequestWQ.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
index feae4160e521015440965cbbc536bb60d1f9811f..b9cdbba6a25a075aa5548d68da4e985fec9783b3 100644 (file)
@@ -13,7 +13,7 @@
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/ImageDispatchSpec.h"
 #include "librbd/io/ImageRequestWQ.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
index 88084d13b7739637c0179280341559ea16d9a625..2423c4c885b91548c3fce90d8ade425f21a65fd1 100644 (file)
@@ -10,7 +10,7 @@
 #include "librbd/Utils.h"
 #include "librbd/image/CloseRequest.h"
 #include "librbd/image/OpenRequest.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
index f4350c8ad27d9085abfcad926fe6ee2971cd4256..50559bc445c896ea42db82ff51041b71d9d1dcf3 100644 (file)
@@ -44,7 +44,7 @@
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/ImageRequest.h"
 #include "librbd/io/ImageRequestWQ.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/io/ObjectRequest.h"
 #include "librbd/io/ReadResult.h"
 #include "librbd/journal/Types.h"
diff --git a/src/librbd/io/Dispatcher.h b/src/librbd/io/Dispatcher.h
new file mode 100644 (file)
index 0000000..4b9d8b4
--- /dev/null
@@ -0,0 +1,184 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_IO_DISPATCHER_H
+#define CEPH_LIBRBD_IO_DISPATCHER_H
+
+#include "include/int_types.h"
+#include "include/Context.h"
+#include "common/ceph_mutex.h"
+#include "common/dout.h"
+#include "common/AsyncOpTracker.h"
+#include "librbd/Utils.h"
+#include "librbd/io/Types.h"
+#include <map>
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::io::Dispatcher: " << this \
+                           << " " << __func__ << ": "
+
+namespace librbd {
+namespace io {
+
+template <typename ImageCtxT, typename DispatchInterfaceT>
+class Dispatcher : public DispatchInterfaceT {
+public:
+  typedef typename DispatchInterfaceT::Dispatch Dispatch;
+  typedef typename DispatchInterfaceT::DispatchLayer DispatchLayer;
+  typedef typename DispatchInterfaceT::DispatchSpec DispatchSpec;
+
+  Dispatcher(ImageCtxT* image_ctx)
+    : m_image_ctx(image_ctx),
+      m_lock(ceph::make_shared_mutex(
+        librbd::util::unique_lock_name("librbd::io::Dispatcher::lock",
+                                      this))) {
+  }
+
+  virtual ~Dispatcher() {
+    ceph_assert(m_dispatches.empty());
+  }
+
+  void shut_down(Context* on_finish) override {
+    auto cct = m_image_ctx->cct;
+    ldout(cct, 5) << dendl;
+
+    std::map<DispatchLayer, DispatchMeta> dispatches;
+    {
+      std::unique_lock locker{m_lock};
+      std::swap(dispatches, m_dispatches);
+    }
+
+    for (auto it : dispatches) {
+      shut_down_dispatch(it.second, &on_finish);
+    }
+    on_finish->complete(0);
+  }
+
+  void register_dispatch(Dispatch* dispatch) override {
+    auto cct = m_image_ctx->cct;
+    auto type = dispatch->get_dispatch_layer();
+    ldout(cct, 5) << "dispatch_layer=" << type << dendl;
+
+    std::unique_lock locker{m_lock};
+
+    auto result = m_dispatches.insert(
+      {type, {dispatch, new AsyncOpTracker()}});
+    ceph_assert(result.second);
+  }
+
+  void shut_down_dispatch(DispatchLayer dispatch_layer,
+                          Context* on_finish) override {
+    auto cct = m_image_ctx->cct;
+    ldout(cct, 5) << "dispatch_layer=" << dispatch_layer << dendl;
+
+    DispatchMeta dispatch_meta;
+    {
+      std::unique_lock locker{m_lock};
+      auto it = m_dispatches.find(dispatch_layer);
+      ceph_assert(it != m_dispatches.end());
+
+      dispatch_meta = it->second;
+      m_dispatches.erase(it);
+    }
+
+    shut_down_dispatch(dispatch_meta, &on_finish);
+    on_finish->complete(0);
+  }
+
+  void send(DispatchSpec* dispatch_spec) {
+    auto cct = m_image_ctx->cct;
+    ldout(cct, 20) << "dispatch_spec=" << dispatch_spec << dendl;
+
+    auto dispatch_layer = dispatch_spec->dispatch_layer;
+
+    // apply the IO request to all layers -- this method will be re-invoked
+    // by the dispatch layer if continuing / restarting the IO
+    while (true) {
+      m_lock.lock_shared();
+      dispatch_layer = dispatch_spec->dispatch_layer;
+      auto it = m_dispatches.upper_bound(dispatch_layer);
+      if (it == m_dispatches.end()) {
+        // the request is complete if handled by all layers
+        dispatch_spec->dispatch_result = DISPATCH_RESULT_COMPLETE;
+        m_lock.unlock_shared();
+        break;
+      }
+
+      auto& dispatch_meta = it->second;
+      auto dispatch = dispatch_meta.dispatch;
+      auto async_op_tracker = dispatch_meta.async_op_tracker;
+      dispatch_spec->dispatch_result = DISPATCH_RESULT_INVALID;
+
+      // prevent recursive locking back into the dispatcher while handling IO
+      async_op_tracker->start_op();
+      m_lock.unlock_shared();
+
+      // advance to next layer in case we skip or continue
+      dispatch_spec->dispatch_layer = dispatch->get_dispatch_layer();
+
+      bool handled = send_dispatch(dispatch, dispatch_spec);
+      async_op_tracker->finish_op();
+
+      // handled ops will resume when the dispatch ctx is invoked
+      if (handled) {
+        return;
+      }
+    }
+
+    // skipped through to the last layer
+    dispatch_spec->dispatcher_ctx.complete(0);
+  }
+
+protected:
+  struct DispatchMeta {
+    Dispatch* dispatch = nullptr;
+    AsyncOpTracker* async_op_tracker = nullptr;
+
+    DispatchMeta() {
+    }
+    DispatchMeta(Dispatch* dispatch, AsyncOpTracker* async_op_tracker)
+      : dispatch(dispatch), async_op_tracker(async_op_tracker) {
+    }
+  };
+
+  ImageCtxT* m_image_ctx;
+
+  ceph::shared_mutex m_lock;
+  std::map<DispatchLayer, DispatchMeta> m_dispatches;
+
+  virtual bool send_dispatch(Dispatch* dispatch,
+                             DispatchSpec* dispatch_spec) = 0;
+
+private:
+  void shut_down_dispatch(DispatchMeta& dispatch_meta,
+                          Context** on_finish) {
+    auto dispatch = dispatch_meta.dispatch;
+    auto async_op_tracker = dispatch_meta.async_op_tracker;
+
+    auto ctx = *on_finish;
+    ctx = new LambdaContext(
+      [dispatch, async_op_tracker, ctx](int r) {
+        delete dispatch;
+        delete async_op_tracker;
+
+        ctx->complete(r);
+      });
+    ctx = new LambdaContext([dispatch, ctx](int r) {
+        dispatch->shut_down(ctx);
+      });
+    *on_finish = new LambdaContext([async_op_tracker, ctx](int r) {
+        async_op_tracker->wait_for_ops(ctx);
+      });
+  }
+
+};
+
+} // namespace io
+} // namespace librbd
+
+#undef dout_subsys
+#undef dout_prefix
+#define dout_prefix *_dout
+
+#endif // CEPH_LIBRBD_IO_DISPATCHER_H
diff --git a/src/librbd/io/DispatcherInterface.h b/src/librbd/io/DispatcherInterface.h
new file mode 100644 (file)
index 0000000..57a5660
--- /dev/null
@@ -0,0 +1,36 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_IO_DISPATCHER_INTERFACE_H
+#define CEPH_LIBRBD_IO_DISPATCHER_INTERFACE_H
+
+#include "include/int_types.h"
+
+struct Context;
+
+namespace librbd {
+namespace io {
+
+template <typename DispatchT>
+struct DispatcherInterface {
+public:
+  typedef DispatchT Dispatch;
+  typedef typename DispatchT::DispatchLayer DispatchLayer;
+  typedef typename DispatchT::DispatchSpec DispatchSpec;
+
+  virtual ~DispatcherInterface() {
+  }
+
+  virtual void shut_down(Context* on_finish) = 0;
+
+  virtual void register_dispatch(Dispatch* dispatch) = 0;
+  virtual void shut_down_dispatch(DispatchLayer dispatch_layer,
+                                  Context* on_finish) = 0;
+
+  virtual void send(DispatchSpec* dispatch_spec) = 0;
+};
+
+} // namespace io
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_IO_DISPATCHER_INTERFACE_H
index 7b7e7e4f1594cde27a6eea7c007c90756b4e6f44..141f8f12740211304d5de10507856fc563e0218a 100644 (file)
@@ -12,7 +12,7 @@
 #include "librbd/io/AsyncOperation.h"
 #include "librbd/io/ObjectDispatchInterface.h"
 #include "librbd/io/ObjectDispatchSpec.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/io/Utils.h"
 #include "librbd/journal/Types.h"
 #include "include/rados/librados.hpp"
index 8f04143e4fa112132c3db8d982ad8a20655b0e63..cbfe8b5ad0e3e7b660e7ce199de3a5fc9f6524e6 100644 (file)
@@ -27,7 +27,7 @@ class ObjectDispatch : public ObjectDispatchInterface {
 public:
   ObjectDispatch(ImageCtxT* image_ctx);
 
-  ObjectDispatchLayer get_object_dispatch_layer() const override {
+  ObjectDispatchLayer get_dispatch_layer() const override {
     return OBJECT_DISPATCH_LAYER_CORE;
   }
 
index 168d8006d1448273b6851667a599a756536cc396..31ed39994ebe2c9a07c4e03cc7874b0cc666867e 100644 (file)
@@ -18,12 +18,18 @@ namespace librbd {
 namespace io {
 
 struct AioCompletion;
+struct ObjectDispatchInterface;
+struct ObjectDispatchSpec;
 
 struct ObjectDispatchInterface {
+  typedef ObjectDispatchInterface Dispatch;
+  typedef ObjectDispatchLayer DispatchLayer;
+  typedef ObjectDispatchSpec DispatchSpec;
+
   virtual ~ObjectDispatchInterface() {
   }
 
-  virtual ObjectDispatchLayer get_object_dispatch_layer() const = 0;
+  virtual ObjectDispatchLayer get_dispatch_layer() const = 0;
 
   virtual void shut_down(Context* on_finish) = 0;
 
index 2b6dccc5cfcae5272d1d29860e3587287c1b3be6..0a4a3474eeef4b98cb167e8ed114031e64c87d66 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "librbd/io/ObjectDispatchSpec.h"
 #include "include/Context.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include <boost/variant.hpp>
 
 namespace librbd {
index 654ed3dd31cd0473aff13b31d1cf97f13c8b31b6..91a76d7eea092cca9f59c7e54ac143d6e4333f94 100644 (file)
@@ -142,7 +142,7 @@ public:
   C_Dispatcher dispatcher_ctx;
 
   ObjectDispatcherInterface* object_dispatcher;
-  ObjectDispatchLayer object_dispatch_layer;
+  ObjectDispatchLayer dispatch_layer;
   int object_dispatch_flags = 0;
   DispatchResult dispatch_result = DISPATCH_RESULT_INVALID;
 
@@ -250,7 +250,7 @@ private:
                      Request&& request, int op_flags,
                      const ZTracer::Trace& parent_trace, Context* on_finish)
     : dispatcher_ctx(this, on_finish), object_dispatcher(object_dispatcher),
-      object_dispatch_layer(object_dispatch_layer), request(std::move(request)),
+      dispatch_layer(object_dispatch_layer), request(std::move(request)),
       op_flags(op_flags), parent_trace(parent_trace) {
   }
 
index 9a74a81340db44bc6649ab5e8c19bb9ed9e94c9f..25ed4989c3eb9e64d90d625d21aa61df6a344e2f 100644 (file)
@@ -35,23 +35,23 @@ struct ObjectDispatcher<I>::C_LayerIterator : public Context {
   void complete(int r) override {
     while (true) {
       object_dispatcher->m_lock.lock_shared();
-      auto it = object_dispatcher->m_object_dispatches.upper_bound(
+      auto it = object_dispatcher->m_dispatches.upper_bound(
         object_dispatch_layer);
-      if (it == object_dispatcher->m_object_dispatches.end()) {
+      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.object_dispatch;
+      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_object_dispatch_layer();
+      object_dispatch_layer = object_dispatch->get_dispatch_layer();
 
       auto handled = execute(object_dispatch, this);
       object_dispatch_meta.async_op_tracker->finish_op();
@@ -174,112 +174,30 @@ struct ObjectDispatcher<I>::SendVisitor : public boost::static_visitor<bool> {
 
 template <typename I>
 ObjectDispatcher<I>::ObjectDispatcher(I* image_ctx)
-  : m_image_ctx(image_ctx),
-    m_lock(ceph::make_shared_mutex(
-      librbd::util::unique_lock_name("librbd::io::ObjectDispatcher::lock",
-                                    this))) {
+  : Dispatcher<I, ObjectDispatcherInterface>(image_ctx) {
   // configure the core object dispatch handler on startup
   auto object_dispatch = new ObjectDispatch(image_ctx);
-  m_object_dispatches[object_dispatch->get_object_dispatch_layer()] =
-    {object_dispatch, new AsyncOpTracker()};
-}
-
-template <typename I>
-ObjectDispatcher<I>::~ObjectDispatcher() {
-  ceph_assert(m_object_dispatches.empty());
-}
-
-template <typename I>
-void ObjectDispatcher<I>::shut_down(Context* on_finish) {
-  auto cct = m_image_ctx->cct;
-  ldout(cct, 5) << dendl;
-
-  std::map<ObjectDispatchLayer, ObjectDispatchMeta> object_dispatches;
-  {
-    std::unique_lock locker{m_lock};
-    std::swap(object_dispatches, m_object_dispatches);
-  }
-
-  for (auto it : object_dispatches) {
-    shut_down_object_dispatch(it.second, &on_finish);
-  }
-  on_finish->complete(0);
-}
-
-template <typename I>
-void ObjectDispatcher<I>::register_object_dispatch(
-    ObjectDispatchInterface* object_dispatch) {
-  auto cct = m_image_ctx->cct;
-  auto type = object_dispatch->get_object_dispatch_layer();
-  ldout(cct, 5) << "object_dispatch_layer=" << type << dendl;
-
-  std::unique_lock locker{m_lock};
-  ceph_assert(type < OBJECT_DISPATCH_LAYER_LAST);
-
-  auto result = m_object_dispatches.insert(
-    {type, {object_dispatch, new AsyncOpTracker()}});
-  ceph_assert(result.second);
-}
-
-template <typename I>
-void ObjectDispatcher<I>::shut_down_object_dispatch(
-    ObjectDispatchLayer object_dispatch_layer, Context* on_finish) {
-  auto cct = m_image_ctx->cct;
-  ldout(cct, 5) << "object_dispatch_layer=" << object_dispatch_layer << dendl;
-  ceph_assert(object_dispatch_layer + 1 < OBJECT_DISPATCH_LAYER_LAST);
-
-  ObjectDispatchMeta object_dispatch_meta;
-  {
-    std::unique_lock locker{m_lock};
-    auto it = m_object_dispatches.find(object_dispatch_layer);
-    ceph_assert(it != m_object_dispatches.end());
-
-    object_dispatch_meta = it->second;
-    m_object_dispatches.erase(it);
-  }
-
-  shut_down_object_dispatch(object_dispatch_meta, &on_finish);
-  on_finish->complete(0);
-}
-
-template <typename I>
-void ObjectDispatcher<I>::shut_down_object_dispatch(
-    ObjectDispatchMeta& object_dispatch_meta, Context** on_finish) {
-  auto object_dispatch = object_dispatch_meta.object_dispatch;
-  auto async_op_tracker = object_dispatch_meta.async_op_tracker;
-
-  Context* ctx = *on_finish;
-  ctx = new LambdaContext(
-    [object_dispatch, async_op_tracker, ctx](int r) {
-      delete object_dispatch;
-      delete async_op_tracker;
-
-      ctx->complete(r);
-    });
-  ctx = new LambdaContext([object_dispatch, ctx](int r) {
-      object_dispatch->shut_down(ctx);
-    });
-  *on_finish = new LambdaContext([async_op_tracker, ctx](int r) {
-      async_op_tracker->wait_for_ops(ctx);
-    });
+  this->register_dispatch(object_dispatch);
 }
 
 template <typename I>
 void ObjectDispatcher<I>::invalidate_cache(Context* on_finish) {
-  auto cct = m_image_ctx->cct;
+  auto image_ctx = this->m_image_ctx;
+  auto cct = image_ctx->cct;
   ldout(cct, 5) << dendl;
 
-  on_finish = util::create_async_context_callback(*m_image_ctx, on_finish);
+  on_finish = util::create_async_context_callback(*image_ctx, on_finish);
   auto ctx = new C_InvalidateCache(this, on_finish);
   ctx->complete(0);
 }
 
 template <typename I>
 void ObjectDispatcher<I>::reset_existence_cache(Context* on_finish) {
-  auto cct = m_image_ctx->cct;
+  auto image_ctx = this->m_image_ctx;
+  auto cct = image_ctx->cct;
   ldout(cct, 5) << dendl;
 
-  on_finish = util::create_async_context_callback(*m_image_ctx, on_finish);
+  on_finish = util::create_async_context_callback(*image_ctx, on_finish);
   auto ctx = new C_ResetExistenceCache(this, on_finish);
   ctx->complete(0);
 }
@@ -288,64 +206,26 @@ template <typename I>
 void ObjectDispatcher<I>::extent_overwritten(
     uint64_t object_no, uint64_t object_off, uint64_t object_len,
     uint64_t journal_tid, uint64_t new_journal_tid) {
-  auto cct = m_image_ctx->cct;
+  auto cct = this->m_image_ctx->cct;
   ldout(cct, 20) << object_no << " " << object_off << "~" << object_len
                  << dendl;
 
-  for (auto it : m_object_dispatches) {
+  std::shared_lock locker{this->m_lock};
+  for (auto it : this->m_dispatches) {
     auto& object_dispatch_meta = it.second;
-    auto object_dispatch = object_dispatch_meta.object_dispatch;
+    auto object_dispatch = object_dispatch_meta.dispatch;
     object_dispatch->extent_overwritten(object_no, object_off, object_len,
                                         journal_tid, new_journal_tid);
   }
 }
 
 template <typename I>
-void ObjectDispatcher<I>::send(ObjectDispatchSpec* object_dispatch_spec) {
-  auto cct = m_image_ctx->cct;
-  ldout(cct, 20) << "object_dispatch_spec=" << object_dispatch_spec << dendl;
-
-  auto object_dispatch_layer = object_dispatch_spec->object_dispatch_layer;
-  ceph_assert(object_dispatch_layer + 1 < OBJECT_DISPATCH_LAYER_LAST);
-
-  // apply the IO request to all layers -- this method will be re-invoked
-  // by the dispatch layer if continuing / restarting the IO
-  while (true) {
-    m_lock.lock_shared();
-    object_dispatch_layer = object_dispatch_spec->object_dispatch_layer;
-    auto it = m_object_dispatches.upper_bound(object_dispatch_layer);
-    if (it == m_object_dispatches.end()) {
-      // the request is complete if handled by all layers
-      object_dispatch_spec->dispatch_result = DISPATCH_RESULT_COMPLETE;
-      m_lock.unlock_shared();
-      break;
-    }
-
-    auto& object_dispatch_meta = it->second;
-    auto object_dispatch = object_dispatch_meta.object_dispatch;
-    object_dispatch_spec->dispatch_result = DISPATCH_RESULT_INVALID;
-
-    // prevent recursive locking back into the dispatcher while handling IO
-    object_dispatch_meta.async_op_tracker->start_op();
-    m_lock.unlock_shared();
-
-    // advance to next layer in case we skip or continue
-    object_dispatch_spec->object_dispatch_layer =
-      object_dispatch->get_object_dispatch_layer();
-
-    bool handled = boost::apply_visitor(
-      SendVisitor{object_dispatch, object_dispatch_spec},
-      object_dispatch_spec->request);
-    object_dispatch_meta.async_op_tracker->finish_op();
-
-    // handled ops will resume when the dispatch ctx is invoked
-    if (handled) {
-      return;
-    }
-  }
-
-  // skipped through to the last layer
-  object_dispatch_spec->dispatcher_ctx.complete(0);
+bool ObjectDispatcher<I>::send_dispatch(
+    ObjectDispatchInterface* object_dispatch,
+    ObjectDispatchSpec* object_dispatch_spec) {
+  return boost::apply_visitor(
+    SendVisitor{object_dispatch, object_dispatch_spec},
+    object_dispatch_spec->request);
 }
 
 } // namespace io
index c949a97573fb83a4f6e66de664be4c4f17f35844..0f8317fb437bd423af68d61d3068d6faf4aad68f 100644 (file)
@@ -6,10 +6,13 @@
 
 #include "include/int_types.h"
 #include "common/ceph_mutex.h"
+#include "librbd/io/Dispatcher.h"
+#include "librbd/io/ObjectDispatchInterface.h"
+#include "librbd/io/ObjectDispatchSpec.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/io/Types.h"
 #include <map>
 
-struct AsyncOpTracker;
 struct Context;
 
 namespace librbd {
@@ -18,67 +21,29 @@ struct ImageCtx;
 
 namespace io {
 
-struct ObjectDispatchInterface;
-struct ObjectDispatchSpec;
-
-struct ObjectDispatcherInterface {
-public:
-  virtual ~ObjectDispatcherInterface() {
-  }
-
-private:
-  friend class ObjectDispatchSpec;
-
-  virtual void send(ObjectDispatchSpec* object_dispatch_spec) = 0;
-};
-
 template <typename ImageCtxT = ImageCtx>
-class ObjectDispatcher : public ObjectDispatcherInterface {
+class ObjectDispatcher
+  : public Dispatcher<ImageCtxT, ObjectDispatcherInterface> {
 public:
   ObjectDispatcher(ImageCtxT* image_ctx);
-  ~ObjectDispatcher();
-
-  void shut_down(Context* on_finish);
 
-  void register_object_dispatch(ObjectDispatchInterface* object_dispatch);
-  void shut_down_object_dispatch(ObjectDispatchLayer object_dispatch_layer,
-                                 Context* on_finish);
-
-  void invalidate_cache(Context* on_finish);
-  void reset_existence_cache(Context* on_finish);
+  void invalidate_cache(Context* on_finish) override;
+  void reset_existence_cache(Context* on_finish) override;
 
   void extent_overwritten(
       uint64_t object_no, uint64_t object_off, uint64_t object_len,
-      uint64_t journal_tid, uint64_t new_journal_tid);
-
-private:
-  struct ObjectDispatchMeta {
-    ObjectDispatchInterface* object_dispatch = nullptr;
-    AsyncOpTracker* async_op_tracker = nullptr;
+      uint64_t journal_tid, uint64_t new_journal_tid) override;
 
-    ObjectDispatchMeta() {
-    }
-    ObjectDispatchMeta(ObjectDispatchInterface* object_dispatch,
-                       AsyncOpTracker* async_op_tracker)
-      : object_dispatch(object_dispatch), async_op_tracker(async_op_tracker) {
-    }
-  };
+protected:
+  bool send_dispatch(ObjectDispatchInterface* object_dispatch,
+                     ObjectDispatchSpec* object_dispatch_spec) override;
 
+private:
   struct C_LayerIterator;
   struct C_InvalidateCache;
   struct C_ResetExistenceCache;
   struct SendVisitor;
 
-  ImageCtxT* m_image_ctx;
-
-  ceph::shared_mutex m_lock;
-  std::map<ObjectDispatchLayer, ObjectDispatchMeta> m_object_dispatches;
-
-  void send(ObjectDispatchSpec* object_dispatch_spec);
-
-  void shut_down_object_dispatch(ObjectDispatchMeta& object_dispatch_meta,
-                                 Context** on_finish);
-
 };
 
 } // namespace io
diff --git a/src/librbd/io/ObjectDispatcherInterface.h b/src/librbd/io/ObjectDispatcherInterface.h
new file mode 100644 (file)
index 0000000..0b2befd
--- /dev/null
@@ -0,0 +1,30 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_IO_OBJECT_DISPATCHER_INTERFACE_H
+#define CEPH_LIBRBD_IO_OBJECT_DISPATCHER_INTERFACE_H
+
+#include "include/int_types.h"
+#include "librbd/io/DispatcherInterface.h"
+#include "librbd/io/ObjectDispatchInterface.h"
+
+struct Context;
+
+namespace librbd {
+namespace io {
+
+struct ObjectDispatcherInterface
+  : public DispatcherInterface<ObjectDispatchInterface> {
+public:
+  virtual void invalidate_cache(Context* on_finish) = 0;
+  virtual void reset_existence_cache(Context* on_finish) = 0;
+
+  virtual void extent_overwritten(
+      uint64_t object_no, uint64_t object_off, uint64_t object_len,
+      uint64_t journal_tid, uint64_t new_journal_tid) = 0;
+};
+
+} // namespace io
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_IO_OBJECT_DISPATCHER_INTERFACE_H
index 6b6a60c9862bf343863d0b36d51307d6794470d8..bae5f2044259b4ec35b178581200ab369ed9a93a 100644 (file)
@@ -198,7 +198,7 @@ void SimpleSchedulerObjectDispatch<I>::init() {
   ldout(cct, 5) << dendl;
 
   // add ourself to the IO object dispatcher chain
-  m_image_ctx->io_object_dispatcher->register_object_dispatch(this);
+  m_image_ctx->io_object_dispatcher->register_dispatch(this);
 }
 
 template <typename I>
index e5a88371d7f3a19f2f1d34b9690adbbb05e2cca6..cca6b12b4c367cd56664388f9ae65c954bc5619b 100644 (file)
@@ -41,7 +41,7 @@ public:
   SimpleSchedulerObjectDispatch(ImageCtxT* image_ctx);
   ~SimpleSchedulerObjectDispatch() override;
 
-  ObjectDispatchLayer get_object_dispatch_layer() const override {
+  ObjectDispatchLayer get_dispatch_layer() const override {
     return OBJECT_DISPATCH_LAYER_SCHEDULER;
   }
 
index daa663c4cbb5da0e8828b055b1824646572754d5..e9edced202034c79d49a0f211396aadac1c26a9d 100644 (file)
@@ -9,6 +9,8 @@
 #include <map>
 #include <vector>
 
+struct Context;
+
 namespace librbd {
 namespace io {
 
index e4bdca007cac12a5a1c097a58487b24b6739f43e..b3db10080074de1edae0aed6ab3bec083b72517a 100644 (file)
@@ -9,7 +9,7 @@
 #include "librbd/Journal.h"
 #include "librbd/Utils.h"
 #include "librbd/io/ObjectDispatchSpec.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
index 47b19524a93f204c56b22473e5ceabaf54c9c723..e63f05535f8e5368b709ce36b772f9a44404f76d 100644 (file)
@@ -31,7 +31,7 @@ public:
 
   ObjectDispatch(ImageCtxT* image_ctx, Journal<ImageCtxT>* journal);
 
-  io::ObjectDispatchLayer get_object_dispatch_layer() const override {
+  io::ObjectDispatchLayer get_dispatch_layer() const override {
     return io::OBJECT_DISPATCH_LAYER_JOURNAL;
   }
 
index 8db5afb3393d87c5faae28800b92ff874276ca66..a14b6de24f42083bf4be8bc867afc382fe5d039c 100644 (file)
@@ -10,7 +10,7 @@
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/ImageDispatchSpec.h"
 #include "librbd/io/ImageRequestWQ.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/operation/TrimRequest.h"
 #include "common/dout.h"
 #include "common/errno.h"
index 5dd3f2573eb20d544c2d9f379987d47f9796e44f..a18f79509f35f3ce01078ef8465e8f1361a0b9bb 100644 (file)
@@ -10,7 +10,7 @@
 #include "librbd/ObjectMap.h"
 #include "librbd/Utils.h"
 #include "librbd/io/ImageRequestWQ.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/operation/ResizeRequest.h"
 #include "osdc/Striper.h"
 #include <boost/lambda/bind.hpp>
index 3c2f58f64af827d8d67ba7fc59164c2464c955d6..0fcb7af034bd73be6710a6c4fbac0ed07e47f2c7 100644 (file)
@@ -9,7 +9,7 @@
 #include "librbd/ObjectMap.h"
 #include "librbd/Utils.h"
 #include "librbd/io/ObjectDispatchSpec.h"
-#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatcherInterface.h"
 #include "common/ContextCompletion.h"
 #include "common/dout.h"
 #include "common/errno.h"
index d48b5ec1993e53922b9e035e71f3fbcd0e3b4601..8ee85acd762b3cd9f43893ced89ecb60dbfb3de2 100644 (file)
@@ -133,7 +133,7 @@ class TestMockParentImageCache : public TestMockFixture {
   void expect_io_object_dispatcher_register_state(MockParentImageCache& mparent_image_cache, 
                                                   int ret_val) {
     auto& expect = EXPECT_CALL((*(mparent_image_cache.get_image_ctx()->io_object_dispatcher)),
-                               register_object_dispatch(_));
+                               register_dispatch(_));
 
         expect.WillOnce(WithArg<0>(Invoke([ret_val, &mparent_image_cache]
                 (io::ObjectDispatchInterface* object_dispatch) {
@@ -168,7 +168,7 @@ TEST_F(TestMockParentImageCache, test_initialization_success) {
   mock_parent_image_cache->init();
   cond.wait();
 
-  ASSERT_EQ(mock_parent_image_cache->get_object_dispatch_layer(),
+  ASSERT_EQ(mock_parent_image_cache->get_dispatch_layer(),
             io::OBJECT_DISPATCH_LAYER_PARENT_CACHE);
   ASSERT_EQ(mock_parent_image_cache->get_state(), true);
   expect_cache_session_state(*mock_parent_image_cache, true);
@@ -202,7 +202,7 @@ TEST_F(TestMockParentImageCache, test_initialization_fail_at_connect) {
   mock_parent_image_cache->init();
 
   // initialization fails.
-  ASSERT_EQ(mock_parent_image_cache->get_object_dispatch_layer(),
+  ASSERT_EQ(mock_parent_image_cache->get_dispatch_layer(),
             io::OBJECT_DISPATCH_LAYER_PARENT_CACHE);
   ASSERT_EQ(mock_parent_image_cache->get_state(), true);
   ASSERT_EQ(mock_parent_image_cache->get_cache_client()->is_session_work(), false);
@@ -240,7 +240,7 @@ TEST_F(TestMockParentImageCache, test_initialization_fail_at_register) {
   mock_parent_image_cache->init();
   cond.wait();
 
-  ASSERT_EQ(mock_parent_image_cache->get_object_dispatch_layer(),
+  ASSERT_EQ(mock_parent_image_cache->get_dispatch_layer(),
             io::OBJECT_DISPATCH_LAYER_PARENT_CACHE);
   ASSERT_EQ(mock_parent_image_cache->get_state(), true);
   expect_cache_session_state(*mock_parent_image_cache, true);
@@ -317,7 +317,7 @@ TEST_F(TestMockParentImageCache, test_read) {
   mock_parent_image_cache->init();
   conn_cond.wait();
 
-  ASSERT_EQ(mock_parent_image_cache->get_object_dispatch_layer(),
+  ASSERT_EQ(mock_parent_image_cache->get_dispatch_layer(),
             io::OBJECT_DISPATCH_LAYER_PARENT_CACHE);
   ASSERT_EQ(mock_parent_image_cache->get_state(), true);
   expect_cache_session_state(*mock_parent_image_cache, true);
index bd3d28693e933f5e14847e6f48696d8179acc8a6..16cf4b0d2b134620c518984408add19d72c5b02d 100644 (file)
@@ -20,7 +20,7 @@ public:
   MockObjectDispatch() : lock("MockObjectDispatch::lock", true, false) {
   }
 
-  MOCK_CONST_METHOD0(get_object_dispatch_layer, ObjectDispatchLayer());
+  MOCK_CONST_METHOD0(get_dispatch_layer, ObjectDispatchLayer());
 
   MOCK_METHOD1(shut_down, void(Context*));
 
index 271c30102a322eae357fac5ae2c7e8eebb18354c..908e2186816daccf93cb0d1a8936a9ea802d96d5 100644 (file)
@@ -21,19 +21,18 @@ struct MockObjectDispatcher : public ObjectDispatcherInterface {
 public:
   MOCK_METHOD1(shut_down, void(Context*));
 
-  MOCK_METHOD1(register_object_dispatch, void(ObjectDispatchInterface*));
-  MOCK_METHOD2(shut_down_object_dispatch, void(ObjectDispatchLayer, Context*));
+  MOCK_METHOD1(register_dispatch, void(ObjectDispatchInterface*));
+  MOCK_METHOD2(shut_down_dispatch, void(ObjectDispatchLayer, Context*));
 
   MOCK_METHOD2(flush, void(FlushSource, Context*));
 
   MOCK_METHOD1(invalidate_cache, void(Context*));
-  MOCK_METHOD1(reset_existance_cache, void(Context*));
+  MOCK_METHOD1(reset_existence_cache, void(Context*));
 
   MOCK_METHOD5(extent_overwritten, void(uint64_t, uint64_t, uint64_t, uint64_t,
                                         uint64_t));
 
   MOCK_METHOD1(send, void(ObjectDispatchSpec*));
-
 };
 
 } // namespace io
index 78a7ae73ccca06a907023ba490eeaf189f2c3adf..bab068be063cc47a732587d0c2d8cbea9dd5a47c 100644 (file)
@@ -300,15 +300,15 @@ public:
                   .WillOnce(CompleteContext(0, static_cast<ContextWQ*>(NULL)));
   }
 
-  void expect_register_object_dispatch(MockImageCtx& mock_image_ctx,
-                                       MockObjectDispatch& mock_object_dispatch) {
+  void expect_register_dispatch(MockImageCtx& mock_image_ctx,
+                                MockObjectDispatch& mock_object_dispatch) {
     EXPECT_CALL(*mock_image_ctx.io_object_dispatcher,
-                register_object_dispatch(&mock_object_dispatch));
+                register_dispatch(&mock_object_dispatch));
   }
 
-  void expect_shut_down_object_dispatch(MockImageCtx& mock_image_ctx) {
+  void expect_shut_down_dispatch(MockImageCtx& mock_image_ctx) {
     EXPECT_CALL(*mock_image_ctx.io_object_dispatcher,
-                shut_down_object_dispatch(io::OBJECT_DISPATCH_LAYER_JOURNAL, _))
+                shut_down_dispatch(io::OBJECT_DISPATCH_LAYER_JOURNAL, _))
       .WillOnce(WithArg<1>(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue)));
   }
 
@@ -510,7 +510,7 @@ public:
     expect_op_work_queue(mock_image_ctx);
 
     InSequence seq;
-    expect_register_object_dispatch(mock_image_ctx, mock_object_dispatch);
+    expect_register_dispatch(mock_image_ctx, mock_object_dispatch);
     expect_construct_journaler(mock_journaler);
     expect_open_journaler(mock_image_ctx, mock_journaler, mock_open_request,
                           primary, 0);
@@ -533,7 +533,7 @@ public:
                      MockJournal *mock_journal,
                      ::journal::MockJournaler &mock_journaler) {
     expect_stop_append(mock_journaler, 0);
-    expect_shut_down_object_dispatch(mock_image_ctx);
+    expect_shut_down_dispatch(mock_image_ctx);
     ASSERT_EQ(0, when_close(mock_journal));
   }
 
@@ -566,7 +566,7 @@ TEST_F(TestMockJournal, StateTransitions) {
   InSequence seq;
 
   MockObjectDispatch mock_object_dispatch;
-  expect_register_object_dispatch(mock_image_ctx, mock_object_dispatch);
+  expect_register_dispatch(mock_image_ctx, mock_object_dispatch);
 
   ::journal::MockJournaler mock_journaler;
   MockJournalOpenRequest mock_open_request;
@@ -603,7 +603,7 @@ TEST_F(TestMockJournal, StateTransitions) {
 
   expect_stop_append(mock_journaler, 0);
   expect_shut_down_journaler(mock_journaler);
-  expect_shut_down_object_dispatch(mock_image_ctx);
+  expect_shut_down_dispatch(mock_image_ctx);
   ASSERT_EQ(0, when_close(mock_journal));
 }
 
@@ -624,7 +624,7 @@ TEST_F(TestMockJournal, InitError) {
   InSequence seq;
 
   MockObjectDispatch mock_object_dispatch;
-  expect_register_object_dispatch(mock_image_ctx, mock_object_dispatch);
+  expect_register_dispatch(mock_image_ctx, mock_object_dispatch);
 
   ::journal::MockJournaler mock_journaler;
   MockJournalOpenRequest mock_open_request;
@@ -652,7 +652,7 @@ TEST_F(TestMockJournal, ReplayCompleteError) {
   InSequence seq;
 
   MockObjectDispatch mock_object_dispatch;
-  expect_register_object_dispatch(mock_image_ctx, mock_object_dispatch);
+  expect_register_dispatch(mock_image_ctx, mock_object_dispatch);
 
   ::journal::MockJournaler mock_journaler;
   MockJournalOpenRequest mock_open_request;
@@ -688,7 +688,7 @@ TEST_F(TestMockJournal, ReplayCompleteError) {
 
   expect_stop_append(mock_journaler, 0);
   expect_shut_down_journaler(mock_journaler);
-  expect_shut_down_object_dispatch(mock_image_ctx);
+  expect_shut_down_dispatch(mock_image_ctx);
   ASSERT_EQ(0, when_close(mock_journal));
 }
 
@@ -709,7 +709,7 @@ TEST_F(TestMockJournal, FlushReplayError) {
   InSequence seq;
 
   MockObjectDispatch mock_object_dispatch;
-  expect_register_object_dispatch(mock_image_ctx, mock_object_dispatch);
+  expect_register_dispatch(mock_image_ctx, mock_object_dispatch);
 
   ::journal::MockJournaler mock_journaler;
   MockJournalOpenRequest mock_open_request;
@@ -750,7 +750,7 @@ TEST_F(TestMockJournal, FlushReplayError) {
 
   expect_stop_append(mock_journaler, 0);
   expect_shut_down_journaler(mock_journaler);
-  expect_shut_down_object_dispatch(mock_image_ctx);
+  expect_shut_down_dispatch(mock_image_ctx);
   ASSERT_EQ(0, when_close(mock_journal));
 }
 
@@ -771,7 +771,7 @@ TEST_F(TestMockJournal, CorruptEntry) {
   InSequence seq;
 
   MockObjectDispatch mock_object_dispatch;
-  expect_register_object_dispatch(mock_image_ctx, mock_object_dispatch);
+  expect_register_dispatch(mock_image_ctx, mock_object_dispatch);
 
   ::journal::MockJournaler mock_journaler;
   MockJournalOpenRequest mock_open_request;
@@ -809,7 +809,7 @@ TEST_F(TestMockJournal, CorruptEntry) {
 
   expect_stop_append(mock_journaler, -EINVAL);
   expect_shut_down_journaler(mock_journaler);
-  expect_shut_down_object_dispatch(mock_image_ctx);
+  expect_shut_down_dispatch(mock_image_ctx);
   ASSERT_EQ(-EINVAL, when_close(mock_journal));
 }
 
@@ -830,7 +830,7 @@ TEST_F(TestMockJournal, StopError) {
   InSequence seq;
 
   MockObjectDispatch mock_object_dispatch;
-  expect_register_object_dispatch(mock_image_ctx, mock_object_dispatch);
+  expect_register_dispatch(mock_image_ctx, mock_object_dispatch);
 
   ::journal::MockJournaler mock_journaler;
   MockJournalOpenRequest mock_open_request;
@@ -852,7 +852,7 @@ TEST_F(TestMockJournal, StopError) {
 
   expect_stop_append(mock_journaler, -EINVAL);
   expect_shut_down_journaler(mock_journaler);
-  expect_shut_down_object_dispatch(mock_image_ctx);
+  expect_shut_down_dispatch(mock_image_ctx);
   ASSERT_EQ(-EINVAL, when_close(mock_journal));
 }
 
@@ -872,7 +872,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) {
 
   InSequence seq;
   MockObjectDispatch mock_object_dispatch;
-  expect_register_object_dispatch(mock_image_ctx, mock_object_dispatch);
+  expect_register_dispatch(mock_image_ctx, mock_object_dispatch);
 
   ::journal::MockJournaler mock_journaler;
   MockJournalOpenRequest mock_open_request;
@@ -941,7 +941,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPreFlushError) {
 
   expect_stop_append(mock_journaler, 0);
   expect_shut_down_journaler(mock_journaler);
-  expect_shut_down_object_dispatch(mock_image_ctx);
+  expect_shut_down_dispatch(mock_image_ctx);
   ASSERT_EQ(0, when_close(mock_journal));
 }
 
@@ -962,7 +962,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) {
   InSequence seq;
 
   MockObjectDispatch mock_object_dispatch;
-  expect_register_object_dispatch(mock_image_ctx, mock_object_dispatch);
+  expect_register_dispatch(mock_image_ctx, mock_object_dispatch);
 
   ::journal::MockJournaler mock_journaler;
   MockJournalOpenRequest mock_open_request;
@@ -1027,7 +1027,7 @@ TEST_F(TestMockJournal, ReplayOnDiskPostFlushError) {
 
   expect_stop_append(mock_journaler, 0);
   expect_shut_down_journaler(mock_journaler);
-  expect_shut_down_object_dispatch(mock_image_ctx);
+  expect_shut_down_dispatch(mock_image_ctx);
   ASSERT_EQ(0, when_close(mock_journal));
 }