]>
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; | |
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 | ||
31f18b77 FG |
32 | virtual ~ImageRequest() { |
33 | m_trace.event("finish"); | |
34 | } | |
7c673cae | 35 | |
224ce89b WB |
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); | |
c07f9fc5 FG |
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); | |
224ce89b | 64 | |
7c673cae FG |
65 | static void aio_read(ImageCtxT *ictx, AioCompletion *c, |
66 | Extents &&image_extents, ReadResult &&read_result, | |
31f18b77 | 67 | int op_flags, const ZTracer::Trace &parent_trace); |
7c673cae | 68 | static void aio_write(ImageCtxT *ictx, AioCompletion *c, |
31f18b77 FG |
69 | Extents &&image_extents, bufferlist &&bl, int op_flags, |
70 | const ZTracer::Trace &parent_trace); | |
7c673cae | 71 | static void aio_discard(ImageCtxT *ictx, AioCompletion *c, uint64_t off, |
31f18b77 FG |
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); | |
7c673cae | 76 | static void aio_writesame(ImageCtxT *ictx, AioCompletion *c, uint64_t off, |
31f18b77 FG |
77 | uint64_t len, bufferlist &&bl, int op_flags, |
78 | const ZTracer::Trace &parent_trace); | |
7c673cae | 79 | |
c07f9fc5 FG |
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 | ||
7c673cae FG |
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 | ||
31f18b77 FG |
98 | inline const ZTracer::Trace &get_trace() const { |
99 | return m_trace; | |
100 | } | |
101 | ||
7c673cae FG |
102 | protected: |
103 | typedef std::list<ObjectRequestHandle *> ObjectRequests; | |
104 | ||
105 | ImageCtxT &m_image_ctx; | |
106 | AioCompletion *m_aio_comp; | |
107 | Extents m_image_extents; | |
31f18b77 | 108 | ZTracer::Trace m_trace; |
7c673cae FG |
109 | bool m_bypass_image_cache = false; |
110 | ||
111 | ImageRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
31f18b77 FG |
112 | Extents &&image_extents, const char *trace_name, |
113 | const ZTracer::Trace &parent_trace) | |
7c673cae | 114 | : m_image_ctx(image_ctx), m_aio_comp(aio_comp), |
31f18b77 FG |
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"); | |
7c673cae | 118 | } |
31f18b77 | 119 | |
7c673cae FG |
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, | |
31f18b77 | 136 | int op_flags, const ZTracer::Trace &parent_trace); |
7c673cae FG |
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, | |
31f18b77 FG |
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), | |
7c673cae FG |
178 | m_synchronous(false) { |
179 | } | |
180 | ||
181 | void send_request() override; | |
182 | ||
c07f9fc5 FG |
183 | virtual int prune_object_extents(ObjectExtents &object_extents) { |
184 | return 0; | |
7c673cae FG |
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, | |
31f18b77 FG |
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), | |
7c673cae FG |
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, | |
31f18b77 FG |
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), | |
7c673cae FG |
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 | ||
c07f9fc5 | 277 | int prune_object_extents(ObjectExtents &object_extents) override; |
7c673cae FG |
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: | |
31f18b77 FG |
299 | ImageFlushRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, |
300 | const ZTracer::Trace &parent_trace) | |
301 | : ImageRequest<ImageCtxT>(image_ctx, aio_comp, {}, "flush", parent_trace) { | |
7c673cae FG |
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, | |
31f18b77 FG |
330 | int op_flags, const ZTracer::Trace &parent_trace) |
331 | : AbstractImageWriteRequest<ImageCtxT>( | |
332 | image_ctx, aio_comp, {{off, len}}, "writesame", parent_trace), | |
7c673cae FG |
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 | ||
c07f9fc5 FG |
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 | ||
7c673cae FG |
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>; | |
c07f9fc5 | 427 | extern template class librbd::io::ImageCompareAndWriteRequest<librbd::ImageCtx>; |
7c673cae FG |
428 | |
429 | #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_H |