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