]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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_IMAGE_REQUEST_H | |
5 | #define CEPH_LIBRBD_IO_IMAGE_REQUEST_H | |
6 | ||
7 | #include "include/int_types.h" | |
8 | #include "include/buffer_fwd.h" | |
31f18b77 | 9 | #include "common/zipkin_trace.h" |
7c673cae | 10 | #include "osd/osd_types.h" |
31f18b77 | 11 | #include "librbd/Utils.h" |
f67539c2 | 12 | #include "librbd/Types.h" |
7c673cae FG |
13 | #include "librbd/io/Types.h" |
14 | #include <list> | |
15 | #include <utility> | |
16 | #include <vector> | |
17 | ||
18 | namespace librbd { | |
19 | class ImageCtx; | |
20 | ||
21 | namespace io { | |
22 | ||
23 | class AioCompletion; | |
11fdf7f2 | 24 | class ObjectDispatchSpec; |
7c673cae FG |
25 | class ReadResult; |
26 | ||
27 | template <typename ImageCtxT = ImageCtx> | |
28 | class ImageRequest { | |
29 | public: | |
31f18b77 FG |
30 | virtual ~ImageRequest() { |
31 | m_trace.event("finish"); | |
32 | } | |
7c673cae FG |
33 | |
34 | static void aio_read(ImageCtxT *ictx, AioCompletion *c, | |
1e59de90 TL |
35 | Extents &&image_extents, ImageArea area, |
36 | ReadResult &&read_result, IOContext io_context, | |
37 | int op_flags, int read_flags, | |
f67539c2 | 38 | const ZTracer::Trace &parent_trace); |
7c673cae | 39 | static void aio_write(ImageCtxT *ictx, AioCompletion *c, |
1e59de90 TL |
40 | Extents &&image_extents, ImageArea area, |
41 | bufferlist &&bl, int op_flags, | |
31f18b77 | 42 | const ZTracer::Trace &parent_trace); |
11fdf7f2 | 43 | static void aio_discard(ImageCtxT *ictx, AioCompletion *c, |
1e59de90 | 44 | Extents &&image_extents, ImageArea area, |
11fdf7f2 TL |
45 | uint32_t discard_granularity_bytes, |
46 | const ZTracer::Trace &parent_trace); | |
31f18b77 | 47 | static void aio_flush(ImageCtxT *ictx, AioCompletion *c, |
11fdf7f2 TL |
48 | FlushSource flush_source, |
49 | const ZTracer::Trace &parent_trace); | |
50 | static void aio_writesame(ImageCtxT *ictx, AioCompletion *c, | |
1e59de90 TL |
51 | Extents &&image_extents, ImageArea area, |
52 | bufferlist &&bl, int op_flags, | |
f67539c2 | 53 | const ZTracer::Trace &parent_trace); |
c07f9fc5 | 54 | static void aio_compare_and_write(ImageCtxT *ictx, AioCompletion *c, |
1e59de90 TL |
55 | Extents &&image_extents, ImageArea area, |
56 | bufferlist &&cmp_bl, bufferlist &&bl, | |
57 | uint64_t *mismatch_offset, int op_flags, | |
f67539c2 | 58 | const ZTracer::Trace &parent_trace); |
c07f9fc5 | 59 | |
7c673cae | 60 | void send(); |
7c673cae | 61 | |
31f18b77 FG |
62 | inline const ZTracer::Trace &get_trace() const { |
63 | return m_trace; | |
64 | } | |
65 | ||
7c673cae | 66 | protected: |
11fdf7f2 | 67 | typedef std::list<ObjectDispatchSpec*> ObjectRequests; |
7c673cae FG |
68 | |
69 | ImageCtxT &m_image_ctx; | |
70 | AioCompletion *m_aio_comp; | |
71 | Extents m_image_extents; | |
1e59de90 | 72 | ImageArea m_image_area; |
31f18b77 | 73 | ZTracer::Trace m_trace; |
7c673cae FG |
74 | |
75 | ImageRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
1e59de90 TL |
76 | Extents &&image_extents, ImageArea area, const char *trace_name, |
77 | const ZTracer::Trace &parent_trace) | |
7c673cae | 78 | : m_image_ctx(image_ctx), m_aio_comp(aio_comp), |
1e59de90 | 79 | m_image_extents(std::move(image_extents)), m_image_area(area), |
f91f0fd5 | 80 | m_trace(librbd::util::create_trace(image_ctx, trace_name, parent_trace)) { |
31f18b77 | 81 | m_trace.event("start"); |
7c673cae | 82 | } |
11fdf7f2 | 83 | |
11fdf7f2 | 84 | virtual void update_timestamp(); |
7c673cae | 85 | virtual void send_request() = 0; |
7c673cae FG |
86 | |
87 | virtual aio_type_t get_aio_type() const = 0; | |
88 | virtual const char *get_request_type() const = 0; | |
89 | }; | |
90 | ||
91 | template <typename ImageCtxT = ImageCtx> | |
92 | class ImageReadRequest : public ImageRequest<ImageCtxT> { | |
93 | public: | |
7c673cae | 94 | ImageReadRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, |
1e59de90 TL |
95 | Extents &&image_extents, ImageArea area, |
96 | ReadResult &&read_result, IOContext io_context, int op_flags, | |
97 | int read_flags, const ZTracer::Trace &parent_trace); | |
7c673cae FG |
98 | |
99 | protected: | |
7c673cae | 100 | void send_request() override; |
7c673cae FG |
101 | |
102 | aio_type_t get_aio_type() const override { | |
103 | return AIO_TYPE_READ; | |
104 | } | |
105 | const char *get_request_type() const override { | |
106 | return "aio_read"; | |
107 | } | |
1e59de90 | 108 | |
7c673cae | 109 | private: |
1e59de90 | 110 | IOContext m_io_context; |
7c673cae | 111 | int m_op_flags; |
f67539c2 | 112 | int m_read_flags; |
7c673cae FG |
113 | }; |
114 | ||
115 | template <typename ImageCtxT = ImageCtx> | |
116 | class AbstractImageWriteRequest : public ImageRequest<ImageCtxT> { | |
117 | public: | |
7c673cae FG |
118 | inline void flag_synchronous() { |
119 | m_synchronous = true; | |
120 | } | |
121 | ||
122 | protected: | |
123 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
7c673cae | 124 | |
7c673cae | 125 | AbstractImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, |
1e59de90 | 126 | Extents &&image_extents, ImageArea area, |
f67539c2 | 127 | const char *trace_name, |
31f18b77 FG |
128 | const ZTracer::Trace &parent_trace) |
129 | : ImageRequest<ImageCtxT>(image_ctx, aio_comp, std::move(image_extents), | |
1e59de90 | 130 | area, trace_name, parent_trace), |
7c673cae FG |
131 | m_synchronous(false) { |
132 | } | |
133 | ||
134 | void send_request() override; | |
135 | ||
9f95a23c TL |
136 | virtual int prune_object_extents( |
137 | LightweightObjectExtents* object_extents) const { | |
c07f9fc5 | 138 | return 0; |
7c673cae | 139 | } |
7c673cae | 140 | |
9f95a23c | 141 | void send_object_requests(const LightweightObjectExtents &object_extents, |
f67539c2 | 142 | IOContext io_context, uint64_t journal_tid); |
11fdf7f2 | 143 | virtual ObjectDispatchSpec *create_object_request( |
f67539c2 | 144 | const LightweightObjectExtent &object_extent, IOContext io_context, |
9f95a23c | 145 | uint64_t journal_tid, bool single_extent, Context *on_finish) = 0; |
7c673cae | 146 | |
11fdf7f2 | 147 | virtual uint64_t append_journal_event(bool synchronous) = 0; |
7c673cae FG |
148 | virtual void update_stats(size_t length) = 0; |
149 | ||
150 | private: | |
151 | bool m_synchronous; | |
152 | }; | |
153 | ||
154 | template <typename ImageCtxT = ImageCtx> | |
155 | class ImageWriteRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
156 | public: | |
7c673cae | 157 | ImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, |
1e59de90 TL |
158 | Extents &&image_extents, ImageArea area, bufferlist &&bl, |
159 | int op_flags, const ZTracer::Trace &parent_trace) | |
31f18b77 | 160 | : AbstractImageWriteRequest<ImageCtxT>( |
1e59de90 TL |
161 | image_ctx, aio_comp, std::move(image_extents), area, |
162 | "write", parent_trace), | |
7c673cae FG |
163 | m_bl(std::move(bl)), m_op_flags(op_flags) { |
164 | } | |
165 | ||
166 | protected: | |
167 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
7c673cae FG |
168 | |
169 | aio_type_t get_aio_type() const override { | |
170 | return AIO_TYPE_WRITE; | |
171 | } | |
172 | const char *get_request_type() const override { | |
173 | return "aio_write"; | |
174 | } | |
175 | ||
9f95a23c TL |
176 | void assemble_extent(const LightweightObjectExtent &object_extent, |
177 | bufferlist *bl); | |
7c673cae | 178 | |
11fdf7f2 | 179 | ObjectDispatchSpec *create_object_request( |
f67539c2 | 180 | const LightweightObjectExtent &object_extent, IOContext io_context, |
9f95a23c | 181 | uint64_t journal_tid, bool single_extent, Context *on_finish) override; |
7c673cae | 182 | |
11fdf7f2 | 183 | uint64_t append_journal_event(bool synchronous) override; |
7c673cae FG |
184 | void update_stats(size_t length) override; |
185 | ||
186 | private: | |
187 | bufferlist m_bl; | |
188 | int m_op_flags; | |
189 | }; | |
190 | ||
191 | template <typename ImageCtxT = ImageCtx> | |
192 | class ImageDiscardRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
193 | public: | |
194 | ImageDiscardRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
1e59de90 TL |
195 | Extents&& image_extents, ImageArea area, |
196 | uint32_t discard_granularity_bytes, | |
11fdf7f2 | 197 | const ZTracer::Trace &parent_trace) |
31f18b77 | 198 | : AbstractImageWriteRequest<ImageCtxT>( |
1e59de90 TL |
199 | image_ctx, aio_comp, std::move(image_extents), area, |
200 | "discard", parent_trace), | |
11fdf7f2 | 201 | m_discard_granularity_bytes(discard_granularity_bytes) { |
7c673cae FG |
202 | } |
203 | ||
204 | protected: | |
205 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
7c673cae FG |
206 | |
207 | aio_type_t get_aio_type() const override { | |
208 | return AIO_TYPE_DISCARD; | |
209 | } | |
210 | const char *get_request_type() const override { | |
211 | return "aio_discard"; | |
212 | } | |
213 | ||
11fdf7f2 | 214 | ObjectDispatchSpec *create_object_request( |
f67539c2 | 215 | const LightweightObjectExtent &object_extent, IOContext io_context, |
9f95a23c | 216 | uint64_t journal_tid, bool single_extent, Context *on_finish) override; |
7c673cae | 217 | |
11fdf7f2 | 218 | uint64_t append_journal_event(bool synchronous) override; |
7c673cae | 219 | void update_stats(size_t length) override; |
11fdf7f2 | 220 | |
9f95a23c TL |
221 | int prune_object_extents( |
222 | LightweightObjectExtents* object_extents) const override; | |
11fdf7f2 | 223 | |
7c673cae | 224 | private: |
11fdf7f2 | 225 | uint32_t m_discard_granularity_bytes; |
7c673cae FG |
226 | }; |
227 | ||
228 | template <typename ImageCtxT = ImageCtx> | |
229 | class ImageFlushRequest : public ImageRequest<ImageCtxT> { | |
230 | public: | |
31f18b77 | 231 | ImageFlushRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, |
11fdf7f2 TL |
232 | FlushSource flush_source, |
233 | const ZTracer::Trace &parent_trace) | |
1e59de90 TL |
234 | : ImageRequest<ImageCtxT>(image_ctx, aio_comp, {}, |
235 | ImageArea::DATA /* dummy for {} */, | |
236 | "flush", parent_trace), | |
11fdf7f2 | 237 | m_flush_source(flush_source) { |
7c673cae FG |
238 | } |
239 | ||
240 | protected: | |
241 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
242 | ||
11fdf7f2 TL |
243 | void update_timestamp() override { |
244 | } | |
7c673cae | 245 | void send_request() override; |
7c673cae FG |
246 | |
247 | aio_type_t get_aio_type() const override { | |
248 | return AIO_TYPE_FLUSH; | |
249 | } | |
250 | const char *get_request_type() const override { | |
251 | return "aio_flush"; | |
252 | } | |
11fdf7f2 TL |
253 | |
254 | private: | |
255 | FlushSource m_flush_source; | |
256 | ||
7c673cae FG |
257 | }; |
258 | ||
259 | template <typename ImageCtxT = ImageCtx> | |
260 | class ImageWriteSameRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
261 | public: | |
262 | ImageWriteSameRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
1e59de90 TL |
263 | Extents&& image_extents, ImageArea area, |
264 | bufferlist &&bl, int op_flags, | |
f67539c2 | 265 | const ZTracer::Trace &parent_trace) |
31f18b77 | 266 | : AbstractImageWriteRequest<ImageCtxT>( |
1e59de90 TL |
267 | image_ctx, aio_comp, std::move(image_extents), area, |
268 | "writesame", parent_trace), | |
7c673cae FG |
269 | m_data_bl(std::move(bl)), m_op_flags(op_flags) { |
270 | } | |
271 | ||
272 | protected: | |
273 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
7c673cae FG |
274 | |
275 | aio_type_t get_aio_type() const override { | |
276 | return AIO_TYPE_WRITESAME; | |
277 | } | |
278 | const char *get_request_type() const override { | |
279 | return "aio_writesame"; | |
280 | } | |
281 | ||
11fdf7f2 | 282 | ObjectDispatchSpec *create_object_request( |
f67539c2 | 283 | const LightweightObjectExtent &object_extent, IOContext io_context, |
9f95a23c | 284 | uint64_t journal_tid, bool single_extent, Context *on_finish) override; |
7c673cae | 285 | |
11fdf7f2 | 286 | uint64_t append_journal_event(bool synchronous) override; |
7c673cae FG |
287 | void update_stats(size_t length) override; |
288 | private: | |
289 | bufferlist m_data_bl; | |
290 | int m_op_flags; | |
291 | }; | |
292 | ||
c07f9fc5 FG |
293 | template <typename ImageCtxT = ImageCtx> |
294 | class ImageCompareAndWriteRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
295 | public: | |
296 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
c07f9fc5 FG |
297 | |
298 | ImageCompareAndWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
1e59de90 TL |
299 | Extents &&image_extents, ImageArea area, |
300 | bufferlist &&cmp_bl, bufferlist &&bl, | |
301 | uint64_t *mismatch_offset, int op_flags, | |
302 | const ZTracer::Trace &parent_trace) | |
c07f9fc5 | 303 | : AbstractImageWriteRequest<ImageCtxT>( |
1e59de90 | 304 | image_ctx, aio_comp, std::move(image_extents), area, |
f67539c2 | 305 | "compare_and_write", parent_trace), |
c07f9fc5 FG |
306 | m_cmp_bl(std::move(cmp_bl)), m_bl(std::move(bl)), |
307 | m_mismatch_offset(mismatch_offset), m_op_flags(op_flags) { | |
308 | } | |
309 | ||
310 | protected: | |
9f95a23c | 311 | void assemble_extent(const LightweightObjectExtent &object_extent, |
39ae355f | 312 | bufferlist *bl, bufferlist *cmp_bl); |
c07f9fc5 | 313 | |
11fdf7f2 | 314 | ObjectDispatchSpec *create_object_request( |
f67539c2 | 315 | const LightweightObjectExtent &object_extent, IOContext io_context, |
9f95a23c | 316 | uint64_t journal_tid, bool single_extent, Context *on_finish) override; |
c07f9fc5 | 317 | |
11fdf7f2 | 318 | uint64_t append_journal_event(bool synchronous) override; |
c07f9fc5 FG |
319 | void update_stats(size_t length) override; |
320 | ||
321 | aio_type_t get_aio_type() const override { | |
322 | return AIO_TYPE_COMPARE_AND_WRITE; | |
323 | } | |
324 | const char *get_request_type() const override { | |
325 | return "aio_compare_and_write"; | |
326 | } | |
327 | ||
9f95a23c TL |
328 | int prune_object_extents( |
329 | LightweightObjectExtents* object_extents) const override; | |
11fdf7f2 | 330 | |
c07f9fc5 FG |
331 | private: |
332 | bufferlist m_cmp_bl; | |
333 | bufferlist m_bl; | |
334 | uint64_t *m_mismatch_offset; | |
335 | int m_op_flags; | |
336 | }; | |
337 | ||
f67539c2 TL |
338 | template <typename ImageCtxT = ImageCtx> |
339 | class ImageListSnapsRequest : public ImageRequest<ImageCtxT> { | |
340 | public: | |
f67539c2 TL |
341 | ImageListSnapsRequest( |
342 | ImageCtxT& image_ctx, AioCompletion* aio_comp, | |
1e59de90 TL |
343 | Extents&& image_extents, ImageArea area, SnapIds&& snap_ids, |
344 | int list_snaps_flags, SnapshotDelta* snapshot_delta, | |
345 | const ZTracer::Trace& parent_trace); | |
f67539c2 TL |
346 | |
347 | protected: | |
348 | void update_timestamp() override {} | |
349 | void send_request() override; | |
350 | ||
351 | aio_type_t get_aio_type() const override { | |
352 | return AIO_TYPE_GENERIC; | |
353 | } | |
354 | const char *get_request_type() const override { | |
355 | return "list-snaps"; | |
356 | } | |
357 | ||
358 | private: | |
359 | SnapIds m_snap_ids; | |
360 | int m_list_snaps_flags; | |
361 | SnapshotDelta* m_snapshot_delta; | |
362 | }; | |
363 | ||
7c673cae FG |
364 | } // namespace io |
365 | } // namespace librbd | |
366 | ||
367 | extern template class librbd::io::ImageRequest<librbd::ImageCtx>; | |
368 | extern template class librbd::io::ImageReadRequest<librbd::ImageCtx>; | |
369 | extern template class librbd::io::AbstractImageWriteRequest<librbd::ImageCtx>; | |
370 | extern template class librbd::io::ImageWriteRequest<librbd::ImageCtx>; | |
371 | extern template class librbd::io::ImageDiscardRequest<librbd::ImageCtx>; | |
372 | extern template class librbd::io::ImageFlushRequest<librbd::ImageCtx>; | |
373 | extern template class librbd::io::ImageWriteSameRequest<librbd::ImageCtx>; | |
c07f9fc5 | 374 | extern template class librbd::io::ImageCompareAndWriteRequest<librbd::ImageCtx>; |
f67539c2 | 375 | extern template class librbd::io::ImageListSnapsRequest<librbd::ImageCtx>; |
7c673cae FG |
376 | |
377 | #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_H |