]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add crypto image dispatch layer 37935/head
authorOr Ozeri <oro@il.ibm.com>
Mon, 2 Nov 2020 14:41:53 +0000 (16:41 +0200)
committerOr Ozeri <oro@il.ibm.com>
Tue, 17 Nov 2020 06:39:55 +0000 (08:39 +0200)
This commit adds a crypto image dispatch layer, in addition to the existing crypto object dispatch layer.
The single purpose of this layer is to translate logical image offset to "on-disk" offsets,
given a crypto header which occupies the beginning of the image data.
This calculation is done via a new remap_extents api,
which is used in to wrap existing Striper translations between object and image extents.

Signed-off-by: Or Ozeri <oro@il.ibm.com>
23 files changed:
src/librbd/CMakeLists.txt
src/librbd/cache/ObjectCacherWriteback.cc
src/librbd/crypto/CryptoImageDispatch.cc [new file with mode: 0644]
src/librbd/crypto/CryptoImageDispatch.h [new file with mode: 0644]
src/librbd/crypto/CryptoObjectDispatch.cc
src/librbd/deep_copy/ObjectCopyRequest.cc
src/librbd/io/CopyupRequest.cc
src/librbd/io/ImageDispatchInterface.h
src/librbd/io/ImageDispatcher.cc
src/librbd/io/ImageDispatcher.h
src/librbd/io/ImageDispatcherInterface.h
src/librbd/io/ImageRequest.cc
src/librbd/io/ObjectRequest.cc
src/librbd/io/Types.h
src/librbd/io/Utils.cc
src/librbd/io/Utils.h
src/librbd/journal/ObjectDispatch.cc
src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc
src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc
src/test/librbd/io/test_mock_CopyupRequest.cc
src/test/librbd/io/test_mock_ImageRequest.cc
src/test/librbd/io/test_mock_ObjectRequest.cc
src/test/librbd/mock/io/MockImageDispatcher.h

