]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: switch to new object dispatcher-based cache hooks
authorJason Dillaman <dillaman@redhat.com>
Fri, 16 Feb 2018 19:07:52 +0000 (14:07 -0500)
committerJason Dillaman <dillaman@redhat.com>
Wed, 7 Mar 2018 17:45:42 +0000 (12:45 -0500)
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
16 files changed:
src/librbd/exclusive_lock/PreReleaseRequest.cc
src/librbd/exclusive_lock/PreReleaseRequest.h
src/librbd/image/CloseRequest.cc
src/librbd/image/CloseRequest.h
src/librbd/image/OpenRequest.cc
src/librbd/image/OpenRequest.h
src/librbd/internal.cc
src/librbd/io/AioCompletion.h
src/librbd/io/ObjectRequest.cc
src/librbd/operation/ResizeRequest.cc
src/librbd/operation/SnapshotRollbackRequest.cc
src/test/librbd/exclusive_lock/test_mock_PreReleaseRequest.cc
src/test/librbd/io/test_mock_ImageRequest.cc
src/test/librbd/io/test_mock_ObjectRequest.cc
src/test/librbd/operation/test_mock_ResizeRequest.cc
src/test/librbd/operation/test_mock_SnapshotRollbackRequest.cc

index 504de0f0b93f9ae39bf1ec58c652d2ca80faf59e..e5ba42b057e43b09cb30d3dc94faa4fd83406bbd 100644 (file)
@@ -12,6 +12,7 @@
 #include "librbd/ObjectMap.h"
 #include "librbd/Utils.h"
 #include "librbd/io/ImageRequestWQ.h"
+#include "librbd/io/ObjectDispatcher.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
@@ -156,25 +157,19 @@ void PreReleaseRequest<I>::handle_wait_for_ops(int r) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 10) << dendl;
 
-  send_invalidate_cache(false);
+  send_invalidate_cache();
 }
 
 template <typename I>
-void PreReleaseRequest<I>::send_invalidate_cache(bool purge_on_error) {
-  if (m_image_ctx.object_cacher == nullptr) {
-    send_flush_notifies();
-    return;
-  }
-
+void PreReleaseRequest<I>::send_invalidate_cache() {
   CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 10) << "purge_on_error=" << purge_on_error << dendl;
+  ldout(cct, 10) << dendl;
 
   RWLock::RLocker owner_lock(m_image_ctx.owner_lock);
-  Context *ctx = create_async_context_callback(
-    m_image_ctx, create_context_callback<
+  Context *ctx = create_context_callback<
       PreReleaseRequest<I>,
-      &PreReleaseRequest<I>::handle_invalidate_cache>(this));
-  m_image_ctx.invalidate_cache(purge_on_error, ctx);
+      &PreReleaseRequest<I>::handle_invalidate_cache>(this);
+  m_image_ctx.io_object_dispatcher->invalidate_cache(ctx);
 }
 
 template <typename I>
@@ -182,15 +177,7 @@ void PreReleaseRequest<I>::handle_invalidate_cache(int r) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 10) << "r=" << r << dendl;
 
