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