From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/librbd/io/ObjectDispatchSpec.h | 295 +++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 src/librbd/io/ObjectDispatchSpec.h (limited to 'src/librbd/io/ObjectDispatchSpec.h') diff --git a/src/librbd/io/ObjectDispatchSpec.h b/src/librbd/io/ObjectDispatchSpec.h new file mode 100644 index 000000000..a0d4b49a4 --- /dev/null +++ b/src/librbd/io/ObjectDispatchSpec.h @@ -0,0 +1,295 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_LIBRBD_IO_OBJECT_DISPATCH_SPEC_H +#define CEPH_LIBRBD_IO_OBJECT_DISPATCH_SPEC_H + +#include "include/int_types.h" +#include "include/buffer.h" +#include "include/Context.h" +#include "include/rados/librados.hpp" +#include "common/zipkin_trace.h" +#include "librbd/Types.h" +#include "librbd/io/Types.h" +#include + +namespace librbd { +namespace io { + +struct ObjectDispatcherInterface; + +struct ObjectDispatchSpec { +private: + // helper to avoid extra heap allocation per object IO + struct C_Dispatcher : public Context { + ObjectDispatchSpec* object_dispatch_spec; + Context* on_finish; + + C_Dispatcher(ObjectDispatchSpec* object_dispatch_spec, Context* on_finish) + : object_dispatch_spec(object_dispatch_spec), on_finish(on_finish) { + } + + void complete(int r) override; + void finish(int r) override; + }; + +public: + struct RequestBase { + uint64_t object_no; + + RequestBase(uint64_t object_no) + : object_no(object_no) { + } + }; + + struct ReadRequest : public RequestBase { + ReadExtents* extents; + int read_flags; + uint64_t* version; + + ReadRequest(uint64_t object_no, ReadExtents* extents, int read_flags, + uint64_t* version) + : RequestBase(object_no), extents(extents), read_flags(read_flags), + version(version) { + } + }; + + struct WriteRequestBase : public RequestBase { + uint64_t object_off; + uint64_t journal_tid; + + WriteRequestBase(uint64_t object_no, uint64_t object_off, + uint64_t journal_tid) + : RequestBase(object_no), object_off(object_off), + journal_tid(journal_tid) { + } + }; + + struct DiscardRequest : public WriteRequestBase { + uint64_t object_len; + int discard_flags; + + DiscardRequest(uint64_t object_no, uint64_t object_off, uint64_t object_len, + int discard_flags, uint64_t journal_tid) + : WriteRequestBase(object_no, object_off, journal_tid), + object_len(object_len), discard_flags(discard_flags) { + } + }; + + struct WriteRequest : public WriteRequestBase { + ceph::bufferlist data; + int write_flags; + std::optional assert_version; + + WriteRequest(uint64_t object_no, uint64_t object_off, + ceph::bufferlist&& data, int write_flags, + std::optional assert_version, uint64_t journal_tid) + : WriteRequestBase(object_no, object_off, journal_tid), + data(std::move(data)), write_flags(write_flags), + assert_version(assert_version) { + } + }; + + struct WriteSameRequest : public WriteRequestBase { + uint64_t object_len; + LightweightBufferExtents buffer_extents; + ceph::bufferlist data; + + WriteSameRequest(uint64_t object_no, uint64_t object_off, + uint64_t object_len, + LightweightBufferExtents&& buffer_extents, + ceph::bufferlist&& data, uint64_t journal_tid) + : WriteRequestBase(object_no, object_off, journal_tid), + object_len(object_len), buffer_extents(std::move(buffer_extents)), + data(std::move(data)) { + } + }; + + struct CompareAndWriteRequest : public WriteRequestBase { + ceph::bufferlist cmp_data; + ceph::bufferlist data; + uint64_t* mismatch_offset; + + CompareAndWriteRequest(uint64_t object_no, uint64_t object_off, + ceph::bufferlist&& cmp_data, ceph::bufferlist&& data, + uint64_t* mismatch_offset, + uint64_t journal_tid) + : WriteRequestBase(object_no, object_off, journal_tid), + cmp_data(std::move(cmp_data)), data(std::move(data)), + mismatch_offset(mismatch_offset) { + } + }; + + struct FlushRequest { + FlushSource flush_source; + uint64_t journal_tid; + + FlushRequest(FlushSource flush_source, uint64_t journal_tid) + : flush_source(flush_source), journal_tid(journal_tid) { + } + }; + + struct ListSnapsRequest : public RequestBase { + Extents extents; + SnapIds snap_ids; + int list_snaps_flags; + SnapshotDelta* snapshot_delta; + + ListSnapsRequest(uint64_t object_no, Extents&& extents, + SnapIds&& snap_ids, int list_snaps_flags, + SnapshotDelta* snapshot_delta) + : RequestBase(object_no), extents(std::move(extents)), + snap_ids(std::move(snap_ids)),list_snaps_flags(list_snaps_flags), + snapshot_delta(snapshot_delta) { + } + }; + + typedef boost::variant Request; + + C_Dispatcher dispatcher_ctx; + + ObjectDispatcherInterface* object_dispatcher; + ObjectDispatchLayer dispatch_layer; + int object_dispatch_flags = 0; + DispatchResult dispatch_result = DISPATCH_RESULT_INVALID; + + Request request; + IOContext io_context; + int op_flags; + ZTracer::Trace parent_trace; + + template + static ObjectDispatchSpec* create_read( + ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer, + uint64_t object_no, ReadExtents* extents, IOContext io_context, + int op_flags, int read_flags, const ZTracer::Trace &parent_trace, + uint64_t* version, Context* on_finish) { + return new ObjectDispatchSpec(image_ctx->io_object_dispatcher, + object_dispatch_layer, + ReadRequest{object_no, extents, + read_flags, version}, + io_context, op_flags, parent_trace, + on_finish); + } + + template + static ObjectDispatchSpec* create_discard( + ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer, + uint64_t object_no, uint64_t object_off, uint64_t object_len, + IOContext io_context, int discard_flags, uint64_t journal_tid, + const ZTracer::Trace &parent_trace, Context *on_finish) { + return new ObjectDispatchSpec(image_ctx->io_object_dispatcher, + object_dispatch_layer, + DiscardRequest{object_no, object_off, + object_len, discard_flags, + journal_tid}, + io_context, 0, parent_trace, on_finish); + } + + template + static ObjectDispatchSpec* create_write( + ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer, + uint64_t object_no, uint64_t object_off, ceph::bufferlist&& data, + IOContext io_context, int op_flags, int write_flags, + std::optional assert_version, uint64_t journal_tid, + const ZTracer::Trace &parent_trace, Context *on_finish) { + return new ObjectDispatchSpec(image_ctx->io_object_dispatcher, + object_dispatch_layer, + WriteRequest{object_no, object_off, + std::move(data), write_flags, + assert_version, journal_tid}, + io_context, op_flags, parent_trace, + on_finish); + } + + template + static ObjectDispatchSpec* create_write_same( + ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer, + uint64_t object_no, uint64_t object_off, uint64_t object_len, + LightweightBufferExtents&& buffer_extents, ceph::bufferlist&& data, + IOContext io_context, int op_flags, uint64_t journal_tid, + const ZTracer::Trace &parent_trace, Context *on_finish) { + return new ObjectDispatchSpec(image_ctx->io_object_dispatcher, + object_dispatch_layer, + WriteSameRequest{object_no, object_off, + object_len, + std::move(buffer_extents), + std::move(data), + journal_tid}, + io_context, op_flags, parent_trace, + on_finish); + } + + template + static ObjectDispatchSpec* create_compare_and_write( + ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer, + uint64_t object_no, uint64_t object_off, ceph::bufferlist&& cmp_data, + ceph::bufferlist&& write_data, IOContext io_context, + uint64_t *mismatch_offset, int op_flags, uint64_t journal_tid, + const ZTracer::Trace &parent_trace, Context *on_finish) { + return new ObjectDispatchSpec(image_ctx->io_object_dispatcher, + object_dispatch_layer, + CompareAndWriteRequest{object_no, + object_off, + std::move(cmp_data), + std::move(write_data), + mismatch_offset, + journal_tid}, + io_context, op_flags, parent_trace, + on_finish); + } + + template + static ObjectDispatchSpec* create_flush( + ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer, + FlushSource flush_source, uint64_t journal_tid, + const ZTracer::Trace &parent_trace, Context *on_finish) { + return new ObjectDispatchSpec(image_ctx->io_object_dispatcher, + object_dispatch_layer, + FlushRequest{flush_source, journal_tid}, + {}, 0, parent_trace, on_finish); + } + + template + static ObjectDispatchSpec* create_list_snaps( + ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer, + uint64_t object_no, Extents&& extents, SnapIds&& snap_ids, + int list_snaps_flags, const ZTracer::Trace &parent_trace, + SnapshotDelta* snapshot_delta, Context* on_finish) { + return new ObjectDispatchSpec(image_ctx->io_object_dispatcher, + object_dispatch_layer, + ListSnapsRequest{object_no, + std::move(extents), + std::move(snap_ids), + list_snaps_flags, + snapshot_delta}, + {}, 0, parent_trace, on_finish); + } + + void send(); + void fail(int r); + +private: + template friend class ObjectDispatcher; + + ObjectDispatchSpec(ObjectDispatcherInterface* object_dispatcher, + ObjectDispatchLayer object_dispatch_layer, + Request&& request, IOContext io_context, int op_flags, + const ZTracer::Trace& parent_trace, Context* on_finish) + : dispatcher_ctx(this, on_finish), object_dispatcher(object_dispatcher), + dispatch_layer(object_dispatch_layer), request(std::move(request)), + io_context(io_context), op_flags(op_flags), parent_trace(parent_trace) { + } + +}; + +} // namespace io +} // namespace librbd + +#endif // CEPH_LIBRBD_IO_OBJECT_DISPATCH_SPEC_H -- cgit v1.2.3