-  if (r == -EBLACKLISTED) {
-    lderr(cct) << "failed to invalidate cache because client is blacklisted"
-               << dendl;
-    if (!m_image_ctx.is_cache_empty()) {
-      // force purge the cache after after being blacklisted
-      send_invalidate_cache(true);
-      return;
-    }
-  } else if (r < 0 && r != -EBUSY) {
+  if (r < 0 && r != -EBLACKLISTED && r != -EBUSY) {
     lderr(cct) << "failed to invalidate cache: " << cpp_strerror(r)
                << dendl;
     m_image_ctx.io_work_queue->unblock_writes();
index 34ac07ab26c859353d8476dccc8d55cba4fb184e..e5b85a8813b21fa40f7866ef50df81980d26e8d4 100644 (file)
@@ -87,7 +87,7 @@ private:
   void send_wait_for_ops();
   void handle_wait_for_ops(int r);
 
-  void send_invalidate_cache(bool purge_on_error);
+  void send_invalidate_cache();
   void handle_invalidate_cache(int r);
 
   void send_flush_notifies();
index 0120c566629e979b3ca304f9292edf186122a267..cf6813dc06b330d424c9c83ab4f901b6fec7d489 100644 (file)
@@ -220,27 +220,6 @@ void CloseRequest<I>::handle_flush_readahead(int r) {
   CephContext *cct = m_image_ctx->cct;
   ldout(cct, 10) << this << " " << __func__ << ": r=" << r << dendl;
 
-  send_shut_down_cache();
-}
-
-template <typename I>
-void CloseRequest<I>::send_shut_down_cache() {
-  CephContext *cct = m_image_ctx->cct;
-  ldout(cct, 10) << this << " " << __func__ << dendl;
-
-  m_image_ctx->shut_down_cache(create_context_callback<
-    CloseRequest<I>, &CloseRequest<I>::handle_shut_down_cache>(this));
-}
-
-template <typename I>
-void CloseRequest<I>::handle_shut_down_cache(int r) {
-  CephContext *cct = m_image_ctx->cct;
-  ldout(cct, 10) << this << " " << __func__ << ": r=" << r << dendl;
-
-  save_result(r);
-  if (r < 0) {
-    lderr(cct) << "failed to shut down cache: " << cpp_strerror(r) << dendl;
-  }
   send_shut_down_object_dispatcher();
 }
 
index 73c344af4343abd725b8aa5d3d9beb5371a1f099..fd101beedb331c2fb679068d01da4f17a7334b81 100644 (file)
@@ -50,9 +50,6 @@ private:
    * FLUSH_READAHEAD
    *    |
    *    v
-   * SHUTDOWN_CACHE
-   *    |
-   *    v
    * SHUT_DOWN_OBJECT_DISPATCHER
    *    |
    *    v
@@ -100,9 +97,6 @@ private:
   void send_flush_readahead();
   void handle_flush_readahead(int r);
 
-  void send_shut_down_cache();
-  void handle_shut_down_cache(int r);
-
   void send_shut_down_object_dispatcher();
   void handle_shut_down_object_dispatcher(int r);
 
index 73a2273e8a03d5cb06cdace47b1e36552235ba75..009541e2f243558fedb34a27baf7e73c903c5bea 100644 (file)
@@ -7,6 +7,7 @@
 #include "cls/rbd/cls_rbd_client.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/Utils.h"
+#include "librbd/cache/ObjectCacherObjectDispatch.h"
 #include "librbd/image/CloseRequest.h"
 #include "librbd/image/RefreshRequest.h"
 #include "librbd/image/SetSnapRequest.h"
@@ -441,7 +442,28 @@ Context *OpenRequest<I>::handle_refresh(int *result) {
     return nullptr;
   }
 
-  m_image_ctx->init_cache();
+  return send_init_cache(result);
+}
+
+template <typename I>
+Context *OpenRequest<I>::send_init_cache(int *result) {
+  // cache is disabled or parent image context
+  if (!m_image_ctx->cache || m_image_ctx->child != nullptr) {
+    return send_register_watch(result);
+  }
+
+  CephContext *cct = m_image_ctx->cct;
+  ldout(cct, 10) << this << " " << __func__ << dendl;
+
+  auto cache = cache::ObjectCacherObjectDispatch<I>::create(m_image_ctx);
+  cache->init();
+
+  // readahead requires the cache
+  m_image_ctx->readahead.set_trigger_requests(
+    m_image_ctx->readahead_trigger_requests);
+  m_image_ctx->readahead.set_max_readahead_size(
+    m_image_ctx->readahead_max_bytes);
+
   return send_register_watch(result);
 }
 
index 45395f148d3bf02da483595d50396fa8489f7f01..aa8bb79d0a97848ff6c770d45fa98062d2fa60ab 100644 (file)
@@ -58,6 +58,9 @@ private:
    *            V2_GET_DATA_POOL --------------> REFRESH
    *                                                |
    *                                                v
+   *                                             INIT_CACHE
+   *                                                |
+   *                                                v
    *                                             REGISTER_WATCH (skip if
    *                                                |            read-only)
    *                                                v
@@ -111,6 +114,8 @@ private:
   void send_refresh();
   Context *handle_refresh(int *result);
 
+  Context *send_init_cache(int *result);
+
   Context *send_register_watch(int *result);
   Context *handle_register_watch(int *result);
 
index 6141f6e2b6034bbc132079404d2c38f70d524c6e..cd96a47ce8df723893a1a03fefb095079decad26 100644 (file)
 #include "common/errno.h"
 #include "common/Throttle.h"
 #include "common/event_socket.h"
-#include "cls/lock/cls_lock_client.h"
+#include "common/perf_counters.h"
+#include "osdc/Striper.h"
 #include "include/stringify.h"
 
+#include "cls/lock/cls_lock_client.h"
 #include "cls/rbd/cls_rbd.h"
 #include "cls/rbd/cls_rbd_types.h"
 #include "cls/rbd/cls_rbd_client.h"
@@ -40,6 +42,8 @@
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/ImageRequest.h"
 #include "librbd/io/ImageRequestWQ.h"
+#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatchSpec.h"
 #include "librbd/io/ObjectRequest.h"
 #include "librbd/io/ReadResult.h"
 #include "librbd/journal/Types.h"
@@ -2245,8 +2249,12 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
       return r;
     }
 
-    RWLock::RLocker owner_locker(ictx->owner_lock);
-    r = ictx->invalidate_cache(false);
+    C_SaferCond ctx;
+    {
+      RWLock::RLocker owner_locker(ictx->owner_lock);
+      ictx->io_object_dispatcher->invalidate_cache(&ctx);
+    }
+    r = ctx.wait();
     ictx->perfcounter->inc(l_librbd_invalidate_cache);
     return r;
   }
