From: Jason Dillaman Date: Wed, 29 Apr 2020 13:52:33 +0000 (-0400) Subject: librbd: initial implementation for image IO dispatcher X-Git-Tag: v17.0.0~2350^2~20 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=b6382d0968dd47933506ac9ac45d087308146bcb;p=ceph.git librbd: initial implementation for image IO dispatcher This is similar to the object IO dispatcher but it expects image extents for IO operations. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/CMakeLists.txt b/src/librbd/CMakeLists.txt index aa536e86ecfdb..edc17aedc3fe0 100644 --- a/src/librbd/CMakeLists.txt +++ b/src/librbd/CMakeLists.txt @@ -73,7 +73,9 @@ set(librbd_internal_srcs io/AioCompletion.cc io/AsyncOperation.cc io/CopyupRequest.cc + io/ImageDispatch.cc io/ImageDispatchSpec.cc + io/ImageDispatcher.cc io/ImageRequest.cc io/ImageRequestWQ.cc io/ObjectDispatch.cc diff --git a/src/librbd/io/ImageDispatch.cc b/src/librbd/io/ImageDispatch.cc new file mode 100644 index 0000000000000..2cd9f7a0b2494 --- /dev/null +++ b/src/librbd/io/ImageDispatch.cc @@ -0,0 +1,121 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/io/ImageDispatch.h" +#include "common/dout.h" +#include "common/WorkQueue.h" +#include "librbd/ImageCtx.h" +#include "librbd/io/ImageRequest.h" + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::io::ImageDispatch: " << this << " " \ + << __func__ << ": " + +namespace librbd { +namespace io { + +template +void ImageDispatch::shut_down(Context* on_finish) { + on_finish->complete(0); +} + +template +bool ImageDispatch::read( + AioCompletion* aio_comp, Extents &&image_extents, ReadResult &&read_result, + int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << "image_extents=" << image_extents << dendl; + + *dispatch_result = DISPATCH_RESULT_COMPLETE; + ImageRequest::aio_read( + m_image_ctx, aio_comp, std::move(image_extents), std::move(read_result), + op_flags, parent_trace); + return true; +} + +template +bool ImageDispatch::write( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&bl, + int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << "image_extents=" << image_extents << dendl; + + *dispatch_result = DISPATCH_RESULT_COMPLETE; + ImageRequest::aio_write( + m_image_ctx, aio_comp, std::move(image_extents), std::move(bl), op_flags, + parent_trace); + return true; +} + +template +bool ImageDispatch::discard( + AioCompletion* aio_comp, Extents &&image_extents, + uint32_t discard_granularity_bytes, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << "image_extents=" << image_extents << dendl; + + *dispatch_result = DISPATCH_RESULT_COMPLETE; + ImageRequest::aio_discard( + m_image_ctx, aio_comp, std::move(image_extents), discard_granularity_bytes, + parent_trace); + return true; +} + +template +bool ImageDispatch::write_same( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&bl, + int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << "image_extents=" << image_extents << dendl; + + *dispatch_result = DISPATCH_RESULT_COMPLETE; + ImageRequest::aio_writesame( + m_image_ctx, aio_comp, std::move(image_extents), std::move(bl), op_flags, + parent_trace); + return true; +} + +template +bool ImageDispatch::compare_and_write( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&cmp_bl, + bufferlist &&bl, uint64_t *mismatch_offset, int op_flags, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << "image_extents=" << image_extents << dendl; + + *dispatch_result = DISPATCH_RESULT_COMPLETE; + ImageRequest::aio_compare_and_write( + m_image_ctx, aio_comp, std::move(image_extents), std::move(cmp_bl), + std::move(bl), mismatch_offset, op_flags, parent_trace); + return true; +} + +template +bool ImageDispatch::flush( + AioCompletion* aio_comp, FlushSource flush_source, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) { + auto cct = m_image_ctx->cct; + ldout(cct, 20) << dendl; + + *dispatch_result = DISPATCH_RESULT_COMPLETE; + ImageRequest::aio_flush(m_image_ctx, aio_comp, flush_source, parent_trace); + return true; +} + +} // namespace io +} // namespace librbd + +template class librbd::io::ImageDispatch; diff --git a/src/librbd/io/ImageDispatch.h b/src/librbd/io/ImageDispatch.h new file mode 100644 index 0000000000000..cc56264cddc7a --- /dev/null +++ b/src/librbd/io/ImageDispatch.h @@ -0,0 +1,82 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_IO_IMAGE_DISPATCH_H +#define CEPH_LIBRBD_IO_IMAGE_DISPATCH_H + +#include "librbd/io/ImageDispatchInterface.h" +#include "include/int_types.h" +#include "include/buffer.h" +#include "common/zipkin_trace.h" +#include "librbd/io/ReadResult.h" +#include "librbd/io/Types.h" + +struct Context; + +namespace librbd { + +struct ImageCtx; + +namespace io { + +struct AioCompletion; + +template +class ImageDispatch : public ImageDispatchInterface { +public: + ImageDispatch(ImageCtxT* image_ctx) : m_image_ctx(image_ctx) { + } + + ImageDispatchLayer get_dispatch_layer() const override { + return IMAGE_DISPATCH_LAYER_CORE; + } + + void shut_down(Context* on_finish) override; + + bool read( + AioCompletion* aio_comp, Extents &&image_extents, + ReadResult &&read_result, int op_flags, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) override; + bool write( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&bl, + int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) override; + bool discard( + AioCompletion* aio_comp, Extents &&image_extents, + uint32_t discard_granularity_bytes, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) override; + bool write_same( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&bl, + int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) override; + bool compare_and_write( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&cmp_bl, + bufferlist &&bl, uint64_t *mismatch_offset, int op_flags, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) override; + bool flush( + AioCompletion* aio_comp, FlushSource flush_source, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) override; + + void handle_finished(int r, uint64_t tid) override {} + +private: + ImageCtxT* m_image_ctx; + +}; + +} // namespace io +} // namespace librbd + +extern template class librbd::io::ImageDispatch; + +#endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_H diff --git a/src/librbd/io/ImageDispatchInterface.h b/src/librbd/io/ImageDispatchInterface.h new file mode 100644 index 0000000000000..d96cb924b92c8 --- /dev/null +++ b/src/librbd/io/ImageDispatchInterface.h @@ -0,0 +1,74 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_IO_IMAGE_DISPATCH_INTERFACE_H +#define CEPH_LIBRBD_IO_IMAGE_DISPATCH_INTERFACE_H + +#include "include/int_types.h" +#include "include/buffer.h" +#include "common/zipkin_trace.h" +#include "librbd/io/ReadResult.h" +#include "librbd/io/Types.h" +#include + +struct Context; + +namespace librbd { +namespace io { + +struct AioCompletion; +template struct ImageDispatchSpec; + +struct ImageDispatchInterface { + typedef ImageDispatchLayer DispatchLayer; + typedef ImageDispatchSpec DispatchSpec; + + virtual ~ImageDispatchInterface() { + } + + virtual ImageDispatchLayer get_dispatch_layer() const = 0; + + virtual void shut_down(Context* on_finish) = 0; + + virtual bool read( + AioCompletion* aio_comp, Extents &&image_extents, + ReadResult &&read_result, int op_flags, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) = 0; + virtual bool write( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&bl, + int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) = 0; + virtual bool discard( + AioCompletion* aio_comp, Extents &&image_extents, + uint32_t discard_granularity_bytes, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) = 0; + virtual bool write_same( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&bl, + int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) = 0; + virtual bool compare_and_write( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&cmp_bl, + bufferlist &&bl, uint64_t *mismatch_offset, int op_flags, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) = 0; + virtual bool flush( + AioCompletion* aio_comp, FlushSource flush_source, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic* image_dispatch_flags, + DispatchResult* dispatch_result, Context* on_dispatched) = 0; + + virtual void handle_finished(int r, uint64_t tid) = 0; + +}; + +} // namespace io +} // namespace librbd + +#endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_INTERFACE_H diff --git a/src/librbd/io/ImageDispatchSpec.cc b/src/librbd/io/ImageDispatchSpec.cc index 1854a6af44bde..285d462737d4f 100644 --- a/src/librbd/io/ImageDispatchSpec.cc +++ b/src/librbd/io/ImageDispatchSpec.cc @@ -5,6 +5,7 @@ #include "librbd/ImageCtx.h" #include "librbd/io/AioCompletion.h" #include "librbd/io/ImageRequest.h" +#include "librbd/io/ImageDispatcherInterface.h" #include namespace librbd { @@ -53,40 +54,40 @@ struct ImageDispatchSpec::SendVisitor void operator()(Read& read) const { ImageRequest::aio_read( - &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents), - std::move(read.read_result), spec->m_op_flags, spec->m_parent_trace); + &spec->m_image_ctx, spec->aio_comp, std::move(spec->image_extents), + std::move(read.read_result), spec->op_flags, spec->parent_trace); } void operator()(Discard& discard) const { ImageRequest::aio_discard( - &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents), - discard.discard_granularity_bytes, spec->m_parent_trace); + &spec->m_image_ctx, spec->aio_comp, std::move(spec->image_extents), + discard.discard_granularity_bytes, spec->parent_trace); } void operator()(Write& write) const { ImageRequest::aio_write( - &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents), - std::move(write.bl), spec->m_op_flags, spec->m_parent_trace); + &spec->m_image_ctx, spec->aio_comp, std::move(spec->image_extents), + std::move(write.bl), spec->op_flags, spec->parent_trace); } void operator()(WriteSame& write_same) const { ImageRequest::aio_writesame( - &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents), - std::move(write_same.bl), spec->m_op_flags, spec->m_parent_trace); + &spec->m_image_ctx, spec->aio_comp, std::move(spec->image_extents), + std::move(write_same.bl), spec->op_flags, spec->parent_trace); } void operator()(CompareAndWrite& compare_and_write) const { ImageRequest::aio_compare_and_write( - &spec->m_image_ctx, spec->m_aio_comp, std::move(spec->m_image_extents), + &spec->m_image_ctx, spec->aio_comp, std::move(spec->image_extents), std::move(compare_and_write.cmp_bl), std::move(compare_and_write.bl), - compare_and_write.mismatch_offset, spec->m_op_flags, - spec->m_parent_trace); + compare_and_write.mismatch_offset, spec->op_flags, + spec->parent_trace); } void operator()(Flush& flush) const { ImageRequest::aio_flush( - &spec->m_image_ctx, spec->m_aio_comp, flush.flush_source, - spec->m_parent_trace); + &spec->m_image_ctx, spec->aio_comp, flush.flush_source, + spec->parent_trace); } }; @@ -144,7 +145,7 @@ struct ImageDispatchSpec::TokenRequestedVisitor template void ImageDispatchSpec::send() { - boost::apply_visitor(SendVisitor{this}, m_request); + boost::apply_visitor(SendVisitor{this}, request); } template @@ -154,13 +155,13 @@ void ImageDispatchSpec::finish(int r) { template void ImageDispatchSpec::fail(int r) { - m_aio_comp->fail(r); + aio_comp->fail(r); } template uint64_t ImageDispatchSpec::extents_length() { uint64_t length = 0; - auto &extents = this->m_image_extents; + auto &extents = this->image_extents; for (auto &extent : extents) { length += extent.second; @@ -170,28 +171,28 @@ uint64_t ImageDispatchSpec::extents_length() { template const Extents& ImageDispatchSpec::get_image_extents() const { - return this->m_image_extents; + return this->image_extents; } template uint64_t ImageDispatchSpec::get_tid() { - return this->m_tid; + return this->tid; } template bool ImageDispatchSpec::is_write_op() const { - return boost::apply_visitor(IsWriteOpVisitor(), m_request); + return boost::apply_visitor(IsWriteOpVisitor(), request); } template bool ImageDispatchSpec::tokens_requested(uint64_t flag, uint64_t *tokens) { return boost::apply_visitor(TokenRequestedVisitor{this, flag, tokens}, - m_request); + request); } template void ImageDispatchSpec::start_op() { - m_aio_comp->start_op(); + aio_comp->start_op(); } } // namespace io diff --git a/src/librbd/io/ImageDispatchSpec.h b/src/librbd/io/ImageDispatchSpec.h index a73b297eefcf5..90eddb616d13c 100644 --- a/src/librbd/io/ImageDispatchSpec.h +++ b/src/librbd/io/ImageDispatchSpec.h @@ -12,6 +12,7 @@ #include "librbd/io/Types.h" #include "librbd/io/ReadResult.h" #include +#include namespace librbd { @@ -19,6 +20,8 @@ class ImageCtx; namespace io { +struct ImageDispatcherInterface; + template class ImageDispatchSpec { private: @@ -83,10 +86,28 @@ public: } }; + typedef boost::variant Request; + C_Dispatcher dispatcher_ctx; + + ImageDispatcherInterface* image_dispatcher; ImageDispatchLayer dispatch_layer; + std::atomic image_dispatch_flags = 0; DispatchResult dispatch_result = DISPATCH_RESULT_INVALID; + AioCompletion* aio_comp; + Extents image_extents; + Request request; + int op_flags; + ZTracer::Trace parent_trace; + uint64_t tid; + std::atomic throttled_flag = 0; + static ImageDispatchSpec* create_read_request( ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer, AioCompletion *aio_comp, Extents &&image_extents, @@ -151,7 +172,7 @@ public: } ~ImageDispatchSpec() { - m_aio_comp->put(); + aio_comp->put(); } void send(); @@ -164,34 +185,27 @@ public: bool tokens_requested(uint64_t flag, uint64_t *tokens); bool was_throttled(uint64_t flag) { - return m_throttled_flag & flag; + return throttled_flag & flag; } void set_throttled(uint64_t flag) { - m_throttled_flag |= flag; + throttled_flag |= flag; } bool were_all_throttled() { - return (m_throttled_flag & RBD_QOS_MASK) == RBD_QOS_MASK; + return (throttled_flag & RBD_QOS_MASK) == RBD_QOS_MASK; } const Extents& get_image_extents() const; AioCompletion* get_aio_completion() const { - return m_aio_comp; + return aio_comp; } uint64_t get_tid(); bool blocked = false; private: - typedef boost::variant Request; - struct SendVisitor; struct IsWriteOpVisitor; struct TokenRequestedVisitor; @@ -202,20 +216,13 @@ private: Request&& request, int op_flags, const ZTracer::Trace& parent_trace, uint64_t tid) : dispatcher_ctx(this), dispatch_layer(image_dispatch_layer), - m_image_ctx(image_ctx), m_aio_comp(aio_comp), - m_image_extents(std::move(image_extents)), m_request(std::move(request)), - m_op_flags(op_flags), m_parent_trace(parent_trace), m_tid(tid) { - m_aio_comp->get(); + aio_comp(aio_comp), image_extents(std::move(image_extents)), + request(std::move(request)), op_flags(op_flags), + parent_trace(parent_trace), tid(tid), m_image_ctx(image_ctx) { + aio_comp->get(); } ImageCtxT& m_image_ctx; - AioCompletion* m_aio_comp; - Extents m_image_extents; - Request m_request; - int m_op_flags; - ZTracer::Trace m_parent_trace; - uint64_t m_tid; - std::atomic m_throttled_flag = 0; void finish(int r); diff --git a/src/librbd/io/ImageDispatcher.cc b/src/librbd/io/ImageDispatcher.cc new file mode 100644 index 0000000000000..19fdd295ac79d --- /dev/null +++ b/src/librbd/io/ImageDispatcher.cc @@ -0,0 +1,120 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "librbd/io/ImageDispatcher.h" +#include "include/Context.h" +#include "common/AsyncOpTracker.h" +#include "common/dout.h" +#include "common/WorkQueue.h" +#include "librbd/ImageCtx.h" +#include "librbd/Utils.h" +#include "librbd/io/ImageDispatch.h" +#include "librbd/io/ImageDispatchInterface.h" +#include "librbd/io/ImageDispatchSpec.h" +#include + +#define dout_subsys ceph_subsys_rbd +#undef dout_prefix +#define dout_prefix *_dout << "librbd::io::ImageDispatcher: " << this \ + << " " << __func__ << ": " + +namespace librbd { +namespace io { + +template +struct ImageDispatcher::SendVisitor : public boost::static_visitor { + ImageDispatchInterface* image_dispatch; + ImageDispatchSpec* image_dispatch_spec; + + SendVisitor(ImageDispatchInterface* image_dispatch, + ImageDispatchSpec* image_dispatch_spec) + : image_dispatch(image_dispatch), + image_dispatch_spec(image_dispatch_spec) { + } + + bool operator()(typename ImageDispatchSpec::Read& read) const { + return image_dispatch->read( + image_dispatch_spec->aio_comp, + std::move(image_dispatch_spec->image_extents), + std::move(read.read_result), image_dispatch_spec->op_flags, + image_dispatch_spec->parent_trace, image_dispatch_spec->tid, + &image_dispatch_spec->image_dispatch_flags, + &image_dispatch_spec->dispatch_result, + &image_dispatch_spec->dispatcher_ctx); + } + + bool operator()(typename ImageDispatchSpec::Discard& discard) const { + return image_dispatch->discard( + image_dispatch_spec->aio_comp, + std::move(image_dispatch_spec->image_extents), + discard.discard_granularity_bytes, + image_dispatch_spec->parent_trace, image_dispatch_spec->tid, + &image_dispatch_spec->image_dispatch_flags, + &image_dispatch_spec->dispatch_result, + &image_dispatch_spec->dispatcher_ctx); + } + + bool operator()(typename ImageDispatchSpec::Write& write) const { + return image_dispatch->write( + image_dispatch_spec->aio_comp, + std::move(image_dispatch_spec->image_extents), std::move(write.bl), + image_dispatch_spec->op_flags, image_dispatch_spec->parent_trace, + image_dispatch_spec->tid, &image_dispatch_spec->image_dispatch_flags, + &image_dispatch_spec->dispatch_result, + &image_dispatch_spec->dispatcher_ctx); + } + + bool operator()(typename ImageDispatchSpec::WriteSame& write_same) const { + return image_dispatch->write_same( + image_dispatch_spec->aio_comp, + std::move(image_dispatch_spec->image_extents), std::move(write_same.bl), + image_dispatch_spec->op_flags, image_dispatch_spec->parent_trace, + image_dispatch_spec->tid, &image_dispatch_spec->image_dispatch_flags, + &image_dispatch_spec->dispatch_result, + &image_dispatch_spec->dispatcher_ctx); + } + + bool operator()( + typename ImageDispatchSpec::CompareAndWrite& compare_and_write) const { + return image_dispatch->compare_and_write( + image_dispatch_spec->aio_comp, + std::move(image_dispatch_spec->image_extents), + std::move(compare_and_write.cmp_bl), std::move(compare_and_write.bl), + compare_and_write.mismatch_offset, image_dispatch_spec->op_flags, + image_dispatch_spec->parent_trace, image_dispatch_spec->tid, + &image_dispatch_spec->image_dispatch_flags, + &image_dispatch_spec->dispatch_result, + &image_dispatch_spec->dispatcher_ctx); + } + + bool operator()(typename ImageDispatchSpec::Flush& flush) const { + return image_dispatch->flush( + image_dispatch_spec->aio_comp, flush.flush_source, + image_dispatch_spec->parent_trace, image_dispatch_spec->tid, + &image_dispatch_spec->image_dispatch_flags, + &image_dispatch_spec->dispatch_result, + &image_dispatch_spec->dispatcher_ctx); + } +}; + +template +ImageDispatcher::ImageDispatcher(I* image_ctx) + : Dispatcher(image_ctx) { + // configure the core image dispatch handler on startup + auto image_dispatch = new ImageDispatch(image_ctx); + this->register_dispatch(image_dispatch); +} + +template +bool ImageDispatcher::send_dispatch( + ImageDispatchInterface* image_dispatch, + ImageDispatchSpec* image_dispatch_spec) { + return boost::apply_visitor( + SendVisitor{image_dispatch, image_dispatch_spec}, + image_dispatch_spec->request); +} + +} // namespace io +} // namespace librbd + +template class librbd::io::ImageDispatcher; diff --git a/src/librbd/io/ImageDispatcher.h b/src/librbd/io/ImageDispatcher.h new file mode 100644 index 0000000000000..1516a76daed62 --- /dev/null +++ b/src/librbd/io/ImageDispatcher.h @@ -0,0 +1,44 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_IO_IMAGE_DISPATCHER_H +#define CEPH_LIBRBD_IO_IMAGE_DISPATCHER_H + +#include "include/int_types.h" +#include "common/ceph_mutex.h" +#include "librbd/io/Dispatcher.h" +#include "librbd/io/ImageDispatchInterface.h" +#include "librbd/io/ImageDispatchSpec.h" +#include "librbd/io/ImageDispatcherInterface.h" +#include "librbd/io/Types.h" +#include + +struct Context; + +namespace librbd { + +struct ImageCtx; + +namespace io { + +template +class ImageDispatcher : public Dispatcher { +public: + ImageDispatcher(ImageCtxT* image_ctx); + +protected: + bool send_dispatch( + ImageDispatchInterface* object_dispatch, + ImageDispatchSpec* object_dispatch_spec) override; + +private: + struct SendVisitor; + +}; + +} // namespace io +} // namespace librbd + +extern template class librbd::io::ImageDispatcher; + +#endif // CEPH_LIBRBD_IO_IMAGE_DISPATCHER_H diff --git a/src/librbd/io/ImageDispatcherInterface.h b/src/librbd/io/ImageDispatcherInterface.h new file mode 100644 index 0000000000000..7628def5ddffd --- /dev/null +++ b/src/librbd/io/ImageDispatcherInterface.h @@ -0,0 +1,24 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_IO_IMAGE_DISPATCHER_INTERFACE_H +#define CEPH_LIBRBD_IO_IMAGE_DISPATCHER_INTERFACE_H + +#include "include/int_types.h" +#include "librbd/io/DispatcherInterface.h" +#include "librbd/io/ImageDispatchInterface.h" + +struct Context; + +namespace librbd { +namespace io { + +struct ImageDispatcherInterface + : public DispatcherInterface { +public: +}; + +} // namespace io +} // namespace librbd + +#endif // CEPH_LIBRBD_IO_IMAGE_DISPATCHER_INTERFACE_H