]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/ImageRequest.h
update sources to v12.1.2
[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/snap_types.h"
10 #include "common/zipkin_trace.h"
11 #include "osd/osd_types.h"
12 #include "librbd/Utils.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 ObjectRequestHandle;
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 ImageRequest* create_read_request(ImageCtxT &image_ctx,
37 AioCompletion *aio_comp,
38 Extents &&image_extents,
39 ReadResult &&read_result,
40 int op_flags,
41 const ZTracer::Trace &parent_trace);
42 static ImageRequest* create_write_request(ImageCtxT &image_ctx,
43 AioCompletion *aio_comp,
44 Extents &&image_extents,
45 bufferlist &&bl, int op_flags,
46 const ZTracer::Trace &parent_trace);
47 static ImageRequest* create_discard_request(ImageCtxT &image_ctx,
48 AioCompletion *aio_comp,
49 uint64_t off, uint64_t len,
50 bool skip_partial_discard,
51 const ZTracer::Trace &parent_trace);
52 static ImageRequest* create_flush_request(ImageCtxT &image_ctx,
53 AioCompletion *aio_comp,
54 const ZTracer::Trace &parent_trace);
55 static ImageRequest* create_writesame_request(ImageCtxT &image_ctx,
56 AioCompletion *aio_comp,
57 uint64_t off, uint64_t len,
58 bufferlist &&bl, int op_flags,
59 const ZTracer::Trace &parent_trace);
60 static ImageRequest* create_compare_and_write_request(
61 ImageCtxT &image_ctx, AioCompletion *c, Extents &&image_extents,
62 bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset,
63 int op_flags, const ZTracer::Trace &parent_trace);
64
65 static void aio_read(ImageCtxT *ictx, AioCompletion *c,
66 Extents &&image_extents, ReadResult &&read_result,
67 int op_flags, const ZTracer::Trace &parent_trace);
68 static void aio_write(ImageCtxT *ictx, AioCompletion *c,
69 Extents &&image_extents, bufferlist &&bl, int op_flags,
70 const ZTracer::Trace &parent_trace);
71 static void aio_discard(ImageCtxT *ictx, AioCompletion *c, uint64_t off,
72 uint64_t len, bool skip_partial_discard,
73 const ZTracer::Trace &parent_trace);
74 static void aio_flush(ImageCtxT *ictx, AioCompletion *c,
75 const ZTracer::Trace &parent_trace);
76 static void aio_writesame(ImageCtxT *ictx, AioCompletion *c, uint64_t off,
77 uint64_t len, bufferlist &&bl, int op_flags,
78 const ZTracer::Trace &parent_trace);
79
80 static void aio_compare_and_write(ImageCtxT *ictx, AioCompletion *c,
81 Extents &&image_extents, bufferlist &&cmp_bl,
82 bufferlist &&bl, uint64_t *mismatch_offset,
83 int op_flags, const ZTracer::Trace &parent_trace);
84
85 virtual bool is_write_op() const {
86 return false;
87 }
88
89 void start_op();
90
91 void send();
92 void fail(int r);
93
94 void set_bypass_image_cache() {
95 m_bypass_image_cache = true;
96 }
97
98 inline const ZTracer::Trace &get_trace() const {
99 return m_trace;
100 }
101
102 protected:
103 typedef std::list<ObjectRequestHandle *> ObjectRequests;
104
105 ImageCtxT &m_image_ctx;
106 AioCompletion *m_aio_comp;
107 Extents m_image_extents;
108 ZTracer::Trace m_trace;
109 bool m_bypass_image_cache = false;
110
111 ImageRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
112 Extents &&image_extents, const char *trace_name,
113 const ZTracer::Trace &parent_trace)
114 : m_image_ctx(image_ctx), m_aio_comp(aio_comp),
115 m_image_extents(std::move(image_extents)),
116 m_trace(util::create_trace(image_ctx, trace_name, parent_trace)) {
117 m_trace.event("start");
118 }
119
120
121 virtual int clip_request();
122 virtual void send_request() = 0;
123 virtual void send_image_cache_request() = 0;
124
125 virtual aio_type_t get_aio_type() const = 0;
126 virtual const char *get_request_type() const = 0;
127 };
128
129 template <typename ImageCtxT = ImageCtx>
130 class ImageReadRequest : public ImageRequest<ImageCtxT> {
131 public:
132 using typename ImageRequest<ImageCtxT>::Extents;
133
134 ImageReadRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
135 Extents &&image_extents, ReadResult &&read_result,
136 int op_flags, const ZTracer::Trace &parent_trace);
137
138 protected:
139 int clip_request() override;
140
141 void send_request() override;
142 void send_image_cache_request() override;
143
144 aio_type_t get_aio_type() const override {
145 return AIO_TYPE_READ;
146 }
147 const char *get_request_type() const override {
148 return "aio_read";
149 }
150 private:
151 char *m_buf;
152 bufferlist *m_pbl;
153 int m_op_flags;
154 };
155
156 template <typename ImageCtxT = ImageCtx>
157 class AbstractImageWriteRequest : public ImageRequest<ImageCtxT> {
158 public:
159 bool is_write_op() const override {
160 return true;
161 }
162
163 inline void flag_synchronous() {
164 m_synchronous = true;
165 }
166
167 protected:
168 using typename ImageRequest<ImageCtxT>::ObjectRequests;
169 using typename ImageRequest<ImageCtxT>::Extents;
170
171 typedef std::vector<ObjectExtent> ObjectExtents;
172
173 AbstractImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
174 Extents &&image_extents, const char *trace_name,
175 const ZTracer::Trace &parent_trace)
176 : ImageRequest<ImageCtxT>(image_ctx, aio_comp, std::move(image_extents),
177 trace_name, parent_trace),
178 m_synchronous(false) {
179 }
180
181 void send_request() override;
182
183 virtual int prune_object_extents(ObjectExtents &object_extents) {
184 return 0;
185 }
186 virtual uint32_t get_object_cache_request_count(bool journaling) const {
187 return 0;
188 }
189 virtual void send_object_cache_requests(const ObjectExtents &object_extents,
190 uint64_t journal_tid) = 0;
191
192 virtual void send_object_requests(const ObjectExtents &object_extents,
193 const ::SnapContext &snapc,
194 ObjectRequests *object_requests);
195 virtual ObjectRequestHandle *create_object_request(
196 const ObjectExtent &object_extent, const ::SnapContext &snapc,
197 Context *on_finish) = 0;
198
199 virtual uint64_t append_journal_event(const ObjectRequests &requests,
200 bool synchronous) = 0;
201 virtual void update_stats(size_t length) = 0;
202
203 private:
204 bool m_synchronous;
205 };
206
207 template <typename ImageCtxT = ImageCtx>
208 class ImageWriteRequest : public AbstractImageWriteRequest<ImageCtxT> {
209 public:
210 using typename ImageRequest<ImageCtxT>::Extents;
211
212 ImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
213 Extents &&image_extents, bufferlist &&bl, int op_flags,
214 const ZTracer::Trace &parent_trace)
215 : AbstractImageWriteRequest<ImageCtxT>(
216 image_ctx, aio_comp, std::move(image_extents), "write", parent_trace),
217 m_bl(std::move(bl)), m_op_flags(op_flags) {
218 }
219
220 protected:
221 using typename ImageRequest<ImageCtxT>::ObjectRequests;
222 using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents;
223
224 aio_type_t get_aio_type() const override {
225 return AIO_TYPE_WRITE;
226 }
227 const char *get_request_type() const override {
228 return "aio_write";
229 }
230
231 void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl);
232
233 void send_image_cache_request() override;
234
235 void send_object_cache_requests(const ObjectExtents &object_extents,
236 uint64_t journal_tid) override;
237
238 void send_object_requests(const ObjectExtents &object_extents,
239 const ::SnapContext &snapc,
240 ObjectRequests *aio_object_requests) override;
241
242 ObjectRequestHandle *create_object_request(
243 const ObjectExtent &object_extent, const ::SnapContext &snapc,
244 Context *on_finish) override;
245
246 uint64_t append_journal_event(const ObjectRequests &requests,
247 bool synchronous) override;
248 void update_stats(size_t length) override;
249
250 private:
251 bufferlist m_bl;
252 int m_op_flags;
253 };
254
255 template <typename ImageCtxT = ImageCtx>
256 class ImageDiscardRequest : public AbstractImageWriteRequest<ImageCtxT> {
257 public:
258 ImageDiscardRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
259 uint64_t off, uint64_t len, bool skip_partial_discard,
260 const ZTracer::Trace &parent_trace)
261 : AbstractImageWriteRequest<ImageCtxT>(
262 image_ctx, aio_comp, {{off, len}}, "discard", parent_trace),
263 m_skip_partial_discard(skip_partial_discard) {
264 }
265
266 protected:
267 using typename ImageRequest<ImageCtxT>::ObjectRequests;
268 using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents;
269
270 aio_type_t get_aio_type() const override {
271 return AIO_TYPE_DISCARD;
272 }
273 const char *get_request_type() const override {
274 return "aio_discard";
275 }
276
277 int prune_object_extents(ObjectExtents &object_extents) override;
278
279 void send_image_cache_request() override;
280
281 uint32_t get_object_cache_request_count(bool journaling) const override;
282 void send_object_cache_requests(const ObjectExtents &object_extents,
283 uint64_t journal_tid) override;
284
285 ObjectRequestHandle *create_object_request(
286 const ObjectExtent &object_extent, const ::SnapContext &snapc,
287 Context *on_finish) override;
288
289 uint64_t append_journal_event(const ObjectRequests &requests,
290 bool synchronous) override;
291 void update_stats(size_t length) override;
292 private:
293 bool m_skip_partial_discard;
294 };
295
296 template <typename ImageCtxT = ImageCtx>
297 class ImageFlushRequest : public ImageRequest<ImageCtxT> {
298 public:
299 ImageFlushRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
300 const ZTracer::Trace &parent_trace)
301 : ImageRequest<ImageCtxT>(image_ctx, aio_comp, {}, "flush", parent_trace) {
302 }
303
304 bool is_write_op() const override {
305 return true;
306 }
307
308 protected:
309 using typename ImageRequest<ImageCtxT>::ObjectRequests;
310
311 int clip_request() override {
312 return 0;
313 }
314 void send_request() override;
315 void send_image_cache_request() override;
316
317 aio_type_t get_aio_type() const override {
318 return AIO_TYPE_FLUSH;
319 }
320 const char *get_request_type() const override {
321 return "aio_flush";
322 }
323 };
324
325 template <typename ImageCtxT = ImageCtx>
326 class ImageWriteSameRequest : public AbstractImageWriteRequest<ImageCtxT> {
327 public:
328 ImageWriteSameRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
329 uint64_t off, uint64_t len, bufferlist &&bl,
330 int op_flags, const ZTracer::Trace &parent_trace)
331 : AbstractImageWriteRequest<ImageCtxT>(
332 image_ctx, aio_comp, {{off, len}}, "writesame", parent_trace),
333 m_data_bl(std::move(bl)), m_op_flags(op_flags) {
334 }
335
336 protected:
337 using typename ImageRequest<ImageCtxT>::ObjectRequests;
338 using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents;
339
340 aio_type_t get_aio_type() const override {
341 return AIO_TYPE_WRITESAME;
342 }
343 const char *get_request_type() const override {
344 return "aio_writesame";
345 }
346
347 bool assemble_writesame_extent(const ObjectExtent &object_extent,
348 bufferlist *bl, bool force_write);
349
350 void send_image_cache_request() override;
351
352 void send_object_cache_requests(const ObjectExtents &object_extents,
353 uint64_t journal_tid) override;
354
355 void send_object_requests(const ObjectExtents &object_extents,
356 const ::SnapContext &snapc,
357 ObjectRequests *object_requests) override;
358 ObjectRequestHandle *create_object_request(
359 const ObjectExtent &object_extent, const ::SnapContext &snapc,
360 Context *on_finish) override;
361
362 uint64_t append_journal_event(const ObjectRequests &requests,
363 bool synchronous) override;
364 void update_stats(size_t length) override;
365 private:
366 bufferlist m_data_bl;
367 int m_op_flags;
368 };
369
370 template <typename ImageCtxT = ImageCtx>
371 class ImageCompareAndWriteRequest : public AbstractImageWriteRequest<ImageCtxT> {
372 public:
373 using typename ImageRequest<ImageCtxT>::ObjectRequests;
374 using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents;
375
376 ImageCompareAndWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
377 Extents &&image_extents, bufferlist &&cmp_bl,
378 bufferlist &&bl, uint64_t *mismatch_offset,
379 int op_flags, const ZTracer::Trace &parent_trace)
380 : AbstractImageWriteRequest<ImageCtxT>(
381 image_ctx, aio_comp, std::move(image_extents), "compare_and_write", parent_trace),
382 m_cmp_bl(std::move(cmp_bl)), m_bl(std::move(bl)),
383 m_mismatch_offset(mismatch_offset), m_op_flags(op_flags) {
384 }
385
386 protected:
387 void send_image_cache_request() override;
388
389 void send_object_cache_requests(const ObjectExtents &object_extents,
390 uint64_t journal_tid) override;
391
392 void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl);
393
394 ObjectRequestHandle *create_object_request(const ObjectExtent &object_extent,
395 const ::SnapContext &snapc,
396 Context *on_finish) override;
397
398 uint64_t append_journal_event(const ObjectRequests &requests,
399 bool synchronous) override;
400 void update_stats(size_t length) override;
401
402 aio_type_t get_aio_type() const override {
403 return AIO_TYPE_COMPARE_AND_WRITE;
404 }
405 const char *get_request_type() const override {
406 return "aio_compare_and_write";
407 }
408
409 int prune_object_extents(ObjectExtents &object_extents) override;
410 private:
411 bufferlist m_cmp_bl;
412 bufferlist m_bl;
413 uint64_t *m_mismatch_offset;
414 int m_op_flags;
415 };
416
417 } // namespace io
418 } // namespace librbd
419
420 extern template class librbd::io::ImageRequest<librbd::ImageCtx>;
421 extern template class librbd::io::ImageReadRequest<librbd::ImageCtx>;
422 extern template class librbd::io::AbstractImageWriteRequest<librbd::ImageCtx>;
423 extern template class librbd::io::ImageWriteRequest<librbd::ImageCtx>;
424 extern template class librbd::io::ImageDiscardRequest<librbd::ImageCtx>;
425 extern template class librbd::io::ImageFlushRequest<librbd::ImageCtx>;
426 extern template class librbd::io::ImageWriteSameRequest<librbd::ImageCtx>;
427 extern template class librbd::io::ImageCompareAndWriteRequest<librbd::ImageCtx>;
428
429 #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_H