@@ -2299,10 +2307,18 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
     object_t oid;
     uint64_t offset;
     uint64_t length;
+
+    bufferlist read_data;
+    io::ExtentMap extent_map;
+
     C_RBD_Readahead(ImageCtx *ictx, object_t oid, uint64_t offset, uint64_t length)
-      : ictx(ictx), oid(oid), offset(offset), length(length) { }
+      : ictx(ictx), oid(oid), offset(offset), length(length) {
+      ictx->readahead.inc_pending();
+    }
+
     void finish(int r) override {
-      ldout(ictx->cct, 20) << "C_RBD_Readahead on " << oid << ": " << offset << "+" << length << dendl;
+      ldout(ictx->cct, 20) << "C_RBD_Readahead on " << oid << ": "
+                           << offset << "~" << length << dendl;
       ictx->readahead.dec_pending();
     }
   };
@@ -2316,7 +2332,7 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
         ++p) {
       total_bytes += p->second;
     }
-    
+
     ictx->md_lock.get_write();
     bool abort = ictx->readahead_disable_after_bytes != 0 &&
       ictx->total_bytes_read > ictx->readahead_disable_after_bytes;
@@ -2327,9 +2343,10 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
     ictx->total_bytes_read += total_bytes;
     ictx->snap_lock.get_read();
     uint64_t image_size = ictx->get_image_size(ictx->snap_id);
+    auto snap_id = ictx->snap_id;
     ictx->snap_lock.put_read();
     ictx->md_lock.put_write();
+
     pair<uint64_t, uint64_t> readahead_extent = ictx->readahead.update(image_extents, image_size);
     uint64_t readahead_offset = readahead_extent.first;
     uint64_t readahead_length = readahead_extent.second;
@@ -2343,11 +2360,13 @@ bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
        for (vector<ObjectExtent>::iterator q = p->second.begin(); q != p->second.end(); ++q) {
          ldout(ictx->cct, 20) << "(readahead) oid " << q->oid << " " << q->offset << "~" << q->length << dendl;
 
-         Context *req_comp = new C_RBD_Readahead(ictx, q->oid, q->offset, q->length);
-         ictx->readahead.inc_pending();
-         ictx->aio_read_from_cache(q->oid, q->objectno, NULL,
-                                   q->length, q->offset,
-                                   req_comp, 0, nullptr);
+         auto req_comp = new C_RBD_Readahead(ictx, q->oid, q->offset,
+                                              q->length);
+          auto req = io::ObjectDispatchSpec::create_read(
+            ictx, io::OBJECT_DISPATCH_LAYER_NONE, q->oid.name, q->objectno,
+            q->offset, q->length, snap_id, 0, {}, &req_comp->read_data,
+            &req_comp->extent_map, req_comp);
+          req->send(0);
        }
       }
       ictx->perfcounter->inc(l_librbd_readahead);
index e0b07cc6ef2879bf5807df737cee306d004fa0fd..7f3abb3947cd5197b7b5270045e1046ec35748f2 100644 (file)
@@ -90,10 +90,16 @@ struct AioCompletion {
   }
 
   template <typename T, void (T::*MF)(int) = &T::complete>
