X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Flibrbd%2Fio%2FImageRequest.h;fp=src%2Fceph%2Fsrc%2Flibrbd%2Fio%2FImageRequest.h;h=9d707a3f8f5f83967d5de46d33eaff54ab2e9a5c;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/librbd/io/ImageRequest.h b/src/ceph/src/librbd/io/ImageRequest.h new file mode 100644 index 0000000..9d707a3 --- /dev/null +++ b/src/ceph/src/librbd/io/ImageRequest.h @@ -0,0 +1,429 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_IO_IMAGE_REQUEST_H +#define CEPH_LIBRBD_IO_IMAGE_REQUEST_H + +#include "include/int_types.h" +#include "include/buffer_fwd.h" +#include "common/snap_types.h" +#include "common/zipkin_trace.h" +#include "osd/osd_types.h" +#include "librbd/Utils.h" +#include "librbd/io/Types.h" +#include +#include +#include + +namespace librbd { +class ImageCtx; + +namespace io { + +class AioCompletion; +class ObjectRequestHandle; +class ReadResult; + +template +class ImageRequest { +public: + typedef std::vector > Extents; + + virtual ~ImageRequest() { + m_trace.event("finish"); + } + + static ImageRequest* create_read_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + Extents &&image_extents, + ReadResult &&read_result, + int op_flags, + const ZTracer::Trace &parent_trace); + static ImageRequest* create_write_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + Extents &&image_extents, + bufferlist &&bl, int op_flags, + const ZTracer::Trace &parent_trace); + static ImageRequest* create_discard_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + uint64_t off, uint64_t len, + bool skip_partial_discard, + const ZTracer::Trace &parent_trace); + static ImageRequest* create_flush_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + const ZTracer::Trace &parent_trace); + static ImageRequest* create_writesame_request(ImageCtxT &image_ctx, + AioCompletion *aio_comp, + uint64_t off, uint64_t len, + bufferlist &&bl, int op_flags, + const ZTracer::Trace &parent_trace); + static ImageRequest* create_compare_and_write_request( + ImageCtxT &image_ctx, AioCompletion *c, Extents &&image_extents, + bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset, + int op_flags, const ZTracer::Trace &parent_trace); + + static void aio_read(ImageCtxT *ictx, AioCompletion *c, + Extents &&image_extents, ReadResult &&read_result, + int op_flags, const ZTracer::Trace &parent_trace); + static void aio_write(ImageCtxT *ictx, AioCompletion *c, + Extents &&image_extents, bufferlist &&bl, int op_flags, + const ZTracer::Trace &parent_trace); + static void aio_discard(ImageCtxT *ictx, AioCompletion *c, uint64_t off, + uint64_t len, bool skip_partial_discard, + const ZTracer::Trace &parent_trace); + static void aio_flush(ImageCtxT *ictx, AioCompletion *c, + const ZTracer::Trace &parent_trace); + static void aio_writesame(ImageCtxT *ictx, AioCompletion *c, uint64_t off, + uint64_t len, bufferlist &&bl, int op_flags, + const ZTracer::Trace &parent_trace); + + static void aio_compare_and_write(ImageCtxT *ictx, AioCompletion *c, + Extents &&image_extents, bufferlist &&cmp_bl, + bufferlist &&bl, uint64_t *mismatch_offset, + int op_flags, const ZTracer::Trace &parent_trace); + + virtual bool is_write_op() const { + return false; + } + + void start_op(); + + void send(); + void fail(int r); + + void set_bypass_image_cache() { + m_bypass_image_cache = true; + } + + inline const ZTracer::Trace &get_trace() const { + return m_trace; + } + +protected: + typedef std::list ObjectRequests; + + ImageCtxT &m_image_ctx; + AioCompletion *m_aio_comp; + Extents m_image_extents; + ZTracer::Trace m_trace; + bool m_bypass_image_cache = false; + + ImageRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, + Extents &&image_extents, const char *trace_name, + const ZTracer::Trace &parent_trace) + : m_image_ctx(image_ctx), m_aio_comp(aio_comp), + m_image_extents(std::move(image_extents)), + m_trace(util::create_trace(image_ctx, trace_name, parent_trace)) { + m_trace.event("start"); + } + + + virtual int clip_request(); + virtual void send_request() = 0; + virtual void send_image_cache_request() = 0; + + virtual aio_type_t get_aio_type() const = 0; + virtual const char *get_request_type() const = 0; +}; + +template +class ImageReadRequest : public ImageRequest { +public: + using typename ImageRequest::Extents; + + ImageReadRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, + Extents &&image_extents, ReadResult &&read_result, + int op_flags, const ZTracer::Trace &parent_trace); + +protected: + int clip_request() override; + + void send_request() override; + void send_image_cache_request() override; + + aio_type_t get_aio_type() const override { + return AIO_TYPE_READ; + } + const char *get_request_type() const override { + return "aio_read"; + } +private: + char *m_buf; + bufferlist *m_pbl; + int m_op_flags; +}; + +template +class AbstractImageWriteRequest : public ImageRequest { +public: + bool is_write_op() const override { + return true; + } + + inline void flag_synchronous() { + m_synchronous = true; + } + +protected: + using typename ImageRequest::ObjectRequests; + using typename ImageRequest::Extents; + + typedef std::vector ObjectExtents; + + AbstractImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, + Extents &&image_extents, const char *trace_name, + const ZTracer::Trace &parent_trace) + : ImageRequest(image_ctx, aio_comp, std::move(image_extents), + trace_name, parent_trace), + m_synchronous(false) { + } + + void send_request() override; + + virtual int prune_object_extents(ObjectExtents &object_extents) { + return 0; + } + virtual uint32_t get_object_cache_request_count(bool journaling) const { + return 0; + } + virtual void send_object_cache_requests(const ObjectExtents &object_extents, + uint64_t journal_tid) = 0; + + virtual void send_object_requests(const ObjectExtents &object_extents, + const ::SnapContext &snapc, + ObjectRequests *object_requests); + virtual ObjectRequestHandle *create_object_request( + const ObjectExtent &object_extent, const ::SnapContext &snapc, + Context *on_finish) = 0; + + virtual uint64_t append_journal_event(const ObjectRequests &requests, + bool synchronous) = 0; + virtual void update_stats(size_t length) = 0; + +private: + bool m_synchronous; +}; + +template +class ImageWriteRequest : public AbstractImageWriteRequest { +public: + using typename ImageRequest::Extents; + + ImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, + Extents &&image_extents, bufferlist &&bl, int op_flags, + const ZTracer::Trace &parent_trace) + : AbstractImageWriteRequest( + image_ctx, aio_comp, std::move(image_extents), "write", parent_trace), + m_bl(std::move(bl)), m_op_flags(op_flags) { + } + +protected: + using typename ImageRequest::ObjectRequests; + using typename AbstractImageWriteRequest::ObjectExtents; + + aio_type_t get_aio_type() const override { + return AIO_TYPE_WRITE; + } + const char *get_request_type() const override { + return "aio_write"; + } + + void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl); + + void send_image_cache_request() override; + + void send_object_cache_requests(const ObjectExtents &object_extents, + uint64_t journal_tid) override; + + void send_object_requests(const ObjectExtents &object_extents, + const ::SnapContext &snapc, + ObjectRequests *aio_object_requests) override; + + ObjectRequestHandle *create_object_request( + const ObjectExtent &object_extent, const ::SnapContext &snapc, + Context *on_finish) override; + + uint64_t append_journal_event(const ObjectRequests &requests, + bool synchronous) override; + void update_stats(size_t length) override; + +private: + bufferlist m_bl; + int m_op_flags; +}; + +template +class ImageDiscardRequest : public AbstractImageWriteRequest { +public: + ImageDiscardRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, + uint64_t off, uint64_t len, bool skip_partial_discard, + const ZTracer::Trace &parent_trace) + : AbstractImageWriteRequest( + image_ctx, aio_comp, {{off, len}}, "discard", parent_trace), + m_skip_partial_discard(skip_partial_discard) { + } + +protected: + using typename ImageRequest::ObjectRequests; + using typename AbstractImageWriteRequest::ObjectExtents; + + aio_type_t get_aio_type() const override { + return AIO_TYPE_DISCARD; + } + const char *get_request_type() const override { + return "aio_discard"; + } + + int prune_object_extents(ObjectExtents &object_extents) override; + + void send_image_cache_request() override; + + uint32_t get_object_cache_request_count(bool journaling) const override; + void send_object_cache_requests(const ObjectExtents &object_extents, + uint64_t journal_tid) override; + + ObjectRequestHandle *create_object_request( + const ObjectExtent &object_extent, const ::SnapContext &snapc, + Context *on_finish) override; + + uint64_t append_journal_event(const ObjectRequests &requests, + bool synchronous) override; + void update_stats(size_t length) override; +private: + bool m_skip_partial_discard; +}; + +template +class ImageFlushRequest : public ImageRequest { +public: + ImageFlushRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, + const ZTracer::Trace &parent_trace) + : ImageRequest(image_ctx, aio_comp, {}, "flush", parent_trace) { + } + + bool is_write_op() const override { + return true; + } + +protected: + using typename ImageRequest::ObjectRequests; + + int clip_request() override { + return 0; + } + void send_request() override; + void send_image_cache_request() override; + + aio_type_t get_aio_type() const override { + return AIO_TYPE_FLUSH; + } + const char *get_request_type() const override { + return "aio_flush"; + } +}; + +template +class ImageWriteSameRequest : public AbstractImageWriteRequest { +public: + ImageWriteSameRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, + uint64_t off, uint64_t len, bufferlist &&bl, + int op_flags, const ZTracer::Trace &parent_trace) + : AbstractImageWriteRequest( + image_ctx, aio_comp, {{off, len}}, "writesame", parent_trace), + m_data_bl(std::move(bl)), m_op_flags(op_flags) { + } + +protected: + using typename ImageRequest::ObjectRequests; + using typename AbstractImageWriteRequest::ObjectExtents; + + aio_type_t get_aio_type() const override { + return AIO_TYPE_WRITESAME; + } + const char *get_request_type() const override { + return "aio_writesame"; + } + + bool assemble_writesame_extent(const ObjectExtent &object_extent, + bufferlist *bl, bool force_write); + + void send_image_cache_request() override; + + void send_object_cache_requests(const ObjectExtents &object_extents, + uint64_t journal_tid) override; + + void send_object_requests(const ObjectExtents &object_extents, + const ::SnapContext &snapc, + ObjectRequests *object_requests) override; + ObjectRequestHandle *create_object_request( + const ObjectExtent &object_extent, const ::SnapContext &snapc, + Context *on_finish) override; + + uint64_t append_journal_event(const ObjectRequests &requests, + bool synchronous) override; + void update_stats(size_t length) override; +private: + bufferlist m_data_bl; + int m_op_flags; +}; + +template +class ImageCompareAndWriteRequest : public AbstractImageWriteRequest { +public: + using typename ImageRequest::ObjectRequests; + using typename AbstractImageWriteRequest::ObjectExtents; + + ImageCompareAndWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, + Extents &&image_extents, bufferlist &&cmp_bl, + bufferlist &&bl, uint64_t *mismatch_offset, + int op_flags, const ZTracer::Trace &parent_trace) + : AbstractImageWriteRequest( + image_ctx, aio_comp, std::move(image_extents), "compare_and_write", parent_trace), + m_cmp_bl(std::move(cmp_bl)), m_bl(std::move(bl)), + m_mismatch_offset(mismatch_offset), m_op_flags(op_flags) { + } + +protected: + void send_image_cache_request() override; + + void send_object_cache_requests(const ObjectExtents &object_extents, + uint64_t journal_tid) override; + + void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl); + + ObjectRequestHandle *create_object_request(const ObjectExtent &object_extent, + const ::SnapContext &snapc, + Context *on_finish) override; + + uint64_t append_journal_event(const ObjectRequests &requests, + bool synchronous) override; + void update_stats(size_t length) override; + + aio_type_t get_aio_type() const override { + return AIO_TYPE_COMPARE_AND_WRITE; + } + const char *get_request_type() const override { + return "aio_compare_and_write"; + } + + int prune_object_extents(ObjectExtents &object_extents) override; +private: + bufferlist m_cmp_bl; + bufferlist m_bl; + uint64_t *m_mismatch_offset; + int m_op_flags; +}; + +} // namespace io +} // namespace librbd + +extern template class librbd::io::ImageRequest; +extern template class librbd::io::ImageReadRequest; +extern template class librbd::io::AbstractImageWriteRequest; +extern template class librbd::io::ImageWriteRequest; +extern template class librbd::io::ImageDiscardRequest; +extern template class librbd::io::ImageFlushRequest; +extern template class librbd::io::ImageWriteSameRequest; +extern template class librbd::io::ImageCompareAndWriteRequest; + +#endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_H