index ac4b196def1eb4229d2864cd95bee15a6ef83620..7fbadfd49baa2971082d2ae275c97e775b266329 100644 (file)
@@ -56,6 +56,7 @@ set(librbd_internal_srcs
   cache/WriteAroundObjectDispatch.cc
   crypto/BlockCrypto.cc
   crypto/CryptoContextPool.cc
+  crypto/CryptoImageDispatch.cc
   crypto/CryptoObjectDispatch.cc
   crypto/openssl/DataCryptor.cc
   deep_copy/ImageCopyRequest.cc
index 50655b6a111bd0fe7544ff639286be2333b5c150..9f3d5c8953e21459f503c7861d7876868c30ef07 100644 (file)
@@ -24,6 +24,7 @@
 #include "librbd/io/ObjectDispatchSpec.h"
 #include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/io/ReadResult.h"
+#include "librbd/io/Utils.h"
 
 #include "include/ceph_assert.h"
 
@@ -167,8 +168,8 @@ bool ObjectCacherWriteback::may_copy_on_write(const object_t& oid,
 
   // reverse map this object extent onto the parent
   vector<pair<uint64_t,uint64_t> > objectx;
-  Striper::extent_to_file(m_ictx->cct, &m_ictx->layout,
-                          object_no, 0, m_ictx->layout.object_size, objectx);
+  io::util::extent_to_file(
+          m_ictx, object_no, 0, m_ictx->layout.object_size, objectx);
   uint64_t object_overlap = m_ictx->prune_parent_extents(objectx, overlap);
   bool may = object_overlap > 0;
   ldout(m_ictx->cct, 10) << "may_copy_on_write " << oid << " " << read_off
@@ -240,8 +241,7 @@ void ObjectCacherWriteback::overwrite_extent(const object_t& oid, uint64_t off,
   ceph_assert(original_journal_tid != 0 && m_ictx->journal != NULL);
 
   Extents file_extents;
-  Striper::extent_to_file(m_ictx->cct, &m_ictx->layout, object_no, off,
-                          len, file_extents);
+  io::util::extent_to_file(m_ictx, object_no, off, len, file_extents);
   for (Extents::iterator it = file_extents.begin();
        it != file_extents.end(); ++it) {
     if (new_journal_tid != 0) {
diff --git a/src/librbd/crypto/CryptoImageDispatch.cc b/src/librbd/crypto/CryptoImageDispatch.cc
new file mode 100644 (file)
index 0000000..84c9a59
--- /dev/null
@@ -0,0 +1,28 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/crypto/CryptoImageDispatch.h"
+
+namespace librbd {
+namespace crypto {
+
+CryptoImageDispatch::CryptoImageDispatch(
+        uint64_t data_offset) : m_data_offset(data_offset) {
+}
+
+
+void CryptoImageDispatch::remap_extents(
+        io::Extents&& image_extents, io::ImageExtentsMapType type) {
+  if (type == io::IMAGE_EXTENTS_MAP_TYPE_LOGICAL_TO_PHYSICAL) {
+    for (auto& extent: image_extents) {
+      extent.first += m_data_offset;
+    }
+  } else if (type == io::IMAGE_EXTENTS_MAP_TYPE_PHYSICAL_TO_LOGICAL) {
+    for (auto& extent: image_extents) {
+      extent.first -= m_data_offset;
+    }
+  }
+}
+
+} // namespace crypto
+} // namespace librbd
diff --git a/src/librbd/crypto/CryptoImageDispatch.h b/src/librbd/crypto/CryptoImageDispatch.h
new file mode 100644 (file)
index 0000000..afc3c84
--- /dev/null
@@ -0,0 +1,104 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_CRYPTO_CRYPTO_IMAGE_DISPATCH_H
+#define CEPH_LIBRBD_CRYPTO_CRYPTO_IMAGE_DISPATCH_H
+
+#include "librbd/io/ImageDispatchInterface.h"
+
+namespace librbd {
+namespace crypto {
+
+class CryptoImageDispatch : public io::ImageDispatchInterface {
+public:
+  CryptoImageDispatch(uint64_t data_offset);
+
+  io::ImageDispatchLayer get_dispatch_layer() const override {
+    return io::IMAGE_DISPATCH_LAYER_CRYPTO;
+  }
+
+  void shut_down(Context* on_finish) override {
+    on_finish->complete(0);
+  }
+
+  bool read(
+      io::AioCompletion* aio_comp, io::Extents &&image_extents,
+      io::ReadResult &&read_result, IOContext io_context, int op_flags,
+      int read_flags, const ZTracer::Trace &parent_trace, uint64_t tid,
+      std::atomic<uint32_t>* image_dispatch_flags,
+      io::DispatchResult* dispatch_result, Context** on_finish,
+      Context* on_dispatched) override {
+    return false;
+  }
+
+  bool write(
+      io::AioCompletion* aio_comp, io::Extents &&image_extents,
+      bufferlist &&bl, IOContext io_context, int op_flags,
+      const ZTracer::Trace &parent_trace, uint64_t tid,
+      std::atomic<uint32_t>* image_dispatch_flags,
+      io::DispatchResult* dispatch_result, Context** on_finish,
+      Context* on_dispatched) override {
+    return false;
+  }
+
+  bool discard(
+      io::AioCompletion* aio_comp, io::Extents &&image_extents,
+      uint32_t discard_granularity_bytes, IOContext io_context,
+      const ZTracer::Trace &parent_trace, uint64_t tid,
+      std::atomic<uint32_t>* image_dispatch_flags,
+      io::DispatchResult* dispatch_result, Context** on_finish,
+      Context* on_dispatched) override {
+    return false;
+  }
+
+  bool write_same(
+      io::AioCompletion* aio_comp, io::Extents &&image_extents,
+      bufferlist &&bl, IOContext io_context, int op_flags,
+      const ZTracer::Trace &parent_trace, uint64_t tid,
+      std::atomic<uint32_t>* image_dispatch_flags,
+      io::DispatchResult* dispatch_result, Context** on_finish,
+      Context* on_dispatched) override {
+    return false;
+  }
+
+  bool compare_and_write(
+      io::AioCompletion* aio_comp, io::Extents &&image_extents,
+      bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset,
+      IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace,
+      uint64_t tid, std::atomic<uint32_t>* image_dispatch_flags,
+      io::DispatchResult* dispatch_result, Context** on_finish,
+      Context* on_dispatched) override {
+    return false;
+  }
+
+  bool flush(
+      io::AioCompletion* aio_comp, io::FlushSource flush_source,
+      const ZTracer::Trace &parent_trace, uint64_t tid,
+      std::atomic<uint32_t>* image_dispatch_flags,
+      io::DispatchResult* dispatch_result, Context** on_finish,
+      Context* on_dispatched) override {
+    return false;
+  }
+
+  bool list_snaps(
+      io::AioCompletion* aio_comp, io::Extents&& image_extents,
+      io::SnapIds&& snap_ids, int list_snaps_flags,
+      io::SnapshotDelta* snapshot_delta, const ZTracer::Trace &parent_trace,
+      uint64_t tid, std::atomic<uint32_t>* image_dispatch_flags,
+      io::DispatchResult* dispatch_result, Context** on_finish,
+      Context* on_dispatched) override {
+    return false;
+  }
+
+  void remap_extents(io::Extents&& image_extents,
+                     io::ImageExtentsMapType type) override;
+
+private:
+  uint64_t m_data_offset;
+
+};
+
+} // namespace crypto
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_CRYPTO_CRYPTO_IMAGE_DISPATCH_H
index b09aad720a6b5d039804da34161f3c1a0e8c0772..25f47f5074365fe756522cd499ec91239cc13868 100644 (file)
@@ -77,8 +77,8 @@ struct C_AlignedObjectReadRequest : public Context {
         for (auto& extent: *extents) {
           auto crypto_ret = crypto->decrypt_aligned_extent(
                   extent,
-                  Striper::get_file_offset(
-                          cct, &image_ctx->layout, object_no, extent.offset));
+                  io::util::get_file_offset(
+                          image_ctx, object_no, extent.offset));
           if (crypto_ret != 0) {
             ceph_assert(crypto_ret < 0);
             r = crypto_ret;
@@ -483,9 +483,7 @@ bool CryptoObjectDispatch<I>::write(
   if (m_crypto->is_aligned(object_off, data.length())) {
     auto r = m_crypto->encrypt(
             &data,
-            Striper::get_file_offset(
-                    m_image_ctx->cct, &m_image_ctx->layout, object_no,
-                    object_off));
+            io::util::get_file_offset(m_image_ctx, object_no, object_off));
     *dispatch_result = r == 0 ? io::DISPATCH_RESULT_CONTINUE
                               : io::DISPATCH_RESULT_COMPLETE;
     on_dispatched->complete(r);
index aa8dfdfe8c39d435bbcf6523178a7d2626181bb7..b1680a1b4712ac1fed75db4b18371cc7a86869a2 100644 (file)
@@ -15,6 +15,7 @@
 #include "librbd/io/ImageDispatchSpec.h"
 #include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/io/ReadResult.h"
+#include "librbd/io/Utils.h"
 #include "osdc/Striper.h"
 
 #define dout_subsys ceph_subsys_rbd
@@ -67,9 +68,9 @@ void ObjectCopyRequest<I>::send() {
 template <typename I>
 void ObjectCopyRequest<I>::send_list_snaps() {
   // image extents are consistent across src and dst so compute once
-  Striper::extent_to_file(m_cct, &m_dst_image_ctx->layout, m_dst_object_number,
-                          0, m_dst_image_ctx->layout.object_size,
-                          m_image_extents);
+  io::util::extent_to_file(
+          m_dst_image_ctx, m_dst_object_number, 0,
+          m_dst_image_ctx->layout.object_size, m_image_extents);
   ldout(m_cct, 20) << "image_extents=" << m_image_extents << dendl;
 
   io::SnapIds snap_ids;
@@ -578,8 +579,8 @@ void ObjectCopyRequest<I>::merge_write_ops() {
     for (auto [image_offset, image_length] : read_op.image_extent_map) {
       // convert image extents back to object extents for the write op
       striper::LightweightObjectExtents object_extents;
-      Striper::file_to_extents(m_cct, &m_dst_image_ctx->layout, image_offset,
-                               image_length, 0, buffer_offset, &object_extents);
+      io::util::file_to_extents(m_dst_image_ctx, image_offset,
+                                image_length, buffer_offset, &object_extents);
       for (auto& object_extent : object_extents) {
         ldout(m_cct, 20) << "src_snap_seq=" << src_snap_seq << ", "
                          << "object_offset=" << object_extent.offset << ", "
@@ -722,8 +723,8 @@ void ObjectCopyRequest<I>::compute_zero_ops() {
     for (auto z = zero_interval.begin(); z != zero_interval.end(); ++z) {
       // convert image extents back to object extents for the write op
       striper::LightweightObjectExtents object_extents;
-      Striper::file_to_extents(m_cct, &m_dst_image_ctx->layout, z.get_start(),
-                               z.get_len(), 0, 0, &object_extents);
+      io::util::file_to_extents(m_dst_image_ctx, z.get_start(), z.get_len(), 0,
+                                &object_extents);
       for (auto& object_extent : object_extents) {
         ceph_assert(object_extent.offset + object_extent.length <=
                       m_dst_image_ctx->layout.object_size);
index 93effcb1cbb6858e5a01285786d00326404b3edd..fb5dfe4a70d9c140f8c855a9ce9efc6a90796001 100644 (file)
@@ -21,6 +21,7 @@
 #include "librbd/io/ObjectDispatcherInterface.h"
 #include "librbd/io/ObjectRequest.h"
 #include "librbd/io/ReadResult.h"
+#include "librbd/io/Utils.h"
 
 #include <boost/lambda/bind.hpp>
 #include <boost/lambda/construct.hpp>
@@ -118,10 +119,10 @@ CopyupRequest<I>::CopyupRequest(I *ictx, uint64_t objectno,
                                 Extents &&image_extents,
                                 const ZTracer::Trace &parent_trace)
   : m_image_ctx(ictx), m_object_no(objectno), m_image_extents(image_extents),
-    m_trace(util::create_trace(*m_image_ctx, "copy-up", parent_trace))
+    m_trace(librbd::util::create_trace(*m_image_ctx, "copy-up", parent_trace))
 {
   ceph_assert(m_image_ctx->data_ctx.is_valid());
-  m_async_op.start_op(*util::get_image_ctx(m_image_ctx));
+  m_async_op.start_op(*librbd::util::get_image_ctx(m_image_ctx));
 }
 
 template <typename I>
@@ -175,7 +176,7 @@ void CopyupRequest<I>::read_from_parent() {
   auto comp = AioCompletion::create_and_start<
     CopyupRequest<I>,
     &CopyupRequest<I>::handle_read_from_parent>(
-      this, util::get_image_ctx(m_image_ctx->parent), AIO_TYPE_READ);
+      this, librbd::util::get_image_ctx(m_image_ctx->parent), AIO_TYPE_READ);
 
   ldout(cct, 20) << "completion=" << comp << ", "
                  << "extents=" << m_image_extents
@@ -248,7 +249,7 @@ void CopyupRequest<I>::deep_copy() {
 
   ldout(cct, 20) << "flatten=" << m_flatten << dendl;
 
-  auto ctx = util::create_context_callback<
+  auto ctx = librbd::util::create_context_callback<
     CopyupRequest<I>, &CopyupRequest<I>::handle_deep_copy>(this);
   auto req = deep_copy::ObjectCopyRequest<I>::create(
     m_image_ctx->parent, m_image_ctx, 0, 0,
@@ -354,7 +355,7 @@ void CopyupRequest<I>::update_object_maps() {
     boost::lambda::bind(boost::lambda::new_ptr<C_UpdateObjectMap<I>>(),
     boost::lambda::_1, m_image_ctx, m_object_no, head_object_map_state,
     &m_snap_ids, m_first_snap_is_clean, m_trace, boost::lambda::_2));
-  auto ctx = util::create_context_callback<
+  auto ctx = librbd::util::create_context_callback<
     CopyupRequest<I>, &CopyupRequest<I>::handle_update_object_maps>(this);
   auto throttle = new AsyncObjectThrottle<I>(
     nullptr, *m_image_ctx, context_factory, ctx, nullptr, 0, m_snap_ids.size());
@@ -643,10 +644,8 @@ void CopyupRequest<I>::compute_deep_copy_snap_ids() {
         return false;
       }
       std::vector<std::pair<uint64_t, uint64_t>> extents;
-      Striper::extent_to_file(cct, &m_image_ctx->layout,
-                              m_object_no, 0,
-                              m_image_ctx->layout.object_size,
-                              extents);
+      util::extent_to_file(m_image_ctx, m_object_no, 0,
+                               m_image_ctx->layout.object_size, extents);
       auto overlap = m_image_ctx->prune_parent_extents(
           extents, parent_overlap);
       return overlap > 0;
@@ -664,9 +663,8 @@ void CopyupRequest<I>::convert_copyup_extent_map() {
   // convert the image-extent extent map to object-extents
   for (auto [image_offset, image_length] : image_extent_map) {
     striper::LightweightObjectExtents object_extents;
-    Striper::file_to_extents(
-      cct, &m_image_ctx->layout, image_offset, image_length, 0, 0,
-      &object_extents);
+    util::file_to_extents(
+      m_image_ctx, image_offset, image_length, 0, &object_extents);
     for (auto& object_extent : object_extents) {
       m_copyup_extent_map.emplace_back(
         object_extent.offset, object_extent.length);
index 205c18c474fa724b7885e522636287ab68832b57..2341107179ce4d4406657ab87f06be92c65f03b1 100644 (file)
@@ -80,6 +80,10 @@ struct ImageDispatchInterface {
       Context* on_dispatched) = 0;
 
   virtual bool invalidate_cache(Context* on_finish) = 0;
+  
+  virtual void remap_extents(Extents&& image_extents,
+                             ImageExtentsMapType type) {}
+
 };
 
 } // namespace io
index fb5908b01c0d62719b80cdd010babd0f2425eab8..a9c1c985522decf4670cc0e9765f1bda7612ab5d 100644 (file)
@@ -260,6 +260,25 @@ void ImageDispatcher<I>::wait_on_writes_unblocked(Context *on_unblocked) {
   m_write_block_dispatch->wait_on_writes_unblocked(on_unblocked);
 }
 
+template <typename I>
+void ImageDispatcher<I>::remap_extents(Extents&& image_extents,
+                                       ImageExtentsMapType type) {
+  auto loop = [&image_extents, type](auto begin, auto end) {
+      for (auto it = begin; it != end; ++it) {
+        auto& image_dispatch_meta = it->second;
+        auto image_dispatch = image_dispatch_meta.dispatch;
+        image_dispatch->remap_extents(std::move(image_extents), type);
+      }
+  };
+
+  std::shared_lock locker{this->m_lock};
+  if (type == IMAGE_EXTENTS_MAP_TYPE_LOGICAL_TO_PHYSICAL) {
+    loop(this->m_dispatches.cbegin(), this->m_dispatches.cend());
+  } else if (type == IMAGE_EXTENTS_MAP_TYPE_PHYSICAL_TO_LOGICAL) {
+    loop(this->m_dispatches.crbegin(), this->m_dispatches.crend());
+  }
+}
+
 template <typename I>
 bool ImageDispatcher<I>::send_dispatch(
     ImageDispatchInterface* image_dispatch,
index 26efd9d8124b8d6fdf5d0cd691b3425c46346bda..d1176ae050e64a2f28c3cdd8a26189549b07284e 100644 (file)
@@ -45,6 +45,9 @@ public:
   void unblock_writes() override;
   void wait_on_writes_unblocked(Context *on_unblocked) override;
 
+  void remap_extents(Extents&& image_extents,
+                     ImageExtentsMapType type) override;
+
 protected:
   bool send_dispatch(
     ImageDispatchInterface* image_dispatch,
index 8bff8566ed24578bfc4f3338841e1600cf1f6dbc..f6b572c5d9e07aea84cb6ff33ebf345524660972 100644 (file)
@@ -29,6 +29,8 @@ public:
   virtual void wait_on_writes_unblocked(Context *on_unblocked) = 0;
 
   virtual void invalidate_cache(Context* on_finish) = 0;
+  virtual void remap_extents(Extents&& image_extents,
+                             ImageExtentsMapType type) = 0;
 };
 
 } // namespace io
index 17b97f9edf870ca752f332d72c8e56a1239222b1..4b31f2c7ae8a9468b8da3251c60b66565a621802 100644 (file)
@@ -87,14 +87,11 @@ struct C_AssembleSnapshotDeltas : public C_AioRequest {
       uint64_t object_no, const SnapshotDelta& object_snapshot_delta,
       SnapshotDelta* image_snapshot_delta,
       SnapshotDelta* assembled_image_snapshot_delta) {
-    auto cct = image_ctx->cct;
     for (auto& [key, object_extents] : object_snapshot_delta) {
       for (auto& object_extent : object_extents) {
         Extents image_extents;
-        Striper::extent_to_file(cct, &image_ctx->layout, object_no,
-                                object_extent.get_off(),
-                                object_extent.get_len(),
-                                image_extents);
+        io::util::extent_to_file(image_ctx, object_no, object_extent.get_off(),
+                                 object_extent.get_len(), image_extents);
 
         auto& intervals = (*image_snapshot_delta)[key];
         auto& assembled_intervals = (*assembled_image_snapshot_delta)[key];
@@ -159,9 +156,8 @@ void readahead(I *ictx, const Extents& image_extents, IOContext io_context) {
     ldout(ictx->cct, 20) << "(readahead logical) " << readahead_offset << "~"
                          << readahead_length << dendl;
     LightweightObjectExtents readahead_object_extents;
-    Striper::file_to_extents(ictx->cct, &ictx->layout,
-                             readahead_offset, readahead_length, 0, 0,
-                             &readahead_object_extents);
+    io::util::file_to_extents(ictx, readahead_offset, readahead_length, 0,
+                              &readahead_object_extents);
     for (auto& object_extent : readahead_object_extents) {
       ldout(ictx->cct, 20) << "(readahead) "
                            << data_object_name(ictx,
@@ -397,8 +393,8 @@ void ImageReadRequest<I>::send_request() {
       continue;
     }
 
-    Striper::file_to_extents(cct, &image_ctx.layout, extent.first,
-                             extent.second, 0, buffer_ofs, &object_extents);
+    util::file_to_extents(&image_ctx, extent.first, extent.second, buffer_ofs,
+                          &object_extents);
     buffer_ofs += extent.second;
   }
 
@@ -428,7 +424,6 @@ void ImageReadRequest<I>::send_request() {
 template <typename I>
 void AbstractImageWriteRequest<I>::send_request() {
   I &image_ctx = this->m_image_ctx;
-  CephContext *cct = image_ctx.cct;
 
   bool journaling = false;
 
@@ -449,8 +444,8 @@ void AbstractImageWriteRequest<I>::send_request() {
     }
 
     // map to object extents
-    Striper::file_to_extents(cct, &image_ctx.layout, extent.first,
-                             extent.second, 0, clip_len, &object_extents);
+    io::util::file_to_extents(&image_ctx, extent.first, extent.second, clip_len,
+                              &object_extents);
     clip_len += extent.second;
   }
 
@@ -840,8 +835,8 @@ void ImageListSnapsRequest<I>::send_request() {
     }
 
     striper::LightweightObjectExtents object_extents;
-    Striper::file_to_extents(cct, &image_ctx.layout, image_extent.first,
-                             image_extent.second, 0, 0, &object_extents);
+    io::util::file_to_extents(&image_ctx, image_extent.first,
+                              image_extent.second, 0, &object_extents);
     for (auto& object_extent : object_extents) {
       object_number_extents[object_extent.object_no].emplace_back(
         object_extent.offset, object_extent.length);
index 0964bec991278e640ce4ffdfc3c987ef4f94bd48..0914d08ef190603d19ed1b963e8b6cf230a0603c 100644 (file)
@@ -170,8 +170,8 @@ bool ObjectRequest<I>::compute_parent_extents(Extents *parent_extents,
     return false;
   }
 
-  Striper::extent_to_file(m_ictx->cct, &m_ictx->layout, m_object_no, 0,
-                          m_ictx->layout.object_size, *parent_extents);
+  io::util::extent_to_file(m_ictx, m_object_no, 0, m_ictx->layout.object_size,
+                           *parent_extents);
   uint64_t object_overlap = m_ictx->prune_parent_extents(*parent_extents,
                                                          parent_overlap);
   if (object_overlap > 0) {
@@ -704,9 +704,8 @@ int ObjectCompareAndWriteRequest<I>::filter_write_result(int r) const {
 
     // object extent compare mismatch
     uint64_t offset = -MAX_ERRNO - r;
-    Striper::extent_to_file(image_ctx->cct, &image_ctx->layout,
-                            this->m_object_no, offset, this->m_object_len,
-                            image_extents);
+    io::util::extent_to_file(image_ctx, this->m_object_no, offset,
+                             this->m_object_len, image_extents);
     ceph_assert(image_extents.size() == 1);
 
     if (m_mismatch_offset) {
@@ -951,8 +950,8 @@ void ObjectListSnapsRequest<I>::list_from_parent() {
   // calculate reverse mapping onto the parent image
   Extents parent_image_extents;
   for (auto [object_off, object_len]: m_object_extents) {
-    Striper::extent_to_file(cct, &image_ctx->layout, this->m_object_no,
-                            object_off, object_len, parent_image_extents);
+    io::util::extent_to_file(image_ctx, this->m_object_no, object_off,
+                             object_len, parent_image_extents);
   }
 
   uint64_t parent_overlap = 0;
@@ -1014,8 +1013,8 @@ void ObjectListSnapsRequest<I>::handle_list_from_parent(int r) {
 
       // map image-extents back to this object
       striper::LightweightObjectExtents object_extents;
-      Striper::file_to_extents(cct, &image_ctx->layout, image_extent.get_off(),
-                               image_extent.get_len(), 0, 0, &object_extents);
+      io::util::file_to_extents(image_ctx, image_extent.get_off(),
+                                image_extent.get_len(), 0, &object_extents);
       for (auto& object_extent : object_extents) {
         ceph_assert(object_extent.object_no == this->m_object_no);
         intervals.insert(
index b0428a0ba753108b93fef1a3d67350968791fad3..8d91c55158c6bc9f3f63a9df44bf4b88f634c744 100644 (file)
@@ -66,6 +66,7 @@ enum ImageDispatchLayer {
   IMAGE_DISPATCH_LAYER_JOURNAL,
   IMAGE_DISPATCH_LAYER_WRITE_BLOCK,
   IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE,
+  IMAGE_DISPATCH_LAYER_CRYPTO,
   IMAGE_DISPATCH_LAYER_CORE,
   IMAGE_DISPATCH_LAYER_LAST
 };
@@ -96,6 +97,11 @@ enum {
     IMAGE_DISPATCH_FLAG_QOS_IOPS_MASK),
 };
 
+enum ImageExtentsMapType {
+    IMAGE_EXTENTS_MAP_TYPE_LOGICAL_TO_PHYSICAL,
+    IMAGE_EXTENTS_MAP_TYPE_PHYSICAL_TO_LOGICAL,
+};
+
 enum ObjectDispatchLayer {
   OBJECT_DISPATCH_LAYER_NONE = 0,
   OBJECT_DISPATCH_LAYER_CACHE,
index 99a911410aaed4528de3b8d7488e18250ff9b9b1..4d11863a97baa8bff09f3ae6ef5a976cdcf83b99 100644 (file)
@@ -11,6 +11,7 @@
 #include "librbd/io/AioCompletion.h"
 #include "librbd/io/ImageDispatchSpec.h"
 #include "librbd/io/ObjectRequest.h"
+#include "librbd/io/ImageDispatcherInterface.h"
 #include "osd/osd_types.h"
 #include "osdc/Striper.h"
 
@@ -94,8 +95,8 @@ void read_parent(I *image_ctx, uint64_t object_no, ReadExtents* extents,
   // calculate reverse mapping onto the image
   Extents parent_extents;
   for (auto& extent: *extents) {
-    Striper::extent_to_file(cct, &image_ctx->layout, object_no, extent.offset,
-                            extent.length, parent_extents);
+    extent_to_file(image_ctx, object_no, extent.offset, extent.length,
+                   parent_extents);
   }
 
   uint64_t parent_overlap = 0;
@@ -180,6 +181,39 @@ bool trigger_copyup(I* image_ctx, uint64_t object_no, IOContext io_context,
   return true;
 }
 
+template <typename I>
+void file_to_extents(I* image_ctx, uint64_t offset, uint64_t length,
+                     uint64_t buffer_offset,
+                     striper::LightweightObjectExtents* object_extents) {
+  Extents extents = {{offset, length}};
+  image_ctx->io_image_dispatcher->remap_extents(
+          std::move(extents), IMAGE_EXTENTS_MAP_TYPE_LOGICAL_TO_PHYSICAL);
+  for (auto [off, len] : extents) {
+    Striper::file_to_extents(image_ctx->cct, &image_ctx->layout, off, len, 0,
+                             buffer_offset, object_extents);
+  }
+}
+
+template <typename I>
+void extent_to_file(I* image_ctx, uint64_t object_no, uint64_t offset,
+                    uint64_t length,
+                    std::vector<std::pair<uint64_t, uint64_t> >& extents) {
+  Striper::extent_to_file(image_ctx->cct, &image_ctx->layout, object_no,
+                          offset, length, extents);
+  image_ctx->io_image_dispatcher->remap_extents(
+          std::move(extents), IMAGE_EXTENTS_MAP_TYPE_PHYSICAL_TO_LOGICAL);
+}
+
+template <typename I>
+uint64_t get_file_offset(I* image_ctx, uint64_t object_no, uint64_t offset) {
+  auto off = Striper::get_file_offset(image_ctx->cct, &image_ctx->layout,
+                                      object_no, offset);
+  Extents extents = {{off, 0}};
+  image_ctx->io_image_dispatcher->remap_extents(
+          std::move(extents), IMAGE_EXTENTS_MAP_TYPE_PHYSICAL_TO_LOGICAL);
+  return extents[0].first;
+}
+
 } // namespace util
 } // namespace io
 } // namespace librbd
@@ -192,3 +226,14 @@ template int librbd::io::util::clip_request(
 template bool librbd::io::util::trigger_copyup(
         librbd::ImageCtx *image_ctx, uint64_t object_no, IOContext io_context,
         Context* on_finish);
+template void librbd::io::util::file_to_extents(
+        librbd::ImageCtx *image_ctx, uint64_t offset, uint64_t length,
+        uint64_t buffer_offset,
+        striper::LightweightObjectExtents* object_extents);
+template void librbd::io::util::extent_to_file(
+        librbd::ImageCtx *image_ctx, uint64_t object_no, uint64_t offset,
+        uint64_t length,
+        std::vector<std::pair<uint64_t, uint64_t> >& extents);
+template uint64_t librbd::io::util::get_file_offset(
+        librbd::ImageCtx *image_ctx, uint64_t object_no, uint64_t offset);
index 22b86058a8bbe21d82aed17612db942443d95f0b..fbcc690089198707c39af661c6a87960e9f5a74b 100644 (file)
@@ -53,6 +53,20 @@ void unsparsify(CephContext* cct, ceph::bufferlist* bl,
 template <typename ImageCtxT = librbd::ImageCtx>
 bool trigger_copyup(ImageCtxT *image_ctx, uint64_t object_no,
                     IOContext io_context, Context* on_finish);
+                
+template <typename ImageCtxT = librbd::ImageCtx>
+void file_to_extents(ImageCtxT *image_ctx, uint64_t offset, uint64_t length,
+                     uint64_t buffer_offset,
+                     striper::LightweightObjectExtents* object_extents);
+
+template <typename ImageCtxT = librbd::ImageCtx>
+void extent_to_file(ImageCtxT *image_ctx, uint64_t object_no, uint64_t offset,
+                    uint64_t length,
+                    std::vector<std::pair<uint64_t, uint64_t> >& extents);
+
+template <typename ImageCtxT = librbd::ImageCtx>
+uint64_t get_file_offset(ImageCtxT *image_ctx, uint64_t object_no,
+                         uint64_t offset);
 
 } // namespace util
 } // namespace io
index 1c42573664f24e55205a4d02577f6994c5ec3c0e..5623c635d8f6229083be6f3fb1fa9c9aa7ea6f56 100644 (file)
@@ -10,6 +10,7 @@
 #include "librbd/asio/ContextWQ.h"
 #include "librbd/io/ObjectDispatchSpec.h"
 #include "librbd/io/ObjectDispatcherInterface.h"
+#include "librbd/io/Utils.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
@@ -51,8 +52,8 @@ struct C_CommitIOEvent : public Context {
         (object_dispatch_flags &
            io::OBJECT_DISPATCH_FLAG_WILL_RETRY_ON_ERROR) == 0) {
       io::Extents file_extents;
-      Striper::extent_to_file(image_ctx->cct, &image_ctx->layout, object_no,
-                              object_off, object_len, file_extents);
+      io::util::extent_to_file(image_ctx, object_no, object_off, object_len,
+                               file_extents);
       for (auto& extent : file_extents) {
         journal->commit_io_event_extent(journal_tid, extent.first,
                                         extent.second, r);
index 805a83d75bda1ebd1494c44e8dace4014a871aea..e4e4493cc5226fe45e5c57b6ecc167f8b6d37276 100644 (file)
@@ -55,6 +55,12 @@ CopyupRequest<librbd::MockImageCtx>* CopyupRequest<
 
 namespace util {
 
+template <> uint64_t get_file_offset(
+        MockImageCtx *image_ctx, uint64_t object_no, uint64_t offset) {
+  return Striper::get_file_offset(image_ctx->cct, &image_ctx->layout,
+                                  object_no, offset);
+}
+
 namespace {
 
 struct Mock {
index 3860a9aa1c93a009526cccad20b4d86dc873aea6..56ae4c195206f02c9c57c74e87957cabdc605e38 100644 (file)
@@ -15,6 +15,7 @@
 #include "librbd/api/Io.h"
 #include "librbd/deep_copy/ObjectCopyRequest.h"
 #include "librbd/io/ReadResult.h"
+#include "librbd/io/Utils.h"
 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
 #include "test/librbd/mock/MockImageCtx.h"
 #include "test/librbd/test_support.h"
@@ -39,6 +40,29 @@ inline ImageCtx* get_image_ctx(MockTestImageCtx* image_ctx) {
 }
 
 } // namespace util
+
+namespace io {
+namespace util {
+
+template <> void file_to_extents(
+        MockTestImageCtx* image_ctx, uint64_t offset, uint64_t length,
+        uint64_t buffer_offset,
+        striper::LightweightObjectExtents* object_extents) {
+  Striper::file_to_extents(image_ctx->cct, &image_ctx->layout, offset, length,
+                           0, buffer_offset, object_extents);
+}
+
+template <> void extent_to_file(
+        MockTestImageCtx* image_ctx, uint64_t object_no, uint64_t offset,
+        uint64_t length,
+        std::vector<std::pair<uint64_t, uint64_t> >& extents) {
+  Striper::extent_to_file(image_ctx->cct, &image_ctx->layout, object_no,
+                          offset, length, extents);
+}
+
+} // namespace util
+} // namespace io
+
 } // namespace librbd
 
 // template definitions
index ee7a911c43e2caf6ddf7e2b0e9b0fb6d6ae8d823..413400b81b7d0d21b4d9bf55732410a05203c653 100644 (file)
@@ -16,6 +16,7 @@
 #include "librbd/io/ImageDispatchSpec.h"
 #include "librbd/io/ObjectRequest.h"
 #include "librbd/io/ReadResult.h"
+#include "librbd/io/Utils.h"
 
 namespace librbd {
 namespace {
@@ -80,6 +81,26 @@ ObjectCopyRequest<librbd::MockTestImageCtx>* ObjectCopyRequest<librbd::MockTestI
 
 namespace io {
 
+namespace util {
+
+template <> void file_to_extents(
+        MockTestImageCtx* image_ctx, uint64_t offset, uint64_t length,
+        uint64_t buffer_offset,
+        striper::LightweightObjectExtents* object_extents) {
+  Striper::file_to_extents(image_ctx->cct, &image_ctx->layout, offset, length,
+                           0, buffer_offset, object_extents);
+}
+
+template <> void extent_to_file(
+        MockTestImageCtx* image_ctx, uint64_t object_no, uint64_t offset,
+        uint64_t length,
+        std::vector<std::pair<uint64_t, uint64_t> >& extents) {
+  Striper::extent_to_file(image_ctx->cct, &image_ctx->layout, object_no,
+                          offset, length, extents);
+}
+
+} // namespace util
+
 template <>
 struct ObjectRequest<librbd::MockTestImageCtx> {
   static void add_write_hint(librbd::MockTestImageCtx&,
index c17e55ca45f7c27f154323ebe3d40bc7580abaeb..d1390bcf85d85eeae893a75c75eb84cf270bf81a 100644 (file)
@@ -8,6 +8,7 @@
 #include "test/librbd/mock/cache/MockImageCache.h"
 #include "librbd/io/ImageRequest.h"
 #include "librbd/io/ObjectDispatchSpec.h"
+#include "librbd/io/Utils.h"
 
 namespace librbd {
 namespace {
@@ -53,6 +54,27 @@ inline ImageCtx *get_image_ctx(MockTestImageCtx *image_ctx) {
 namespace librbd {
 namespace io {
 
+namespace util {
+
+template<>
+void file_to_extents(
+        MockTestImageCtx *image_ctx, uint64_t offset, uint64_t length,
+        uint64_t buffer_offset,
+        striper::LightweightObjectExtents *object_extents) {
+  Striper::file_to_extents(image_ctx->cct, &image_ctx->layout, offset, length,
+                           0, buffer_offset, object_extents);
+}
+
+template <> void extent_to_file(
+        MockTestImageCtx* image_ctx, uint64_t object_no, uint64_t offset,
+        uint64_t length,
+        std::vector<std::pair<uint64_t, uint64_t> >& extents) {
+  Striper::extent_to_file(image_ctx->cct, &image_ctx->layout, object_no,
+                          offset, length, extents);
+}
+
+} // namespace util
+
 using ::testing::_;
 using ::testing::InSequence;
 using ::testing::Invoke;
index 559de694e5ebe63ff724bd510b62e6203fdaf02b..5a451bcfbc51017e42509ae6e5a0120b435ac5da 100644 (file)
@@ -90,6 +90,22 @@ ImageListSnapsRequest<librbd::MockTestImageCtx>* ImageListSnapsRequest<librbd::M
 
 namespace util {
 
+template <> void file_to_extents(
+        MockTestImageCtx* image_ctx, uint64_t offset, uint64_t length,
+        uint64_t buffer_offset,
+        striper::LightweightObjectExtents* object_extents) {
+  Striper::file_to_extents(image_ctx->cct, &image_ctx->layout, offset, length,
+                           0, buffer_offset, object_extents);
+}
+
+template <> void extent_to_file(
+        MockTestImageCtx* image_ctx, uint64_t object_no, uint64_t offset,
+        uint64_t length,
+        std::vector<std::pair<uint64_t, uint64_t> >& extents) {
+  Striper::extent_to_file(image_ctx->cct, &image_ctx->layout, object_no,
+                          offset, length, extents);
+}
+
 namespace {
 
 struct Mock {
index 14669133048ab6f745eac1da5146b8d926e05c44..7d63044cda8102720cb8c2430c1af64a3ee5abb9 100644 (file)
@@ -37,6 +37,8 @@ public:
 
   MOCK_METHOD0(unblock_writes, void());
   MOCK_METHOD1(wait_on_writes_unblocked, void(Context*));
+
+  MOCK_METHOD2(remap_extents, void(Extents&&, ImageExtentsMapType));
 };
 
 } // namespace io