]>
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); | |
60 | ||
7c673cae FG |
61 | static void aio_read(ImageCtxT *ictx, AioCompletion *c, |
62 | Extents &&image_extents, ReadResult &&read_result, | |
31f18b77 | 63 | int op_flags, const ZTracer::Trace &parent_trace); |
7c673cae | 64 | static void aio_write(ImageCtxT *ictx, AioCompletion *c, |
31f18b77 FG |
65 | Extents &&image_extents, bufferlist &&bl, int op_flags, |
66 | const ZTracer::Trace &parent_trace); | |
7c673cae | 67 | static void aio_discard(ImageCtxT *ictx, AioCompletion *c, uint64_t off, |
31f18b77 FG |
68 | uint64_t len, bool skip_partial_discard, |
69 | const ZTracer::Trace &parent_trace); | |
70 | static void aio_flush(ImageCtxT *ictx, AioCompletion *c, | |
71 | const ZTracer::Trace &parent_trace); | |
7c673cae | 72 | static void aio_writesame(ImageCtxT *ictx, AioCompletion *c, uint64_t off, |
31f18b77 FG |
73 | uint64_t len, bufferlist &&bl, int op_flags, |
74 | const ZTracer::Trace &parent_trace); | |
7c673cae FG |
75 | |
76 | virtual bool is_write_op() const { | |
77 | return false; | |
78 | } | |
79 | ||
80 | void start_op(); | |
81 | ||
82 | void send(); | |
83 | void fail(int r); | |
84 | ||
85 | void set_bypass_image_cache() { | |
86 | m_bypass_image_cache = true; | |
87 | } | |
88 | ||
31f18b77 FG |
89 | inline const ZTracer::Trace &get_trace() const { |
90 | return m_trace; | |
91 | } | |
92 | ||
7c673cae FG |
93 | protected: |
94 | typedef std::list<ObjectRequestHandle *> ObjectRequests; | |
95 | ||
96 | ImageCtxT &m_image_ctx; | |
97 | AioCompletion *m_aio_comp; | |
98 | Extents m_image_extents; | |
31f18b77 | 99 | ZTracer::Trace m_trace; |
7c673cae FG |
100 | bool m_bypass_image_cache = false; |
101 | ||
102 | ImageRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
31f18b77 FG |
103 | Extents &&image_extents, const char *trace_name, |
104 | const ZTracer::Trace &parent_trace) | |
7c673cae | 105 | : m_image_ctx(image_ctx), m_aio_comp(aio_comp), |
31f18b77 FG |
106 | m_image_extents(std::move(image_extents)), |
107 | m_trace(util::create_trace(image_ctx, trace_name, parent_trace)) { | |
108 | m_trace.event("start"); | |
7c673cae | 109 | } |
31f18b77 | 110 | |
7c673cae FG |
111 | |
112 | virtual int clip_request(); | |
113 | virtual void send_request() = 0; | |
114 | virtual void send_image_cache_request() = 0; | |
115 | ||
116 | virtual aio_type_t get_aio_type() const = 0; | |
117 | virtual const char *get_request_type() const = 0; | |
118 | }; | |
119 | ||
120 | template <typename ImageCtxT = ImageCtx> | |
121 | class ImageReadRequest : public ImageRequest<ImageCtxT> { | |
122 | public: | |
123 | using typename ImageRequest<ImageCtxT>::Extents; | |
124 | ||
125 | ImageReadRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
126 | Extents &&image_extents, ReadResult &&read_result, | |
31f18b77 | 127 | int op_flags, const ZTracer::Trace &parent_trace); |
7c673cae FG |
128 | |
129 | protected: | |
130 | int clip_request() override; | |
131 | ||
132 | void send_request() override; | |
133 | void send_image_cache_request() override; | |
134 | ||
135 | aio_type_t get_aio_type() const override { | |
136 | return AIO_TYPE_READ; | |
137 | } | |
138 | const char *get_request_type() const override { | |
139 | return "aio_read"; | |
140 | } | |
141 | private: | |
142 | char *m_buf; | |
143 | bufferlist *m_pbl; | |
144 | int m_op_flags; | |
145 | }; | |
146 | ||
147 | template <typename ImageCtxT = ImageCtx> | |
148 | class AbstractImageWriteRequest : public ImageRequest<ImageCtxT> { | |
149 | public: | |
150 | bool is_write_op() const override { | |
151 | return true; | |
152 | } | |
153 | ||
154 | inline void flag_synchronous() { | |
155 | m_synchronous = true; | |
156 | } | |
157 | ||
158 | protected: | |
159 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
160 | using typename ImageRequest<ImageCtxT>::Extents; | |
161 | ||
162 | typedef std::vector<ObjectExtent> ObjectExtents; | |
163 | ||
164 | AbstractImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
31f18b77 FG |
165 | Extents &&image_extents, const char *trace_name, |
166 | const ZTracer::Trace &parent_trace) | |
167 | : ImageRequest<ImageCtxT>(image_ctx, aio_comp, std::move(image_extents), | |
168 | trace_name, parent_trace), | |
7c673cae FG |
169 | m_synchronous(false) { |
170 | } | |
171 | ||
172 | void send_request() override; | |
173 | ||
174 | virtual void prune_object_extents(ObjectExtents &object_extents) { | |
175 | } | |
176 | virtual uint32_t get_object_cache_request_count(bool journaling) const { | |
177 | return 0; | |
178 | } | |
179 | virtual void send_object_cache_requests(const ObjectExtents &object_extents, | |
180 | uint64_t journal_tid) = 0; | |
181 | ||
182 | virtual void send_object_requests(const ObjectExtents &object_extents, | |
183 | const ::SnapContext &snapc, | |
184 | ObjectRequests *object_requests); | |
185 | virtual ObjectRequestHandle *create_object_request( | |
186 | const ObjectExtent &object_extent, const ::SnapContext &snapc, | |
187 | Context *on_finish) = 0; | |
188 | ||
189 | virtual uint64_t append_journal_event(const ObjectRequests &requests, | |
190 | bool synchronous) = 0; | |
191 | virtual void update_stats(size_t length) = 0; | |
192 | ||
193 | private: | |
194 | bool m_synchronous; | |
195 | }; | |
196 | ||
197 | template <typename ImageCtxT = ImageCtx> | |
198 | class ImageWriteRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
199 | public: | |
200 | using typename ImageRequest<ImageCtxT>::Extents; | |
201 | ||
202 | ImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
31f18b77 FG |
203 | Extents &&image_extents, bufferlist &&bl, int op_flags, |
204 | const ZTracer::Trace &parent_trace) | |
205 | : AbstractImageWriteRequest<ImageCtxT>( | |
206 | image_ctx, aio_comp, std::move(image_extents), "write", parent_trace), | |
7c673cae FG |
207 | m_bl(std::move(bl)), m_op_flags(op_flags) { |
208 | } | |
209 | ||
210 | protected: | |
211 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
212 | using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents; | |
213 | ||
214 | aio_type_t get_aio_type() const override { | |
215 | return AIO_TYPE_WRITE; | |
216 | } | |
217 | const char *get_request_type() const override { | |
218 | return "aio_write"; | |
219 | } | |
220 | ||
221 | void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl); | |
222 | ||
223 | void send_image_cache_request() override; | |
224 | ||
225 | void send_object_cache_requests(const ObjectExtents &object_extents, | |
226 | uint64_t journal_tid) override; | |
227 | ||
228 | void send_object_requests(const ObjectExtents &object_extents, | |
229 | const ::SnapContext &snapc, | |
230 | ObjectRequests *aio_object_requests) override; | |
231 | ||
232 | ObjectRequestHandle *create_object_request( | |
233 | const ObjectExtent &object_extent, const ::SnapContext &snapc, | |
234 | Context *on_finish) override; | |
235 | ||
236 | uint64_t append_journal_event(const ObjectRequests &requests, | |
237 | bool synchronous) override; | |
238 | void update_stats(size_t length) override; | |
239 | ||
240 | private: | |
241 | bufferlist m_bl; | |
242 | int m_op_flags; | |
243 | }; | |
244 | ||
245 | template <typename ImageCtxT = ImageCtx> | |
246 | class ImageDiscardRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
247 | public: | |
248 | ImageDiscardRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
31f18b77 FG |
249 | uint64_t off, uint64_t len, bool skip_partial_discard, |
250 | const ZTracer::Trace &parent_trace) | |
251 | : AbstractImageWriteRequest<ImageCtxT>( | |
252 | image_ctx, aio_comp, {{off, len}}, "discard", parent_trace), | |
7c673cae FG |
253 | m_skip_partial_discard(skip_partial_discard) { |
254 | } | |
255 | ||
256 | protected: | |
257 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
258 | using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents; | |
259 | ||
260 | aio_type_t get_aio_type() const override { | |
261 | return AIO_TYPE_DISCARD; | |
262 | } | |
263 | const char *get_request_type() const override { | |
264 | return "aio_discard"; | |
265 | } | |
266 | ||
267 | void prune_object_extents(ObjectExtents &object_extents) override; | |
268 | ||
269 | void send_image_cache_request() override; | |
270 | ||
271 | uint32_t get_object_cache_request_count(bool journaling) const override; | |
272 | void send_object_cache_requests(const ObjectExtents &object_extents, | |
273 | uint64_t journal_tid) override; | |
274 | ||
275 | ObjectRequestHandle *create_object_request( | |
276 | const ObjectExtent &object_extent, const ::SnapContext &snapc, | |
277 | Context *on_finish) override; | |
278 | ||
279 | uint64_t append_journal_event(const ObjectRequests &requests, | |
280 | bool synchronous) override; | |
281 | void update_stats(size_t length) override; | |
282 | private: | |
283 | bool m_skip_partial_discard; | |
284 | }; | |
285 | ||
286 | template <typename ImageCtxT = ImageCtx> | |
287 | class ImageFlushRequest : public ImageRequest<ImageCtxT> { | |
288 | public: | |
31f18b77 FG |
289 | ImageFlushRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, |
290 | const ZTracer::Trace &parent_trace) | |
291 | : ImageRequest<ImageCtxT>(image_ctx, aio_comp, {}, "flush", parent_trace) { | |
7c673cae FG |
292 | } |
293 | ||
294 | bool is_write_op() const override { | |
295 | return true; | |
296 | } | |
297 | ||
298 | protected: | |
299 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
300 | ||
301 | int clip_request() override { | |
302 | return 0; | |
303 | } | |
304 | void send_request() override; | |
305 | void send_image_cache_request() override; | |
306 | ||
307 | aio_type_t get_aio_type() const override { | |
308 | return AIO_TYPE_FLUSH; | |
309 | } | |
310 | const char *get_request_type() const override { | |
311 | return "aio_flush"; | |
312 | } | |
313 | }; | |
314 | ||
315 | template <typename ImageCtxT = ImageCtx> | |
316 | class ImageWriteSameRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
317 | public: | |
318 | ImageWriteSameRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
319 | uint64_t off, uint64_t len, bufferlist &&bl, | |
31f18b77 FG |
320 | int op_flags, const ZTracer::Trace &parent_trace) |
321 | : AbstractImageWriteRequest<ImageCtxT>( | |
322 | image_ctx, aio_comp, {{off, len}}, "writesame", parent_trace), | |
7c673cae FG |
323 | m_data_bl(std::move(bl)), m_op_flags(op_flags) { |
324 | } | |
325 | ||
326 | protected: | |
327 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
328 | using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents; | |
329 | ||
330 | aio_type_t get_aio_type() const override { | |
331 | return AIO_TYPE_WRITESAME; | |
332 | } | |
333 | const char *get_request_type() const override { | |
334 | return "aio_writesame"; | |
335 | } | |
336 | ||
337 | bool assemble_writesame_extent(const ObjectExtent &object_extent, | |
338 | bufferlist *bl, bool force_write); | |
339 | ||
340 | void send_image_cache_request() override; | |
341 | ||
342 | void send_object_cache_requests(const ObjectExtents &object_extents, | |
343 | uint64_t journal_tid) override; | |
344 | ||
345 | void send_object_requests(const ObjectExtents &object_extents, | |
346 | const ::SnapContext &snapc, | |
347 | ObjectRequests *object_requests) override; | |
348 | ObjectRequestHandle *create_object_request( | |
349 | const ObjectExtent &object_extent, const ::SnapContext &snapc, | |
350 | Context *on_finish) override; | |
351 | ||
352 | uint64_t append_journal_event(const ObjectRequests &requests, | |
353 | bool synchronous) override; | |
354 | void update_stats(size_t length) override; | |
355 | private: | |
356 | bufferlist m_data_bl; | |
357 | int m_op_flags; | |
358 | }; | |
359 | ||
360 | } // namespace io | |
361 | } // namespace librbd | |
362 | ||
363 | extern template class librbd::io::ImageRequest<librbd::ImageCtx>; | |
364 | extern template class librbd::io::ImageReadRequest<librbd::ImageCtx>; | |
365 | extern template class librbd::io::AbstractImageWriteRequest<librbd::ImageCtx>; | |
366 | extern template class librbd::io::ImageWriteRequest<librbd::ImageCtx>; | |
367 | extern template class librbd::io::ImageDiscardRequest<librbd::ImageCtx>; | |
368 | extern template class librbd::io::ImageFlushRequest<librbd::ImageCtx>; | |
369 | extern template class librbd::io::ImageWriteSameRequest<librbd::ImageCtx>; | |
370 | ||
371 | #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_H |