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 void aio_read(ImageCtxT
*ictx
, AioCompletion
*c
,
37 Extents
&&image_extents
, ReadResult
&&read_result
,
38 int op_flags
, const ZTracer::Trace
&parent_trace
);
39 static void aio_write(ImageCtxT
*ictx
, AioCompletion
*c
,
40 Extents
&&image_extents
, bufferlist
&&bl
, int op_flags
,
41 const ZTracer::Trace
&parent_trace
);
42 static void aio_discard(ImageCtxT
*ictx
, AioCompletion
*c
, uint64_t off
,
43 uint64_t len
, bool skip_partial_discard
,
44 const ZTracer::Trace
&parent_trace
);
45 static void aio_flush(ImageCtxT
*ictx
, AioCompletion
*c
,
46 const ZTracer::Trace
&parent_trace
);
47 static void aio_writesame(ImageCtxT
*ictx
, AioCompletion
*c
, uint64_t off
,
48 uint64_t len
, bufferlist
&&bl
, int op_flags
,
49 const ZTracer::Trace
&parent_trace
);
51 virtual bool is_write_op() const {
60 void set_bypass_image_cache() {
61 m_bypass_image_cache
= true;
64 inline const ZTracer::Trace
&get_trace() const {
69 typedef std::list
<ObjectRequestHandle
*> ObjectRequests
;
71 ImageCtxT
&m_image_ctx
;
72 AioCompletion
*m_aio_comp
;
73 Extents m_image_extents
;
74 ZTracer::Trace m_trace
;
75 bool m_bypass_image_cache
= false;
77 ImageRequest(ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
,
78 Extents
&&image_extents
, const char *trace_name
,
79 const ZTracer::Trace
&parent_trace
)
80 : m_image_ctx(image_ctx
), m_aio_comp(aio_comp
),
81 m_image_extents(std::move(image_extents
)),
82 m_trace(util::create_trace(image_ctx
, trace_name
, parent_trace
)) {
83 m_trace
.event("start");
87 virtual int clip_request();
88 virtual void send_request() = 0;
89 virtual void send_image_cache_request() = 0;
91 virtual aio_type_t
get_aio_type() const = 0;
92 virtual const char *get_request_type() const = 0;
95 template <typename ImageCtxT
= ImageCtx
>
96 class ImageReadRequest
: public ImageRequest
<ImageCtxT
> {
98 using typename ImageRequest
<ImageCtxT
>::Extents
;
100 ImageReadRequest(ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
,
101 Extents
&&image_extents
, ReadResult
&&read_result
,
102 int op_flags
, const ZTracer::Trace
&parent_trace
);
105 int clip_request() override
;
107 void send_request() override
;
108 void send_image_cache_request() override
;
110 aio_type_t
get_aio_type() const override
{
111 return AIO_TYPE_READ
;
113 const char *get_request_type() const override
{
122 template <typename ImageCtxT
= ImageCtx
>
123 class AbstractImageWriteRequest
: public ImageRequest
<ImageCtxT
> {
125 bool is_write_op() const override
{
129 inline void flag_synchronous() {
130 m_synchronous
= true;
134 using typename ImageRequest
<ImageCtxT
>::ObjectRequests
;
135 using typename ImageRequest
<ImageCtxT
>::Extents
;
137 typedef std::vector
<ObjectExtent
> ObjectExtents
;
139 AbstractImageWriteRequest(ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
,
140 Extents
&&image_extents
, const char *trace_name
,
141 const ZTracer::Trace
&parent_trace
)
142 : ImageRequest
<ImageCtxT
>(image_ctx
, aio_comp
, std::move(image_extents
),
143 trace_name
, parent_trace
),
144 m_synchronous(false) {
147 void send_request() override
;
149 virtual void prune_object_extents(ObjectExtents
&object_extents
) {
151 virtual uint32_t get_object_cache_request_count(bool journaling
) const {
154 virtual void send_object_cache_requests(const ObjectExtents
&object_extents
,
155 uint64_t journal_tid
) = 0;
157 virtual void send_object_requests(const ObjectExtents
&object_extents
,
158 const ::SnapContext
&snapc
,
159 ObjectRequests
*object_requests
);
160 virtual ObjectRequestHandle
*create_object_request(
161 const ObjectExtent
&object_extent
, const ::SnapContext
&snapc
,
162 Context
*on_finish
) = 0;
164 virtual uint64_t append_journal_event(const ObjectRequests
&requests
,
165 bool synchronous
) = 0;
166 virtual void update_stats(size_t length
) = 0;
172 template <typename ImageCtxT
= ImageCtx
>
173 class ImageWriteRequest
: public AbstractImageWriteRequest
<ImageCtxT
> {
175 using typename ImageRequest
<ImageCtxT
>::Extents
;
177 ImageWriteRequest(ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
,
178 Extents
&&image_extents
, bufferlist
&&bl
, int op_flags
,
179 const ZTracer::Trace
&parent_trace
)
180 : AbstractImageWriteRequest
<ImageCtxT
>(
181 image_ctx
, aio_comp
, std::move(image_extents
), "write", parent_trace
),
182 m_bl(std::move(bl
)), m_op_flags(op_flags
) {
186 using typename ImageRequest
<ImageCtxT
>::ObjectRequests
;
187 using typename AbstractImageWriteRequest
<ImageCtxT
>::ObjectExtents
;
189 aio_type_t
get_aio_type() const override
{
190 return AIO_TYPE_WRITE
;
192 const char *get_request_type() const override
{
196 void assemble_extent(const ObjectExtent
&object_extent
, bufferlist
*bl
);
198 void send_image_cache_request() override
;
200 void send_object_cache_requests(const ObjectExtents
&object_extents
,
201 uint64_t journal_tid
) override
;
203 void send_object_requests(const ObjectExtents
&object_extents
,
204 const ::SnapContext
&snapc
,
205 ObjectRequests
*aio_object_requests
) override
;
207 ObjectRequestHandle
*create_object_request(
208 const ObjectExtent
&object_extent
, const ::SnapContext
&snapc
,
209 Context
*on_finish
) override
;
211 uint64_t append_journal_event(const ObjectRequests
&requests
,
212 bool synchronous
) override
;
213 void update_stats(size_t length
) override
;
220 template <typename ImageCtxT
= ImageCtx
>
221 class ImageDiscardRequest
: public AbstractImageWriteRequest
<ImageCtxT
> {
223 ImageDiscardRequest(ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
,
224 uint64_t off
, uint64_t len
, bool skip_partial_discard
,
225 const ZTracer::Trace
&parent_trace
)
226 : AbstractImageWriteRequest
<ImageCtxT
>(
227 image_ctx
, aio_comp
, {{off
, len
}}, "discard", parent_trace
),
228 m_skip_partial_discard(skip_partial_discard
) {
232 using typename ImageRequest
<ImageCtxT
>::ObjectRequests
;
233 using typename AbstractImageWriteRequest
<ImageCtxT
>::ObjectExtents
;
235 aio_type_t
get_aio_type() const override
{
236 return AIO_TYPE_DISCARD
;
238 const char *get_request_type() const override
{
239 return "aio_discard";
242 void prune_object_extents(ObjectExtents
&object_extents
) override
;
244 void send_image_cache_request() override
;
246 uint32_t get_object_cache_request_count(bool journaling
) const override
;
247 void send_object_cache_requests(const ObjectExtents
&object_extents
,
248 uint64_t journal_tid
) override
;
250 ObjectRequestHandle
*create_object_request(
251 const ObjectExtent
&object_extent
, const ::SnapContext
&snapc
,
252 Context
*on_finish
) override
;
254 uint64_t append_journal_event(const ObjectRequests
&requests
,
255 bool synchronous
) override
;
256 void update_stats(size_t length
) override
;
258 bool m_skip_partial_discard
;
261 template <typename ImageCtxT
= ImageCtx
>
262 class ImageFlushRequest
: public ImageRequest
<ImageCtxT
> {
264 ImageFlushRequest(ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
,
265 const ZTracer::Trace
&parent_trace
)
266 : ImageRequest
<ImageCtxT
>(image_ctx
, aio_comp
, {}, "flush", parent_trace
) {
269 bool is_write_op() const override
{
274 using typename ImageRequest
<ImageCtxT
>::ObjectRequests
;
276 int clip_request() override
{
279 void send_request() override
;
280 void send_image_cache_request() override
;
282 aio_type_t
get_aio_type() const override
{
283 return AIO_TYPE_FLUSH
;
285 const char *get_request_type() const override
{
290 template <typename ImageCtxT
= ImageCtx
>
291 class ImageWriteSameRequest
: public AbstractImageWriteRequest
<ImageCtxT
> {
293 ImageWriteSameRequest(ImageCtxT
&image_ctx
, AioCompletion
*aio_comp
,
294 uint64_t off
, uint64_t len
, bufferlist
&&bl
,
295 int op_flags
, const ZTracer::Trace
&parent_trace
)
296 : AbstractImageWriteRequest
<ImageCtxT
>(
297 image_ctx
, aio_comp
, {{off
, len
}}, "writesame", parent_trace
),
298 m_data_bl(std::move(bl
)), m_op_flags(op_flags
) {
302 using typename ImageRequest
<ImageCtxT
>::ObjectRequests
;
303 using typename AbstractImageWriteRequest
<ImageCtxT
>::ObjectExtents
;
305 aio_type_t
get_aio_type() const override
{
306 return AIO_TYPE_WRITESAME
;
308 const char *get_request_type() const override
{
309 return "aio_writesame";
312 bool assemble_writesame_extent(const ObjectExtent
&object_extent
,
313 bufferlist
*bl
, bool force_write
);
315 void send_image_cache_request() override
;
317 void send_object_cache_requests(const ObjectExtents
&object_extents
,
318 uint64_t journal_tid
) override
;
320 void send_object_requests(const ObjectExtents
&object_extents
,
321 const ::SnapContext
&snapc
,
322 ObjectRequests
*object_requests
) override
;
323 ObjectRequestHandle
*create_object_request(
324 const ObjectExtent
&object_extent
, const ::SnapContext
&snapc
,
325 Context
*on_finish
) override
;
327 uint64_t append_journal_event(const ObjectRequests
&requests
,
328 bool synchronous
) override
;
329 void update_stats(size_t length
) override
;
331 bufferlist m_data_bl
;
336 } // namespace librbd
338 extern template class librbd::io::ImageRequest
<librbd::ImageCtx
>;
339 extern template class librbd::io::ImageReadRequest
<librbd::ImageCtx
>;
340 extern template class librbd::io::AbstractImageWriteRequest
<librbd::ImageCtx
>;
341 extern template class librbd::io::ImageWriteRequest
<librbd::ImageCtx
>;
342 extern template class librbd::io::ImageDiscardRequest
<librbd::ImageCtx
>;
343 extern template class librbd::io::ImageFlushRequest
<librbd::ImageCtx
>;
344 extern template class librbd::io::ImageWriteSameRequest
<librbd::ImageCtx
>;
346 #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_H