-  static AioCompletion *create_and_start(T *obj, ImageCtx *image_ctx,
-                                         aio_type_t type) {
+  static AioCompletion *create(T *obj, ImageCtx *image_ctx, aio_type_t type) {
     AioCompletion *comp = create<T, MF>(obj);
     comp->init_time(image_ctx, type);
+    return comp;
+  }
+
+  template <typename T, void (T::*MF)(int) = &T::complete>
+  static AioCompletion *create_and_start(T *obj, ImageCtx *image_ctx,
+                                         aio_type_t type) {
+    AioCompletion *comp = create<T, MF>(obj, image_ctx, type);
     comp->start_op();
     return comp;
   }
index d2eeb1801df3c443b5cba713641b95efb30f9402..b5537d75af7375455893a5b0b3fc25b91bf6859e 100644 (file)
@@ -298,10 +298,6 @@ void ObjectReadRequest<I>::handle_read_object(int r) {
 template <typename I>
 void ObjectReadRequest<I>::read_parent() {
   I *image_ctx = this->m_ictx;
-  if (m_cache_initiated) {
-    this->finish(-ENOENT);
-    return;
-  }
 
   uint64_t object_overlap = 0;
   Extents parent_extents;
index df9ed2b9b23f3822c48929b05e1409bd32daa38a..31827f562f51638b57026f5f988cb40f87e1ce78 100644 (file)
@@ -7,7 +7,10 @@
 #include "librbd/internal.h"
 #include "librbd/ObjectMap.h"
 #include "librbd/Utils.h"
+#include "librbd/io/AioCompletion.h"
+#include "librbd/io/ImageDispatchSpec.h"
 #include "librbd/io/ImageRequestWQ.h"
+#include "librbd/io/ObjectDispatcher.h"
 #include "librbd/operation/TrimRequest.h"
 #include "common/dout.h"
 #include "common/errno.h"
@@ -182,18 +185,19 @@ Context *ResizeRequest<I>::handle_trim_image(int *result) {
 template <typename I>
 void ResizeRequest<I>::send_flush_cache() {
   I &image_ctx = this->m_image_ctx;
-  if (image_ctx.object_cacher == nullptr) {
-    send_trim_image();
-    return;
-  }
 
   CephContext *cct = image_ctx.cct;
   ldout(cct, 5) << this << " " << __func__ << dendl;
 
   RWLock::RLocker owner_locker(image_ctx.owner_lock);
-  image_ctx.flush_cache(create_async_context_callback(
-    image_ctx, create_context_callback<
-      ResizeRequest<I>, &ResizeRequest<I>::handle_flush_cache>(this)));
+  auto ctx = create_context_callback<
+    ResizeRequest<I>, &ResizeRequest<I>::handle_flush_cache>(this);
+  auto aio_comp = io::AioCompletion::create(
+    ctx, util::get_image_ctx(&image_ctx), io::AIO_TYPE_FLUSH);
+  auto req = io::ImageDispatchSpec<I>::create_flush_request(
+    image_ctx, aio_comp, io::FLUSH_SOURCE_INTERNAL, {});
+  req->send();
+  delete req;
 }
 
 template <typename I>
@@ -220,9 +224,8 @@ void ResizeRequest<I>::send_invalidate_cache() {
   // need to invalidate since we're deleting objects, and
   // ObjectCacher doesn't track non-existent objects
   RWLock::RLocker owner_locker(image_ctx.owner_lock);
-  image_ctx.invalidate_cache(false, create_async_context_callback(
-    image_ctx, create_context_callback<
-      ResizeRequest<I>, &ResizeRequest<I>::handle_invalidate_cache>(this)));
+  image_ctx.io_object_dispatcher->invalidate_cache(create_context_callback<
+    ResizeRequest<I>, &ResizeRequest<I>::handle_invalidate_cache>(this));
 }
 
 template <typename I>
index f224b68fcc4f97e02e0433a0a4eb395ca585ef6a..7072e72ce599fe378b4e564500f8dd6bad06eab1 100644 (file)
@@ -10,6 +10,7 @@
 #include "librbd/ObjectMap.h"
 #include "librbd/Utils.h"
 #include "librbd/io/ImageRequestWQ.h"
+#include "librbd/io/ObjectDispatcher.h"
 #include "librbd/operation/ResizeRequest.h"
 #include "osdc/Striper.h"
 #include <boost/lambda/bind.hpp>
@@ -277,9 +278,6 @@ Context *SnapshotRollbackRequest<I>::send_invalidate_cache() {
   I &image_ctx = this->m_image_ctx;
 
   apply();
-  if (image_ctx.object_cacher == NULL) {
-    return this->create_context_finisher(0);
-  }
 
   CephContext *cct = image_ctx.cct;
   ldout(cct, 5) << this << " " << __func__ << dendl;
@@ -288,7 +286,7 @@ Context *SnapshotRollbackRequest<I>::send_invalidate_cache() {
   Context *ctx = create_context_callback<
     SnapshotRollbackRequest<I>,
     &SnapshotRollbackRequest<I>::handle_invalidate_cache>(this);
-  image_ctx.invalidate_cache(true, ctx);
+  image_ctx.io_object_dispatcher->invalidate_cache(ctx);
   return nullptr;
 }
 
index 44aa012568d12d935408ad6398146e2e806cb153..989e793fc734403eec44cd7f56922a2e75a905be 100644 (file)
@@ -6,6 +6,7 @@
 #include "test/librbd/mock/MockImageCtx.h"
 #include "test/librbd/mock/MockJournal.h"
 #include "test/librbd/mock/MockObjectMap.h"
+#include "test/librbd/mock/io/MockObjectDispatch.h"
 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
 #include "common/AsyncOpTracker.h"
 #include "librbd/exclusive_lock/PreReleaseRequest.h"
@@ -94,19 +95,10 @@ public:
                   .WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
   }
 
-  void expect_invalidate_cache(MockImageCtx &mock_image_ctx, bool purge,
+  void expect_invalidate_cache(MockImageCtx &mock_image_ctx,
                                int r) {
-    if (mock_image_ctx.object_cacher != nullptr) {
-      EXPECT_CALL(mock_image_ctx, invalidate_cache(purge, _))
-                    .WillOnce(WithArg<1>(CompleteContext(r, static_cast<ContextWQ*>(NULL)))); 
-    }
-  }
-
-  void expect_is_cache_empty(MockImageCtx &mock_image_ctx, bool empty) {
-    if (mock_image_ctx.object_cacher != nullptr) {
-      EXPECT_CALL(mock_image_ctx, is_cache_empty())
-        .WillOnce(Return(empty));
-    }
+    EXPECT_CALL(*mock_image_ctx.io_object_dispatcher, invalidate_cache(_))
+      .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
   }
 
   void expect_flush_notifies(MockImageCtx &mock_image_ctx) {
@@ -142,7 +134,8 @@ TEST_F(TestMockExclusiveLockPreReleaseRequest, Success) {
   expect_prepare_lock(mock_image_ctx);
   expect_cancel_op_requests(mock_image_ctx, 0);
   expect_block_writes(mock_image_ctx, 0);
-  expect_invalidate_cache(mock_image_ctx, false, 0);
+  expect_invalidate_cache(mock_image_ctx, 0);
+
   expect_flush_notifies(mock_image_ctx);
 
   MockJournal *mock_journal = new MockJournal();
@@ -176,7 +169,8 @@ TEST_F(TestMockExclusiveLockPreReleaseRequest, SuccessJournalDisabled) {
   InSequence seq;
   expect_prepare_lock(mock_image_ctx);
   expect_cancel_op_requests(mock_image_ctx, 0);
-  expect_invalidate_cache(mock_image_ctx, false, 0);
+  expect_invalidate_cache(mock_image_ctx, 0);
+
   expect_flush_notifies(mock_image_ctx);
 
   MockObjectMap *mock_object_map = new MockObjectMap();
@@ -205,7 +199,8 @@ TEST_F(TestMockExclusiveLockPreReleaseRequest, SuccessObjectMapDisabled) {
 
   InSequence seq;
   expect_cancel_op_requests(mock_image_ctx, 0);
-  expect_invalidate_cache(mock_image_ctx, false, 0);
+  expect_invalidate_cache(mock_image_ctx, 0);
+
   expect_flush_notifies(mock_image_ctx);
 
   C_SaferCond release_ctx;
@@ -229,10 +224,8 @@ TEST_F(TestMockExclusiveLockPreReleaseRequest, Blacklisted) {
   expect_prepare_lock(mock_image_ctx);
   expect_cancel_op_requests(mock_image_ctx, 0);
   expect_block_writes(mock_image_ctx, -EBLACKLISTED);
-  expect_invalidate_cache(mock_image_ctx, false, -EBLACKLISTED);
-  expect_is_cache_empty(mock_image_ctx, false);
-  expect_invalidate_cache(mock_image_ctx, true, -EBLACKLISTED);
-  expect_is_cache_empty(mock_image_ctx, true);
+  expect_invalidate_cache(mock_image_ctx, -EBLACKLISTED);
+
   expect_flush_notifies(mock_image_ctx);
 
   MockJournal *mock_journal = new MockJournal();
@@ -287,7 +280,8 @@ TEST_F(TestMockExclusiveLockPreReleaseRequest, UnlockError) {
   InSequence seq;
   expect_cancel_op_requests(mock_image_ctx, 0);
   expect_block_writes(mock_image_ctx, 0);
-  expect_invalidate_cache(mock_image_ctx, false, 0);
+  expect_invalidate_cache(mock_image_ctx, 0);
+
   expect_flush_notifies(mock_image_ctx);
 
   C_SaferCond ctx;
index 7dd0454f2e455955a6d607a68cc7c6d42c9850fc..09970e741422e4d48e87dc59fa9cc0dfda8908c0 100644 (file)
@@ -95,11 +95,6 @@ struct TestMockIoImageRequest : public TestMockFixture {
                 }));
   }
 
-  void expect_flush(MockImageCtx &mock_image_ctx, int r) {
-    EXPECT_CALL(mock_image_ctx, flush_cache(_))
-      .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
-  }
-
   void expect_flush_async_operations(MockImageCtx &mock_image_ctx, int r) {
     EXPECT_CALL(mock_image_ctx, flush_async_operations(_))
       .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
@@ -118,12 +113,7 @@ TEST_F(TestMockIoImageRequest, AioWriteJournalAppendDisabled) {
 
   InSequence seq;
   expect_is_journal_appending(mock_journal, false);
-  if (mock_image_ctx.image_ctx->cache) {
-    expect_write_to_cache(mock_image_ctx, ictx->get_object_name(0),
-                          0, 1, 0, 0);
-  } else {
-    expect_object_request_send(mock_image_ctx, 0);
-  }
+  expect_object_request_send(mock_image_ctx, 0);
 
   C_SaferCond aio_comp_ctx;
   AioCompletion *aio_comp = AioCompletion::create_and_start(
@@ -184,7 +174,6 @@ TEST_F(TestMockIoImageRequest, AioFlushJournalAppendDisabled) {
   expect_is_journal_appending(mock_journal, false);
   expect_flush_async_operations(mock_image_ctx, 0);
   expect_object_request_send(mock_image_ctx, 0);
-  expect_flush(mock_image_ctx, 0);
 
   C_SaferCond aio_comp_ctx;
   AioCompletion *aio_comp = AioCompletion::create_and_start(
@@ -210,13 +199,7 @@ TEST_F(TestMockIoImageRequest, AioWriteSameJournalAppendDisabled) {
 
   InSequence seq;
   expect_is_journal_appending(mock_journal, false);
-  if (mock_image_ctx.image_ctx->cache) {
-    expect_write_to_cache(mock_image_ctx, ictx->get_object_name(0),
-                          0, 1, 0, 0);
-  } else {
-    expect_object_request_send(mock_image_ctx, 0);
-  }
-
+  expect_object_request_send(mock_image_ctx, 0);
 
   C_SaferCond aio_comp_ctx;
   AioCompletion *aio_comp = AioCompletion::create_and_start(
index ad850ab9dd01dbc70a44f7e363d9ecaef8d99bc4..00d0e42e56ec5fe76252ffb0f1ef7dcc37bf802d 100644 (file)
@@ -180,22 +180,6 @@ struct TestMockIoObjectRequest : public TestMockFixture {
     }
   }
 
-  void expect_cache_read(MockTestImageCtx &mock_image_ctx,
-                         const std::string& oid, uint64_t object_no,
-                         uint64_t off, uint64_t len, const std::string& data,
-                         int r) {
-    bufferlist bl;
-    bl.append(data);
-
-    EXPECT_CALL(mock_image_ctx, aio_read_from_cache({oid}, object_no, _, len,
-                                                    off, _, _, _))
-      .WillOnce(WithArgs<2, 5>(Invoke([bl, r](bufferlist *out_bl,
-                                           Context *on_finish) {
-                                 out_bl->append(bl);
-                                 on_finish->complete(r);
-                               })));
-  }
-
   void expect_aio_read(MockImageRequest& mock_image_request,
                        Extents&& extents, int r) {
     EXPECT_CALL(mock_image_request, aio_read(_, extents))
@@ -408,60 +392,6 @@ TEST_F(TestMockIoObjectRequest, ReadError) {
   ASSERT_EQ(-EPERM, ctx.wait());
 }
 
-TEST_F(TestMockIoObjectRequest, CacheRead) {
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ictx->sparse_read_threshold_bytes = 8096;
-
-  MockTestImageCtx mock_image_ctx(*ictx);
-  MockObjectMap mock_object_map;
-  if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
-    mock_image_ctx.object_map = &mock_object_map;
-  }
-
-  expect_op_work_queue(mock_image_ctx);
-
-  InSequence seq;
-  expect_cache_read(mock_image_ctx, ictx->get_object_name(0), 0, 0, 4096,
-                    std::string(4096, '1'), 0);
-
-  bufferlist bl;
-  ExtentMap extent_map;
-  C_SaferCond ctx;
-  auto req = MockObjectReadRequest::create(
-    &mock_image_ctx, ictx->get_object_name(0), 0, 0, 4096, CEPH_NOSNAP, 0,
-    false, {}, &bl, &extent_map, &ctx);
-  req->send();
-  ASSERT_EQ(0, ctx.wait());
-}
-
-TEST_F(TestMockIoObjectRequest, CacheReadError) {
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(m_image_name, &ictx));
-  ictx->sparse_read_threshold_bytes = 8096;
-
-  MockTestImageCtx mock_image_ctx(*ictx);
-  MockObjectMap mock_object_map;
-  if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
-    mock_image_ctx.object_map = &mock_object_map;
-  }
-
-  expect_op_work_queue(mock_image_ctx);
-
-  InSequence seq;
-  expect_cache_read(mock_image_ctx, ictx->get_object_name(0), 0, 0, 4096,
-                    "", -EPERM);
-
-  bufferlist bl;
-  ExtentMap extent_map;
-  C_SaferCond ctx;
-  auto req = MockObjectReadRequest::create(
-    &mock_image_ctx, ictx->get_object_name(0), 0, 0, 4096, CEPH_NOSNAP, 0,
-    false, {}, &bl, &extent_map, &ctx);
-  req->send();
-  ASSERT_EQ(-EPERM, ctx.wait());
-}
-
 TEST_F(TestMockIoObjectRequest, ParentRead) {
   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
 
@@ -560,49 +490,6 @@ TEST_F(TestMockIoObjectRequest, ParentReadError) {
   ASSERT_EQ(-EPERM, ctx.wait());
 }
 
-TEST_F(TestMockIoObjectRequest, CacheInitiated) {
-  REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
-
-  librbd::Image image;
-  librbd::RBD rbd;
-  ASSERT_EQ(0, rbd.open(m_ioctx, image, m_image_name.c_str(), NULL));
-  ASSERT_EQ(0, image.snap_create("one"));
-  ASSERT_EQ(0, image.snap_protect("one"));
-  image.close();
-
-  std::string clone_name = get_temp_image_name();
-  int order = 0;
-  ASSERT_EQ(0, rbd.clone(m_ioctx, m_image_name.c_str(), "one", m_ioctx,
-                         clone_name.c_str(), RBD_FEATURE_LAYERING, &order));
-
-  librbd::ImageCtx *ictx;
-  ASSERT_EQ(0, open_image(clone_name, &ictx));
-  ictx->sparse_read_threshold_bytes = 8096;
-  ictx->clone_copy_on_read = false;
-
-  MockTestImageCtx mock_image_ctx(*ictx);
-  mock_image_ctx.parent = &mock_image_ctx;
-
-  MockObjectMap mock_object_map;
-  if (ictx->test_features(RBD_FEATURE_OBJECT_MAP)) {
-    mock_image_ctx.object_map = &mock_object_map;
-  }
-
-  InSequence seq;
-  expect_object_may_exist(mock_image_ctx, 0, true);
-  expect_get_read_flags(mock_image_ctx, CEPH_NOSNAP, 0);
-  expect_read(mock_image_ctx, ictx->get_object_name(0), 0, 4096, "", -ENOENT);
-
-  bufferlist bl;
-  ExtentMap extent_map;
-  C_SaferCond ctx;
-  auto req = MockObjectReadRequest::create(
-    &mock_image_ctx, ictx->get_object_name(0), 0, 0, 4096, CEPH_NOSNAP, 0, true,
-    {}, &bl, &extent_map, &ctx);
-  req->send();
-  ASSERT_EQ(-ENOENT, ctx.wait());
-}
-
 TEST_F(TestMockIoObjectRequest, CopyOnRead) {
   REQUIRE_FEATURE(RBD_FEATURE_LAYERING);
 
index 7b70a50e8f48f9a314cb6380094fd6e89a62a2f7..85a22610e2bb482206ab352fdeb9fdc0da7eb64f 100644 (file)
@@ -4,16 +4,53 @@
 #include "test/librbd/test_mock_fixture.h"
 #include "test/librbd/test_support.h"
 #include "test/librbd/mock/MockImageCtx.h"
+#include "test/librbd/mock/io/MockObjectDispatch.h"
 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
 #include "common/bit_vector.hpp"
 #include "librbd/internal.h"
 #include "librbd/ObjectMap.h"
+#include "librbd/io/ImageDispatchSpec.h"
 #include "librbd/operation/ResizeRequest.h"
 #include "librbd/operation/TrimRequest.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
 namespace librbd {
+
+namespace util {
+
+inline ImageCtx* get_image_ctx(MockImageCtx* image_ctx) {
+  return image_ctx->image_ctx;
+}
+
+} // namespace util
+
+namespace io {
+
+template <>
+struct ImageDispatchSpec<MockImageCtx> {
+  static ImageDispatchSpec* s_instance;
+  AioCompletion *aio_comp = nullptr;
+
+  static ImageDispatchSpec* create_flush_request(
+      MockImageCtx &image_ctx, AioCompletion *aio_comp,
+      FlushSource flush_source, const ZTracer::Trace &parent_trace) {
+    assert(s_instance != nullptr);
+    s_instance->aio_comp = aio_comp;
+    return s_instance;
+  }
+
+  MOCK_CONST_METHOD0(send, void());
+
+  ImageDispatchSpec() {
+    s_instance = this;
+  }
+};
+
+ImageDispatchSpec<MockImageCtx>* ImageDispatchSpec<MockImageCtx>::s_instance = nullptr;
+
+} // namespace io
+
 namespace operation {
 
 template <>
@@ -50,6 +87,7 @@ namespace operation {
 
 using ::testing::_;
 using ::testing::DoAll;
+using ::testing::Invoke;
 using ::testing::InSequence;
 using ::testing::Return;
 using ::testing::StrEq;
@@ -59,6 +97,7 @@ class TestMockOperationResizeRequest : public TestMockFixture {
 public:
   typedef ResizeRequest<MockImageCtx> MockResizeRequest;
   typedef TrimRequest<MockImageCtx> MockTrimRequest;
+  typedef io::ImageDispatchSpec<MockImageCtx> MockIoImageDispatchSpec;
 
   void expect_block_writes(MockImageCtx &mock_image_ctx, int r) {
     EXPECT_CALL(*mock_image_ctx.io_work_queue, block_writes(_))
@@ -112,21 +151,24 @@ public:
                   .WillOnce(FinishRequest(&mock_trim_request, r, &mock_image_ctx));
   }
 
-  void expect_flush_cache(MockImageCtx &mock_image_ctx, int r) {
-    if (!mock_image_ctx.image_ctx->cache) {
-      return;
-    }
-    EXPECT_CALL(mock_image_ctx, flush_cache(_))
-                  .WillOnce(CompleteContext(r, static_cast<ContextWQ*>(NULL)));
-    expect_op_work_queue(mock_image_ctx);
+  void expect_flush_cache(MockImageCtx &mock_image_ctx,
+                          MockIoImageDispatchSpec& mock_io_image_dispatch_spec,
+                          int r) {
+    EXPECT_CALL(mock_io_image_dispatch_spec, send())
+      .WillOnce(Invoke([&mock_image_ctx, &mock_io_image_dispatch_spec, r]() {
+                  auto aio_comp = mock_io_image_dispatch_spec.s_instance->aio_comp;
+                  auto ctx = new FunctionContext([aio_comp](int r) {
+                    aio_comp->get();
+                    aio_comp->fail(r);
+                  });
+                  mock_image_ctx.image_ctx->op_work_queue->queue(ctx, r);
+                }));
   }
 
-  void expect_invalidate_cache(MockImageCtx &mock_image_ctx, int r) {
-    if (!mock_image_ctx.image_ctx->cache) {
-      return;
-    }
-    EXPECT_CALL(mock_image_ctx, invalidate_cache(false, _))
-                   .WillOnce(WithArg<1>(CompleteContext(r, static_cast<ContextWQ*>(NULL))));
+  void expect_invalidate_cache(MockImageCtx &mock_image_ctx,
+                               int r) {
+    EXPECT_CALL(*mock_image_ctx.io_object_dispatcher, invalidate_cache(_))
+                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
     expect_op_work_queue(mock_image_ctx);
   }
 
@@ -211,7 +253,8 @@ TEST_F(TestMockOperationResizeRequest, ShrinkSuccess) {
   expect_unblock_writes(mock_image_ctx);
 
   MockTrimRequest mock_trim_request;
-  expect_flush_cache(mock_image_ctx, 0);
+  auto mock_io_image_dispatch_spec = new MockIoImageDispatchSpec();
+  expect_flush_cache(mock_image_ctx, *mock_io_image_dispatch_spec, 0);
   expect_invalidate_cache(mock_image_ctx, 0);
   expect_trim(mock_image_ctx, mock_trim_request, 0);
   expect_block_writes(mock_image_ctx, 0);
@@ -273,7 +316,8 @@ TEST_F(TestMockOperationResizeRequest, TrimError) {
   expect_unblock_writes(mock_image_ctx);
 
   MockTrimRequest mock_trim_request;
-  expect_flush_cache(mock_image_ctx, 0);
+  auto mock_io_image_dispatch_spec = new MockIoImageDispatchSpec();
+  expect_flush_cache(mock_image_ctx, *mock_io_image_dispatch_spec, 0);
   expect_invalidate_cache(mock_image_ctx, -EBUSY);
   expect_trim(mock_image_ctx, mock_trim_request, -EINVAL);
   expect_commit_op_event(mock_image_ctx, -EINVAL);
@@ -298,7 +342,8 @@ TEST_F(TestMockOperationResizeRequest, FlushCacheError) {
   expect_unblock_writes(mock_image_ctx);
 
   MockTrimRequest mock_trim_request;
-  expect_flush_cache(mock_image_ctx, -EINVAL);
+  auto mock_io_image_dispatch_spec = new MockIoImageDispatchSpec();
+  expect_flush_cache(mock_image_ctx, *mock_io_image_dispatch_spec, -EINVAL);
   expect_commit_op_event(mock_image_ctx, -EINVAL);
   ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, true, 0, false));
 }
@@ -321,7 +366,8 @@ TEST_F(TestMockOperationResizeRequest, InvalidateCacheError) {
   expect_unblock_writes(mock_image_ctx);
 
   MockTrimRequest mock_trim_request;
-  expect_flush_cache(mock_image_ctx, 0);
+  auto mock_io_image_dispatch_spec = new MockIoImageDispatchSpec();
+  expect_flush_cache(mock_image_ctx, *mock_io_image_dispatch_spec, 0);
   expect_invalidate_cache(mock_image_ctx, -EINVAL);
   expect_commit_op_event(mock_image_ctx, -EINVAL);
   ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, true, 0, false));
index 97cc5f153dc2aef6e59776ac1f6a7735a8906eb5..e41b795a1a32f87a3f77281c8e826265c61281ed 100644 (file)
@@ -4,6 +4,7 @@
 #include "test/librbd/test_mock_fixture.h"
 #include "test/librbd/test_support.h"
 #include "test/librbd/mock/MockImageCtx.h"
+#include "test/librbd/mock/io/MockObjectDispatch.h"
 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
 #include "include/stringify.h"
 #include "common/bit_vector.hpp"
@@ -159,11 +160,10 @@ public:
     }
   }
 
-  void expect_invalidate_cache(MockOperationImageCtx &mock_image_ctx, int r) {
-    if (mock_image_ctx.object_cacher != nullptr) {
-      EXPECT_CALL(mock_image_ctx, invalidate_cache(true, _))
-                    .WillOnce(WithArg<1>(CompleteContext(r, static_cast<ContextWQ*>(NULL))));
-    }
+  void expect_invalidate_cache(MockOperationImageCtx &mock_image_ctx,
+                               int r) {
+    EXPECT_CALL(*mock_image_ctx.io_object_dispatcher, invalidate_cache(_))
+                   .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
   }
 
   int when_snap_rollback(MockOperationImageCtx &mock_image_ctx,