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