diff options
23 files changed, 365 insertions, 56 deletions
diff --git a/src/librbd/CMakeLists.txt b/src/librbd/CMakeLists.txt index ac4b196def1..7fbadfd49ba 100644 --- a/src/librbd/CMakeLists.txt +++ b/src/librbd/CMakeLists.txt @@ -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 diff --git a/src/librbd/cache/ObjectCacherWriteback.cc b/src/librbd/cache/ObjectCacherWriteback.cc index 50655b6a111..9f3d5c8953e 100644 --- a/src/librbd/cache/ObjectCacherWriteback.cc +++ b/src/librbd/cache/ObjectCacherWriteback.cc @@ -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 index 00000000000..84c9a59be9a --- /dev/null +++ b/src/librbd/crypto/CryptoImageDispatch.cc @@ -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 index 00000000000..afc3c84543c --- /dev/null +++ b/src/librbd/crypto/CryptoImageDispatch.h @@ -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 diff --git a/src/librbd/crypto/CryptoObjectDispatch.cc b/src/librbd/crypto/CryptoObjectDispatch.cc index b09aad720a6..25f47f50743 100644 --- a/src/librbd/crypto/CryptoObjectDispatch.cc +++ b/src/librbd/crypto/CryptoObjectDispatch.cc @@ -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); diff --git a/src/librbd/deep_copy/ObjectCopyRequest.cc b/src/librbd/deep_copy/ObjectCopyRequest.cc index aa8dfdfe8c3..b1680a1b471 100644 --- a/src/librbd/deep_copy/ObjectCopyRequest.cc +++ b/src/librbd/deep_copy/ObjectCopyRequest.cc @@ -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); diff --git a/src/librbd/io/CopyupRequest.cc b/src/librbd/io/CopyupRequest.cc index 93effcb1cbb..fb5dfe4a70d 100644 --- a/src/librbd/io/CopyupRequest.cc +++ b/src/librbd/io/CopyupRequest.cc @@ -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); diff --git a/src/librbd/io/ImageDispatchInterface.h b/src/librbd/io/ImageDispatchInterface.h index 205c18c474f..2341107179c 100644 --- a/src/librbd/io/ImageDispatchInterface.h +++ b/src/librbd/io/ImageDispatchInterface.h @@ -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 diff --git a/src/librbd/io/ImageDispatcher.cc b/src/librbd/io/ImageDispatcher.cc index fb5908b01c0..a9c1c985522 100644 --- a/src/librbd/io/ImageDispatcher.cc +++ b/src/librbd/io/ImageDispatcher.cc @@ -261,6 +261,25 @@ void ImageDispatcher<I>::wait_on_writes_unblocked(Context *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, ImageDispatchSpec* image_dispatch_spec) { diff --git a/src/librbd/io/ImageDispatcher.h b/src/librbd/io/ImageDispatcher.h index 26efd9d8124..d1176ae050e 100644 --- a/src/librbd/io/ImageDispatcher.h +++ b/src/librbd/io/ImageDispatcher.h @@ -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, diff --git a/src/librbd/io/ImageDispatcherInterface.h b/src/librbd/io/ImageDispatcherInterface.h index 8bff8566ed2..f6b572c5d9e 100644 --- a/src/librbd/io/ImageDispatcherInterface.h +++ b/src/librbd/io/ImageDispatcherInterface.h @@ -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 diff --git a/src/librbd/io/ImageRequest.cc b/src/librbd/io/ImageRequest.cc index 17b97f9edf8..4b31f2c7ae8 100644 --- a/src/librbd/io/ImageRequest.cc +++ b/src/librbd/io/ImageRequest.cc @@ -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); diff --git a/src/librbd/io/ObjectRequest.cc b/src/librbd/io/ObjectRequest.cc index 0964bec9912..0914d08ef19 100644 --- a/src/librbd/io/ObjectRequest.cc +++ b/src/librbd/io/ObjectRequest.cc @@ -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( diff --git a/src/librbd/io/Types.h b/src/librbd/io/Types.h index b0428a0ba75..8d91c55158c 100644 --- a/src/librbd/io/Types.h +++ b/src/librbd/io/Types.h @@ -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, diff --git a/src/librbd/io/Utils.cc b/src/librbd/io/Utils.cc index 99a911410aa..4d11863a97b 100644 --- a/src/librbd/io/Utils.cc +++ b/src/librbd/io/Utils.cc @@ -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); + diff --git a/src/librbd/io/Utils.h b/src/librbd/io/Utils.h index 22b86058a8b..fbcc6900891 100644 --- a/src/librbd/io/Utils.h +++ b/src/librbd/io/Utils.h @@ -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 diff --git a/src/librbd/journal/ObjectDispatch.cc b/src/librbd/journal/ObjectDispatch.cc index 1c42573664f..5623c635d8f 100644 --- a/src/librbd/journal/ObjectDispatch.cc +++ b/src/librbd/journal/ObjectDispatch.cc @@ -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); diff --git a/src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc b/src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc index 805a83d75bd..e4e4493cc52 100644 --- a/src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc +++ b/src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc @@ -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 { diff --git a/src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc b/src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc index 3860a9aa1c9..56ae4c19520 100644 --- a/src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc +++ b/src/test/librbd/deep_copy/test_mock_ObjectCopyRequest.cc @@ -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 diff --git a/src/test/librbd/io/test_mock_CopyupRequest.cc b/src/test/librbd/io/test_mock_CopyupRequest.cc index ee7a911c43e..413400b81b7 100644 --- a/src/test/librbd/io/test_mock_CopyupRequest.cc +++ b/src/test/librbd/io/test_mock_CopyupRequest.cc @@ -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&, diff --git a/src/test/librbd/io/test_mock_ImageRequest.cc b/src/test/librbd/io/test_mock_ImageRequest.cc index c17e55ca45f..d1390bcf85d 100644 --- a/src/test/librbd/io/test_mock_ImageRequest.cc +++ b/src/test/librbd/io/test_mock_ImageRequest.cc @@ -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; diff --git a/src/test/librbd/io/test_mock_ObjectRequest.cc b/src/test/librbd/io/test_mock_ObjectRequest.cc index 559de694e5e..5a451bcfbc5 100644 --- a/src/test/librbd/io/test_mock_ObjectRequest.cc +++ b/src/test/librbd/io/test_mock_ObjectRequest.cc @@ -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 { diff --git a/src/test/librbd/mock/io/MockImageDispatcher.h b/src/test/librbd/mock/io/MockImageDispatcher.h index 14669133048..7d63044cda8 100644 --- a/src/test/librbd/mock/io/MockImageDispatcher.h +++ b/src/test/librbd/mock/io/MockImageDispatcher.h @@ -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 |