]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/ObjectDispatchSpec.h
Import ceph 15.2.8
[ceph.git] / ceph / src / librbd / io / ObjectDispatchSpec.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_LIBRBD_IO_OBJECT_DISPATCH_SPEC_H
5 #define CEPH_LIBRBD_IO_OBJECT_DISPATCH_SPEC_H
6
7 #include "include/int_types.h"
8 #include "include/buffer.h"
9 #include "include/Context.h"
10 #include "include/rados/librados.hpp"
11 #include "common/snap_types.h"
12 #include "common/zipkin_trace.h"
13 #include "librbd/io/Types.h"
14 #include <boost/variant/variant.hpp>
15
16 namespace librbd {
17 namespace io {
18
19 struct ObjectDispatcherInterface;
20
21 struct ObjectDispatchSpec {
22 private:
23 // helper to avoid extra heap allocation per object IO
24 struct C_Dispatcher : public Context {
25 ObjectDispatchSpec* object_dispatch_spec;
26 Context* on_finish;
27
28 C_Dispatcher(ObjectDispatchSpec* object_dispatch_spec, Context* on_finish)
29 : object_dispatch_spec(object_dispatch_spec), on_finish(on_finish) {
30 }
31
32 void complete(int r) override;
33 void finish(int r) override;
34 };
35
36 public:
37 struct RequestBase {
38 uint64_t object_no;
39 uint64_t object_off;
40
41 RequestBase(uint64_t object_no, uint64_t object_off)
42 : object_no(object_no), object_off(object_off) {
43 }
44 };
45
46 struct ReadRequest : public RequestBase {
47 uint64_t object_len;
48 librados::snap_t snap_id;
49 ceph::bufferlist* read_data;
50 ExtentMap* extent_map;
51
52 ReadRequest(uint64_t object_no, uint64_t object_off, uint64_t object_len,
53 librados::snap_t snap_id, ceph::bufferlist* read_data,
54 ExtentMap* extent_map)
55 : RequestBase(object_no, object_off),
56 object_len(object_len), snap_id(snap_id), read_data(read_data),
57 extent_map(extent_map) {
58 }
59 };
60
61 struct WriteRequestBase : public RequestBase {
62 ::SnapContext snapc;
63 uint64_t journal_tid;
64
65 WriteRequestBase(uint64_t object_no, uint64_t object_off,
66 const ::SnapContext& snapc, uint64_t journal_tid)
67 : RequestBase(object_no, object_off), snapc(snapc),
68 journal_tid(journal_tid) {
69 }
70 };
71
72 struct DiscardRequest : public WriteRequestBase {
73 uint64_t object_len;
74 int discard_flags;
75
76 DiscardRequest(uint64_t object_no, uint64_t object_off, uint64_t object_len,
77 int discard_flags, const ::SnapContext& snapc,
78 uint64_t journal_tid)
79 : WriteRequestBase(object_no, object_off, snapc, journal_tid),
80 object_len(object_len), discard_flags(discard_flags) {
81 }
82 };
83
84 struct WriteRequest : public WriteRequestBase {
85 ceph::bufferlist data;
86
87 WriteRequest(uint64_t object_no, uint64_t object_off,
88 ceph::bufferlist&& data, const ::SnapContext& snapc,
89 uint64_t journal_tid)
90 : WriteRequestBase(object_no, object_off, snapc, journal_tid),
91 data(std::move(data)) {
92 }
93 };
94
95 struct WriteSameRequest : public WriteRequestBase {
96 uint64_t object_len;
97 LightweightBufferExtents buffer_extents;
98 ceph::bufferlist data;
99
100 WriteSameRequest(uint64_t object_no, uint64_t object_off,
101 uint64_t object_len,
102 LightweightBufferExtents&& buffer_extents,
103 ceph::bufferlist&& data, const ::SnapContext& snapc,
104 uint64_t journal_tid)
105 : WriteRequestBase(object_no, object_off, snapc, journal_tid),
106 object_len(object_len), buffer_extents(std::move(buffer_extents)),
107 data(std::move(data)) {
108 }
109 };
110
111 struct CompareAndWriteRequest : public WriteRequestBase {
112 ceph::bufferlist cmp_data;
113 ceph::bufferlist data;
114 uint64_t* mismatch_offset;
115
116 CompareAndWriteRequest(uint64_t object_no, uint64_t object_off,
117 ceph::bufferlist&& cmp_data, ceph::bufferlist&& data,
118 uint64_t* mismatch_offset,
119 const ::SnapContext& snapc, uint64_t journal_tid)
120 : WriteRequestBase(object_no, object_off, snapc, journal_tid),
121 cmp_data(std::move(cmp_data)), data(std::move(data)),
122 mismatch_offset(mismatch_offset) {
123 }
124 };
125
126 struct FlushRequest {
127 FlushSource flush_source;
128 uint64_t journal_tid;
129
130 FlushRequest(FlushSource flush_source, uint64_t journal_tid)
131 : flush_source(flush_source), journal_tid(journal_tid) {
132 }
133 };
134
135 typedef boost::variant<ReadRequest,
136 DiscardRequest,
137 WriteRequest,
138 WriteSameRequest,
139 CompareAndWriteRequest,
140 FlushRequest> Request;
141
142 C_Dispatcher dispatcher_ctx;
143
144 ObjectDispatcherInterface* object_dispatcher;
145 ObjectDispatchLayer object_dispatch_layer;
146 int object_dispatch_flags = 0;
147 DispatchResult dispatch_result = DISPATCH_RESULT_INVALID;
148
149 Request request;
150 int op_flags;
151 ZTracer::Trace parent_trace;
152
153 template <typename ImageCtxT>
154 static ObjectDispatchSpec* create_read(
155 ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
156 uint64_t object_no, uint64_t object_off, uint64_t object_len,
157 librados::snap_t snap_id, int op_flags,
158 const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data,
159 ExtentMap* extent_map, Context* on_finish) {
160 return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
161 object_dispatch_layer,
162 ReadRequest{object_no, object_off,
163 object_len, snap_id, read_data,
164 extent_map},
165 op_flags, parent_trace, on_finish);
166 }
167
168 template <typename ImageCtxT>
169 static ObjectDispatchSpec* create_discard(
170 ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
171 uint64_t object_no, uint64_t object_off, uint64_t object_len,
172 const ::SnapContext &snapc, int discard_flags, uint64_t journal_tid,
173 const ZTracer::Trace &parent_trace, Context *on_finish) {
174 return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
175 object_dispatch_layer,
176 DiscardRequest{object_no, object_off,
177 object_len, discard_flags,
178 snapc, journal_tid},
179 0, parent_trace, on_finish);
180 }
181
182 template <typename ImageCtxT>
183 static ObjectDispatchSpec* create_write(
184 ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
185 uint64_t object_no, uint64_t object_off, ceph::bufferlist&& data,
186 const ::SnapContext &snapc, int op_flags, uint64_t journal_tid,
187 const ZTracer::Trace &parent_trace, Context *on_finish) {
188 return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
189 object_dispatch_layer,
190 WriteRequest{object_no, object_off,
191 std::move(data), snapc,
192 journal_tid},
193 op_flags, parent_trace, on_finish);
194 }
195
196 template <typename ImageCtxT>
197 static ObjectDispatchSpec* create_write_same(
198 ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
199 uint64_t object_no, uint64_t object_off, uint64_t object_len,
200 LightweightBufferExtents&& buffer_extents, ceph::bufferlist&& data,
201 const ::SnapContext &snapc, int op_flags, uint64_t journal_tid,
202 const ZTracer::Trace &parent_trace, Context *on_finish) {
203 return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
204 object_dispatch_layer,
205 WriteSameRequest{object_no, object_off,
206 object_len,
207 std::move(buffer_extents),
208 std::move(data), snapc,
209 journal_tid},
210 op_flags, parent_trace, on_finish);
211 }
212
213 template <typename ImageCtxT>
214 static ObjectDispatchSpec* create_compare_and_write(
215 ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
216 uint64_t object_no, uint64_t object_off, ceph::bufferlist&& cmp_data,
217 ceph::bufferlist&& write_data, const ::SnapContext &snapc,
218 uint64_t *mismatch_offset, int op_flags, uint64_t journal_tid,
219 const ZTracer::Trace &parent_trace, Context *on_finish) {
220 return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
221 object_dispatch_layer,
222 CompareAndWriteRequest{object_no,
223 object_off,
224 std::move(cmp_data),
225 std::move(write_data),
226 mismatch_offset,
227 snapc, journal_tid},
228 op_flags, parent_trace, on_finish);
229 }
230
231 template <typename ImageCtxT>
232 static ObjectDispatchSpec* create_flush(
233 ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
234 FlushSource flush_source, uint64_t journal_tid,
235 const ZTracer::Trace &parent_trace, Context *on_finish) {
236 return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
237 object_dispatch_layer,
238 FlushRequest{flush_source, journal_tid}, 0,
239 parent_trace, on_finish);
240 }
241
242 void send();
243 void fail(int r);
244
245 private:
246 template <typename> friend class ObjectDispatcher;
247
248 ObjectDispatchSpec(ObjectDispatcherInterface* object_dispatcher,
249 ObjectDispatchLayer object_dispatch_layer,
250 Request&& request, int op_flags,
251 const ZTracer::Trace& parent_trace, Context* on_finish)
252 : dispatcher_ctx(this, on_finish), object_dispatcher(object_dispatcher),
253 object_dispatch_layer(object_dispatch_layer), request(std::move(request)),
254 op_flags(op_flags), parent_trace(parent_trace) {
255 }
256
257 };
258
259 } // namespace io
260 } // namespace librbd
261
262 #endif // CEPH_LIBRBD_IO_OBJECT_DISPATCH_SPEC_H