1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_LIBRBD_IO_IMAGE_REQUEST_H
5 #define CEPH_LIBRBD_IO_IMAGE_REQUEST_H
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"
24 class ObjectRequestHandle;
27 template <typename ImageCtxT = ImageCtx>
30 typedef std::vector<std::pair<uint64_t,uint64_t> > Extents;
32 virtual ~ImageRequest() {
33 m_trace.event("finish");
36 static ImageRequest* create_read_request(ImageCtxT &image_ctx,
37 AioCompletion *aio_comp,
38 Extents &&image_extents,
39 ReadResult &&read_result,
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);
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);
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);
85 virtual bool is_write_op() const {
94 void set_bypass_image_cache() {
95 m_bypass_image_cache = true;
98 inline const ZTracer::Trace &get_trace() const {
103 typedef std::list<ObjectRequestHandle *> ObjectRequests;
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;
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");
121 virtual int clip_request();
122 virtual void send_request() = 0;
123 virtual void send_image_cache_request() = 0;
125 virtual aio_type_t get_aio_type() const = 0;
126 virtual const char *get_request_type() const = 0;
129 template <typename ImageCtxT = ImageCtx>
130 class ImageReadRequest : public ImageRequest<ImageCtxT> {
132 using typename ImageRequest<ImageCtxT>::Extents;
134 ImageReadRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
135 Extents &&image_extents, ReadResult &&read_result,
136 int op_flags, const ZTracer::Trace &parent_trace);
139 int clip_request() override;
141 void send_request() override;
142 void send_image_cache_request() override;
144 aio_type_t get_aio_type() const override {
145 return AIO_TYPE_READ;
147 const char *get_request_type() const override {
156 template <typename ImageCtxT = ImageCtx>
157 class AbstractImageWriteRequest : public ImageRequest<ImageCtxT> {
159 bool is_write_op() const override {
163 inline void flag_synchronous() {
164 m_synchronous = true;
168 using typename ImageRequest<ImageCtxT>::ObjectRequests;
169 using typename ImageRequest<ImageCtxT>::Extents;
171 typedef std::vector<ObjectExtent> ObjectExtents;
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) {
181 void send_request() override;
183 virtual int prune_object_extents(ObjectExtents &object_extents) {
186 virtual uint32_t get_object_cache_request_count(bool journaling) const {
189 virtual void send_object_cache_requests(const ObjectExtents &object_extents,
190 uint64_t journal_tid) = 0;
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;
199 virtual uint64_t append_journal_event(const ObjectRequests &requests,
200 bool synchronous) = 0;
201 virtual void update_stats(size_t length) = 0;
207 template <typename ImageCtxT = ImageCtx>
208 class ImageWriteRequest : public AbstractImageWriteRequest<ImageCtxT> {
210 using typename ImageRequest<ImageCtxT>::Extents;
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) {
221 using typename ImageRequest<ImageCtxT>::ObjectRequests;
222 using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents;
224 aio_type_t get_aio_type() const override {
225 return AIO_TYPE_WRITE;
227 const char *get_request_type() const override {
231 void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl);
233 void send_image_cache_request() override;
235 void send_object_cache_requests(const ObjectExtents &object_extents,
236 uint64_t journal_tid) override;
238 void send_object_requests(const ObjectExtents &object_extents,
239 const ::SnapContext &snapc,
240 ObjectRequests *aio_object_requests) override;
242 ObjectRequestHandle *create_object_request(
243 const ObjectExtent &object_extent, const ::SnapContext &snapc,
244 Context *on_finish) override;
246 uint64_t append_journal_event(const ObjectRequests &requests,
247 bool synchronous) override;
248 void update_stats(size_t length) override;
255 template <typename ImageCtxT = ImageCtx>
256 class ImageDiscardRequest : public AbstractImageWriteRequest<ImageCtxT> {
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) {
267 using typename ImageRequest<ImageCtxT>::ObjectRequests;
268 using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents;
270 aio_type_t get_aio_type() const override {
271 return AIO_TYPE_DISCARD;
273 const char *get_request_type() const override {
274 return "aio_discard";
277 int prune_object_extents(ObjectExtents &object_extents) override;
279 void send_image_cache_request() override;
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;
285 ObjectRequestHandle *create_object_request(
286 const ObjectExtent &object_extent, const ::SnapContext &snapc,
287 Context *on_finish) override;
289 uint64_t append_journal_event(const ObjectRequests &requests,
290 bool synchronous) override;
291 void update_stats(size_t length) override;
293 bool m_skip_partial_discard;
296 template <typename ImageCtxT = ImageCtx>
297 class ImageFlushRequest : public ImageRequest<ImageCtxT> {
299 ImageFlushRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
300 const ZTracer::Trace &parent_trace)
301 : ImageRequest<ImageCtxT>(image_ctx, aio_comp, {}, "flush", parent_trace) {
304 bool is_write_op() const override {
309 using typename ImageRequest<ImageCtxT>::ObjectRequests;
311 int clip_request() override {
314 void send_request() override;
315 void send_image_cache_request() override;
317 aio_type_t get_aio_type() const override {
318 return AIO_TYPE_FLUSH;
320 const char *get_request_type() const override {
325 template <typename ImageCtxT = ImageCtx>
326 class ImageWriteSameRequest : public AbstractImageWriteRequest<ImageCtxT> {
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) {
337 using typename ImageRequest<ImageCtxT>::ObjectRequests;
338 using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents;
340 aio_type_t get_aio_type() const override {
341 return AIO_TYPE_WRITESAME;
343 const char *get_request_type() const override {
344 return "aio_writesame";
347 bool assemble_writesame_extent(const ObjectExtent &object_extent,
348 bufferlist *bl, bool force_write);
350 void send_image_cache_request() override;
352 void send_object_cache_requests(const ObjectExtents &object_extents,
353 uint64_t journal_tid) override;
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;
362 uint64_t append_journal_event(const ObjectRequests &requests,
363 bool synchronous) override;
364 void update_stats(size_t length) override;
366 bufferlist m_data_bl;
370 template <typename ImageCtxT = ImageCtx>
371 class ImageCompareAndWriteRequest : public AbstractImageWriteRequest<ImageCtxT> {
373 using typename ImageRequest<ImageCtxT>::ObjectRequests;
374 using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents;
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) {
387 void send_image_cache_request() override;
389 void send_object_cache_requests(const ObjectExtents &object_extents,
390 uint64_t journal_tid) override;
392 void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl);
394 ObjectRequestHandle *create_object_request(const ObjectExtent &object_extent,
395 const ::SnapContext &snapc,
396 Context *on_finish) override;
398 uint64_t append_journal_event(const ObjectRequests &requests,
399 bool synchronous) override;
400 void update_stats(size_t length) override;
402 aio_type_t get_aio_type() const override {
403 return AIO_TYPE_COMPARE_AND_WRITE;
405 const char *get_request_type() const override {
406 return "aio_compare_and_write";
409 int prune_object_extents(ObjectExtents &object_extents) override;
413 uint64_t *m_mismatch_offset;
418 } // namespace librbd
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>;
429 #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_H