]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: make read_parent reusable
authorMykola Golub <mgolub@suse.com>
Mon, 20 Jul 2020 09:53:57 +0000 (10:53 +0100)
committerMykola Golub <mgolub@suse.com>
Thu, 23 Jul 2020 14:54:18 +0000 (15:54 +0100)
Signed-off-by: Mykola Golub <mgolub@suse.com>
src/librbd/io/ImageRequest.h
src/librbd/io/ObjectRequest.cc
src/librbd/io/Utils.cc
src/librbd/io/Utils.h
src/test/librbd/io/test_mock_ObjectRequest.cc

index ca2a74e35ee207221b0628091b8b46160341f3bf..36ba9624b24064927ec2dfa22436f2dd5fccd2b2 100644 (file)
@@ -79,7 +79,7 @@ protected:
               const ZTracer::Trace &parent_trace)
     : m_image_ctx(image_ctx), m_aio_comp(aio_comp),
       m_image_extents(std::move(image_extents)),
-      m_trace(util::create_trace(image_ctx, trace_name, parent_trace)) {
+      m_trace(librbd::util::create_trace(image_ctx, trace_name, parent_trace)) {
     m_trace.event("start");
   }
 
index 1b2cf9119c62e2287a0a118a9df664a149626d69..1bae9099d24cea62a435de7ae2d3bf2a234564d0 100644 (file)
@@ -19,8 +19,6 @@
 #include "librbd/asio/Utils.h"
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/CopyupRequest.h"
-#include "librbd/io/ImageRequest.h"
-#include "librbd/io/ReadResult.h"
 #include "librbd/io/Utils.h"
 
 #include <boost/optional.hpp>
@@ -36,6 +34,8 @@ namespace librbd {
 namespace io {
 
 using librbd::util::data_object_name;
+using librbd::util::create_context_callback;
+using librbd::util::create_trace;
 
 namespace {
 
@@ -104,7 +104,7 @@ ObjectRequest<I>::ObjectRequest(
     const ZTracer::Trace &trace, Context *completion)
   : m_ictx(ictx), m_object_no(objectno), m_object_off(off),
     m_object_len(len), m_snap_id(snap_id), m_completion(completion),
-    m_trace(librbd::util::create_trace(*ictx, "", trace)) {
+    m_trace(create_trace(*ictx, "", trace)) {
   ceph_assert(m_ictx->data_ctx.is_valid());
   if (m_trace.valid()) {
     m_trace.copy_name(trace_name + std::string(" ") +
@@ -251,38 +251,14 @@ void ObjectReadRequest<I>::handle_read_object(int r) {
 template <typename I>
 void ObjectReadRequest<I>::read_parent() {
   I *image_ctx = this->m_ictx;
-
-  std::shared_lock image_locker{image_ctx->image_lock};
-
-  // calculate reverse mapping onto the image
-  Extents parent_extents;
-  Striper::extent_to_file(image_ctx->cct, &image_ctx->layout,
-                          this->m_object_no, this->m_object_off,
-                          this->m_object_len, parent_extents);
-
-  uint64_t parent_overlap = 0;
-  uint64_t object_overlap = 0;
-  int r = image_ctx->get_parent_overlap(this->m_snap_id, &parent_overlap);
-  if (r == 0) {
-    object_overlap = image_ctx->prune_parent_extents(parent_extents,
-                                                     parent_overlap);
-  }
-
-  if (object_overlap == 0) {
-    image_locker.unlock();
-
-    this->finish(-ENOENT);
-    return;
-  }
-
   ldout(image_ctx->cct, 20) << dendl;
 
-  auto parent_completion = AioCompletion::create_and_start<
-    ObjectReadRequest<I>, &ObjectReadRequest<I>::handle_read_parent>(
-      this, librbd::util::get_image_ctx(image_ctx->parent), AIO_TYPE_READ);
-  ImageRequest<I>::aio_read(image_ctx->parent, parent_completion,
-                            std::move(parent_extents), ReadResult{m_read_data},
-                            0, this->m_trace);
+  auto ctx = create_context_callback<
+    ObjectReadRequest<I>, &ObjectReadRequest<I>::handle_read_parent>(this);
+
+  io::util::read_parent<I>(image_ctx, this->m_object_no, this->m_object_off,
+                           this->m_object_len, this->m_snap_id, this->m_trace,
+                           m_read_data, ctx);
 }
 
 template <typename I>
index d50ac98d1987109334ea58a258ab279e58ea77a3..78d8a5a83fa889e9892114b53d2c7146c38a803b 100644 (file)
@@ -2,10 +2,18 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "librbd/io/Utils.h"
+#include "common/dout.h"
 #include "include/buffer.h"
 #include "include/rados/librados.hpp"
 #include "include/neorados/RADOS.hpp"
+#include "librbd/io/AioCompletion.h"
+#include "librbd/io/ImageRequest.h"
 #include "osd/osd_types.h"
+#include "osdc/Striper.h"
+
+#define dout_subsys ceph_subsys_rbd
+#undef dout_prefix
+#define dout_prefix *_dout << "librbd::io::util: " << __func__ << ": "
 
 namespace librbd {
 namespace io {
@@ -71,7 +79,52 @@ bool assemble_write_same_extent(
   return false;
 }
 
+template <typename I>
+void read_parent(I *image_ctx, uint64_t object_no, uint64_t off,
+                 uint64_t len, librados::snap_t snap_id,
+                 const ZTracer::Trace &trace, ceph::bufferlist* data,
+                 Context* on_finish) {
+
+  auto cct = image_ctx->cct;
+
+  std::shared_lock image_locker{image_ctx->image_lock};
+
+  // calculate reverse mapping onto the image
+  Extents parent_extents;
+  Striper::extent_to_file(cct, &image_ctx->layout, object_no, off, len,
+                          parent_extents);
+
+  uint64_t parent_overlap = 0;
+  uint64_t object_overlap = 0;
+  int r = image_ctx->get_parent_overlap(snap_id, &parent_overlap);
+  if (r == 0) {
+    object_overlap = image_ctx->prune_parent_extents(parent_extents,
+                                                     parent_overlap);
+  }
+
+  if (object_overlap == 0) {
+    image_locker.unlock();
+
+    on_finish->complete(-ENOENT);
+    return;
+  }
+
+  ldout(cct, 20) << dendl;
+
+  auto comp = AioCompletion::create_and_start(on_finish, image_ctx->parent,
+                                              AIO_TYPE_READ);
+  ldout(cct, 20) << "completion " << comp << ", extents " << parent_extents
+                 << dendl;
+
+  ImageRequest<I>::aio_read(image_ctx->parent, comp, std::move(parent_extents),
+                            ReadResult{data}, 0, trace);
+}
+
 } // namespace util
 } // namespace io
 } // namespace librbd
 
+template void librbd::io::util::read_parent(
+    librbd::ImageCtx *image_ctx, uint64_t object_no, uint64_t off, uint64_t len,
+    librados::snap_t snap_id, const ZTracer::Trace &trace,
+    ceph::bufferlist* data, Context* on_finish);
index cadc22840bf9cadb82a973d351c5255a9ab357e1..295bf0469cac851c456de4dbf9f907cb80f61101 100644 (file)
@@ -6,6 +6,8 @@
 
 #include "include/int_types.h"
 #include "include/buffer_fwd.h"
+#include "include/rados/rados_types.hpp"
+#include "common/zipkin_trace.h"
 #include "librbd/io/Types.h"
 #include <map>
 
@@ -14,6 +16,9 @@ class ObjectExtent;
 namespace neorados { struct Op; }
 
 namespace librbd {
+
+struct ImageCtx;
+
 namespace io {
 namespace util {
 
@@ -24,6 +29,12 @@ bool assemble_write_same_extent(const LightweightObjectExtent &object_extent,
                                 ceph::bufferlist *ws_data,
                                 bool force_write);
 
+template <typename ImageCtxT = librbd::ImageCtx>
+void read_parent(ImageCtxT *image_ctx, uint64_t object_no, uint64_t off,
+                 uint64_t len, librados::snap_t snap_id,
+                 const ZTracer::Trace &trace, ceph::bufferlist* data,
+                 Context* on_finish);
+
 } // namespace util
 } // namespace io
 } // namespace librbd
index 841b3c40d3312df8318a388104168c64ac151c4e..a5ab6dba533db2a79648ff5e435194d57cee8480 100644 (file)
@@ -10,8 +10,8 @@
 #include "test/librados_test_stub/MockTestMemRadosClient.h"
 #include "include/rbd/librbd.hpp"
 #include "librbd/io/CopyupRequest.h"
-#include "librbd/io/ImageRequest.h"
 #include "librbd/io/ObjectRequest.h"
+#include "librbd/io/Utils.h"
 
 namespace librbd {
 namespace {
@@ -53,24 +53,38 @@ struct CopyupRequest<librbd::MockTestImageCtx> : public CopyupRequest<librbd::Mo
   }
 };
 
-template <>
-struct ImageRequest<librbd::MockTestImageCtx> {
-  static ImageRequest *s_instance;
-  static void aio_read(librbd::MockImageCtx *ictx, AioCompletion *c,
-                       Extents &&image_extents, ReadResult &&read_result,
-                       int op_flags, const ZTracer::Trace &parent_trace) {
-    s_instance->aio_read(c, image_extents);
-  }
+CopyupRequest<librbd::MockTestImageCtx>* CopyupRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
 
-  MOCK_METHOD2(aio_read, void(AioCompletion *, const Extents&));
+namespace util {
+
+namespace {
 
-  ImageRequest() {
+struct Mock {
+  static Mock* s_instance;
+
+  Mock() {
     s_instance = this;
   }
+
+  MOCK_METHOD8(read_parent,
+               void(librbd::MockTestImageCtx *, uint64_t, uint64_t, uint64_t,
+                    librados::snap_t, const ZTracer::Trace &, ceph::bufferlist*,
+                    Context*));
 };
 
-CopyupRequest<librbd::MockTestImageCtx>* CopyupRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
-ImageRequest<librbd::MockTestImageCtx>* ImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
+Mock *Mock::s_instance = nullptr;
+
+} // anonymous namespace
+
+template<> void read_parent(
+    librbd::MockTestImageCtx *image_ctx, uint64_t object_no, uint64_t off,
+    uint64_t len, librados::snap_t snap_id, const ZTracer::Trace &trace,
+    ceph::bufferlist* data, Context* on_finish) {
+  Mock::s_instance->read_parent(image_ctx, object_no, off, len, snap_id, trace,
+                                data, on_finish);
+}
+
+} // namespace util
 
 } // namespace io
 } // namespace librbd
@@ -97,7 +111,7 @@ struct TestMockIoObjectRequest : public TestMockFixture {
   typedef ObjectCompareAndWriteRequest<librbd::MockTestImageCtx> MockObjectCompareAndWriteRequest;
   typedef AbstractObjectWriteRequest<librbd::MockTestImageCtx> MockAbstractObjectWriteRequest;
   typedef CopyupRequest<librbd::MockTestImageCtx> MockCopyupRequest;
-  typedef ImageRequest<librbd::MockTestImageCtx> MockImageRequest;
+  typedef util::Mock MockUtils;
 
   void expect_object_may_exist(MockTestImageCtx &mock_image_ctx,
                                uint64_t object_no, bool exists) {
@@ -182,14 +196,12 @@ struct TestMockIoObjectRequest : public TestMockFixture {
     }
   }
 
-  void expect_aio_read(MockTestImageCtx &mock_image_ctx,
-                       MockImageRequest& mock_image_request,
-                       Extents&& extents, int r) {
-    EXPECT_CALL(mock_image_request, aio_read(_, extents))
-      .WillOnce(WithArg<0>(Invoke([&mock_image_ctx, r](AioCompletion* aio_comp) {
-                             aio_comp->set_request_count(1);
-                             mock_image_ctx.image_ctx->op_work_queue->queue(new C_AioRequest(aio_comp), r);
-                           })));
+  void expect_read_parent(MockUtils &mock_utils, uint64_t object_no,
+                          uint64_t off, uint64_t len, librados::snap_t snap_id,
+                          int r) {
+    EXPECT_CALL(mock_utils,
+                read_parent(_, object_no, off, len, snap_id, _, _, _))
+      .WillOnce(WithArg<7>(CompleteContext(r, static_cast<asio::ContextWQ*>(nullptr))));
   }
 
   void expect_copyup(MockCopyupRequest& mock_copyup_request, int r) {
@@ -438,10 +450,8 @@ TEST_F(TestMockIoObjectRequest, ParentRead) {
   expect_get_read_flags(mock_image_ctx, CEPH_NOSNAP, 0);
   expect_read(mock_image_ctx, ictx->get_object_name(0), 0, 4096, "", -ENOENT);
 
-  MockImageRequest mock_image_request;
-  expect_get_parent_overlap(mock_image_ctx, CEPH_NOSNAP, 4096, 0);
-  expect_prune_parent_extents(mock_image_ctx, {{0, 4096}}, 4096, 4096);
-  expect_aio_read(mock_image_ctx, mock_image_request, {{0, 4096}}, 0);
+  MockUtils mock_utils;
+  expect_read_parent(mock_utils, 0, 0, 4096, CEPH_NOSNAP, 0);
 
   bufferlist bl;
   Extents extent_map;
@@ -485,10 +495,8 @@ TEST_F(TestMockIoObjectRequest, ParentReadError) {
   expect_get_read_flags(mock_image_ctx, CEPH_NOSNAP, 0);
   expect_read(mock_image_ctx, ictx->get_object_name(0), 0, 4096, "", -ENOENT);
 
-  MockImageRequest mock_image_request;
-  expect_get_parent_overlap(mock_image_ctx, CEPH_NOSNAP, 4096, 0);
-  expect_prune_parent_extents(mock_image_ctx, {{0, 4096}}, 4096, 4096);
-  expect_aio_read(mock_image_ctx, mock_image_request, {{0, 4096}}, -EPERM);
+  MockUtils mock_utils;
+  expect_read_parent(mock_utils, 0, 0, 4096, CEPH_NOSNAP, -EPERM);
 
   bufferlist bl;
   Extents extent_map;
@@ -532,10 +540,8 @@ TEST_F(TestMockIoObjectRequest, CopyOnRead) {
   expect_get_read_flags(mock_image_ctx, CEPH_NOSNAP, 0);
   expect_read(mock_image_ctx, ictx->get_object_name(0), 0, 4096, "", -ENOENT);
 
-  MockImageRequest mock_image_request;
-  expect_get_parent_overlap(mock_image_ctx, CEPH_NOSNAP, 4096, 0);
-  expect_prune_parent_extents(mock_image_ctx, {{0, 4096}}, 4096, 4096);
-  expect_aio_read(mock_image_ctx, mock_image_request, {{0, 4096}}, 0);
+  MockUtils mock_utils;
+  expect_read_parent(mock_utils, 0, 0, 4096, CEPH_NOSNAP, 0);
 
   MockCopyupRequest mock_copyup_request;
   expect_get_parent_overlap(mock_image_ctx, CEPH_NOSNAP, 4096, 0);