From 75a9cbbc74ccab9a990a38f941c2f35c8570d76f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rados=C5=82aw=20Zarzy=C5=84ski?= Date: Tue, 26 Apr 2022 15:50:32 +0200 Subject: [PATCH] crimson/os: add junction between OSD's ops and Seastore's OrderingHandle. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Radosław Zarzyński --- src/crimson/os/seastore/ordering_handle.h | 140 +++++++++++++++++----- src/crimson/osd/osd_operation.h | 8 ++ 2 files changed, 115 insertions(+), 33 deletions(-) diff --git a/src/crimson/os/seastore/ordering_handle.h b/src/crimson/os/seastore/ordering_handle.h index b44860f092991..add75066be4d1 100644 --- a/src/crimson/os/seastore/ordering_handle.h +++ b/src/crimson/os/seastore/ordering_handle.h @@ -6,9 +6,36 @@ #include #include "crimson/common/operation.h" +#include "crimson/osd/osd_operation.h" namespace crimson::os::seastore { +struct WritePipeline { + struct ReserveProjectedUsage : OrderedExclusivePhaseT { + constexpr static auto type_name = "WritePipeline::reserve_projected_usage"; + } reserve_projected_usage; + struct OolWrites : UnorderedStageT { + constexpr static auto type_name = "UnorderedStage::ool_writes_stage"; + } ool_writes; + struct Prepare : OrderedExclusivePhaseT { + constexpr static auto type_name = "WritePipeline::prepare_phase"; + } prepare; + struct DeviceSubmission : OrderedConcurrentPhaseT { + constexpr static auto type_name = "WritePipeline::device_submission_phase"; + } device_submission; + struct Finalize : OrderedExclusivePhaseT { + constexpr static auto type_name = "WritePipeline::finalize_phase"; + } finalize; + + using BlockingEvents = std::tuple< + ReserveProjectedUsage::BlockingEvent, + OolWrites::BlockingEvent, + Prepare::BlockingEvent, + DeviceSubmission::BlockingEvent, + Finalize::BlockingEvent + >; +}; + /** * PlaceholderOperation * @@ -17,31 +44,85 @@ namespace crimson::os::seastore { * Until then (and for tests likely permanently) we'll use this unregistered * placeholder for the pipeline phases necessary for journal correctness. */ -class PlaceholderOperation : public Operation { +class PlaceholderOperation : public crimson::osd::PhasedOperationT { public: - using IRef = boost::intrusive_ptr; + constexpr static auto type = 0U; + constexpr static auto type_name = + "crimson::os::seastore::PlaceholderOperation"; - unsigned get_type() const final { - return 0; + static PlaceholderOperation::IRef create() { + return IRef{new PlaceholderOperation()}; } - const char *get_type_name() const final { - return "crimson::os::seastore::PlaceholderOperation"; - } + WritePipeline::BlockingEvents tracking_events; private: void dump_detail(ceph::Formatter *f) const final {} void print(std::ostream &) const final {} }; -struct OrderingHandle { +struct OperationProxy { OperationRef op; - PipelineHandle phase_handle; + OperationProxy(OperationRef op) : op(std::move(op)) {} + + virtual seastar::future<> enter(WritePipeline::ReserveProjectedUsage&) = 0; + virtual seastar::future<> enter(WritePipeline::OolWrites&) = 0; + virtual seastar::future<> enter(WritePipeline::Prepare&) = 0; + virtual seastar::future<> enter(WritePipeline::DeviceSubmission&) = 0; + virtual seastar::future<> enter(WritePipeline::Finalize&) = 0; + + virtual void exit() = 0; + virtual seastar::future<> complete() = 0; + + virtual ~OperationProxy() = default; +}; + +template +struct OperationProxyT : OperationProxy { + OperationProxyT(typename OpT::IRef op) : OperationProxy(op) {} + + OpT* that() { + return static_cast(op.get()); + } + const OpT* that() const { + return static_cast(op.get()); + } + + seastar::future<> enter(WritePipeline::ReserveProjectedUsage& s) final { + return that()->enter_stage(s); + } + seastar::future<> enter(WritePipeline::OolWrites& s) final { + return that()->enter_stage(s); + } + seastar::future<> enter(WritePipeline::Prepare& s) final { + return that()->enter_stage(s); + } + seastar::future<> enter(WritePipeline::DeviceSubmission& s) final { + return that()->enter_stage(s); + } + seastar::future<> enter(WritePipeline::Finalize& s) final { + return that()->enter_stage(s); + } + + void exit() final { + return that()->handle.exit(); + } + seastar::future<> complete() final { + return that()->handle.complete(); + } +}; + +struct OrderingHandle { + // we can easily optimize this dynalloc out as all concretes are + // supposed to have exactly the same size. + std::unique_ptr op; seastar::shared_mutex *collection_ordering_lock = nullptr; - OrderingHandle(OperationRef &&op) : op(std::move(op)) {} + // in the future we might add further constructors / template to type + // erasure while extracting the location of tracking events. + OrderingHandle(std::unique_ptr op) : op(std::move(op)) {} OrderingHandle(OrderingHandle &&other) - : op(std::move(other.op)), phase_handle(std::move(other.phase_handle)), + : op(std::move(other.op)), collection_ordering_lock(other.collection_ordering_lock) { other.collection_ordering_lock = nullptr; } @@ -61,16 +142,15 @@ struct OrderingHandle { template seastar::future<> enter(T &t) { - //return op->with_blocking_future(phase_handle.enter(t)); - return seastar::now(); + return op->enter(t); } void exit() { - return phase_handle.exit(); + op->exit(); } seastar::future<> complete() { - return phase_handle.complete(); + return op->complete(); } ~OrderingHandle() { @@ -79,25 +159,19 @@ struct OrderingHandle { }; inline OrderingHandle get_dummy_ordering_handle() { - return OrderingHandle{new PlaceholderOperation}; + using PlaceholderOpProxy = OperationProxyT; + return OrderingHandle{ + std::make_unique(PlaceholderOperation::create())}; } -struct WritePipeline { - OrderedExclusivePhase reserve_projected_usage{ - "WritePipeline::reserve_projected_usage" - }; - UnorderedStage ool_writes{ - "UnorderedStage::ool_writes_stage" - }; - OrderedExclusivePhase prepare{ - "WritePipeline::prepare_phase" - }; - OrderedConcurrentPhase device_submission{ - "WritePipeline::device_submission_phase" - }; - OrderedExclusivePhase finalize{ - "WritePipeline::finalize_phase" +} // namespace crimson::os::seastore + +namespace crimson { + template <> + struct EventBackendRegistry { + static std::tuple<> get_backends() { + return {}; + } }; -}; +} // namespace crimson -} diff --git a/src/crimson/osd/osd_operation.h b/src/crimson/osd/osd_operation.h index 66f2ef9eb77b4..f3e4f6386d0d3 100644 --- a/src/crimson/osd/osd_operation.h +++ b/src/crimson/osd/osd_operation.h @@ -8,6 +8,11 @@ #include "crimson/osd/scheduler/scheduler.h" #include "osd/osd_types.h" +namespace crimson::os::seastore { + template + class OperationProxyT; +} + namespace crimson::osd { enum class OperationTypeCode { @@ -188,6 +193,9 @@ protected: } PipelineHandle handle; + + template + friend class crimson::os::seastore::OperationProxyT; }; /** -- 2.39.5