]>
Commit | Line | Data |
---|---|---|
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" | |
10 | #include "common/zipkin_trace.h" | |
11 | #include "osd/osd_types.h" | |
12 | #include "librbd/Utils.h" | |
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 | ||
32 | virtual ~ImageRequest() { | |
33 | m_trace.event("finish"); | |
34 | } | |
35 | ||
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); | |
50 | ||
51 | virtual bool is_write_op() const { | |
52 | return false; | |
53 | } | |
54 | ||
55 | void start_op(); | |
56 | ||
57 | void send(); | |
58 | void fail(int r); | |
59 | ||
60 | void set_bypass_image_cache() { | |
61 | m_bypass_image_cache = true; | |
62 | } | |
63 | ||
64 | inline const ZTracer::Trace &get_trace() const { | |
65 | return m_trace; | |
66 | } | |
67 | ||
68 | protected: | |
69 | typedef std::list<ObjectRequestHandle *> ObjectRequests; | |
70 | ||
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; | |
76 | ||
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"); | |
84 | } | |
85 | ||
86 | ||
87 | virtual int clip_request(); | |
88 | virtual void send_request() = 0; | |
89 | virtual void send_image_cache_request() = 0; | |
90 | ||
91 | virtual aio_type_t get_aio_type() const = 0; | |
92 | virtual const char *get_request_type() const = 0; | |
93 | }; | |
94 | ||
95 | template <typename ImageCtxT = ImageCtx> | |
96 | class ImageReadRequest : public ImageRequest<ImageCtxT> { | |
97 | public: | |
98 | using typename ImageRequest<ImageCtxT>::Extents; | |
99 | ||
100 | ImageReadRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
101 | Extents &&image_extents, ReadResult &&read_result, | |
102 | int op_flags, const ZTracer::Trace &parent_trace); | |
103 | ||
104 | protected: | |
105 | int clip_request() override; | |
106 | ||
107 | void send_request() override; | |
108 | void send_image_cache_request() override; | |
109 | ||
110 | aio_type_t get_aio_type() const override { | |
111 | return AIO_TYPE_READ; | |
112 | } | |
113 | const char *get_request_type() const override { | |
114 | return "aio_read"; | |
115 | } | |
116 | private: | |
117 | char *m_buf; | |
118 | bufferlist *m_pbl; | |
119 | int m_op_flags; | |
120 | }; | |
121 | ||
122 | template <typename ImageCtxT = ImageCtx> | |
123 | class AbstractImageWriteRequest : public ImageRequest<ImageCtxT> { | |
124 | public: | |
125 | bool is_write_op() const override { | |
126 | return true; | |
127 | } | |
128 | ||
129 | inline void flag_synchronous() { | |
130 | m_synchronous = true; | |
131 | } | |
132 | ||
133 | protected: | |
134 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
135 | using typename ImageRequest<ImageCtxT>::Extents; | |
136 | ||
137 | typedef std::vector<ObjectExtent> ObjectExtents; | |
138 | ||
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) { | |
145 | } | |
146 | ||
147 | void send_request() override; | |
148 | ||
149 | virtual void prune_object_extents(ObjectExtents &object_extents) { | |
150 | } | |
151 | virtual uint32_t get_object_cache_request_count(bool journaling) const { | |
152 | return 0; | |
153 | } | |
154 | virtual void send_object_cache_requests(const ObjectExtents &object_extents, | |
155 | uint64_t journal_tid) = 0; | |
156 | ||
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; | |
163 | ||
164 | virtual uint64_t append_journal_event(const ObjectRequests &requests, | |
165 | bool synchronous) = 0; | |
166 | virtual void update_stats(size_t length) = 0; | |
167 | ||
168 | private: | |
169 | bool m_synchronous; | |
170 | }; | |
171 | ||
172 | template <typename ImageCtxT = ImageCtx> | |
173 | class ImageWriteRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
174 | public: | |
175 | using typename ImageRequest<ImageCtxT>::Extents; | |
176 | ||
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) { | |
183 | } | |
184 | ||
185 | protected: | |
186 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
187 | using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents; | |
188 | ||
189 | aio_type_t get_aio_type() const override { | |
190 | return AIO_TYPE_WRITE; | |
191 | } | |
192 | const char *get_request_type() const override { | |
193 | return "aio_write"; | |
194 | } | |
195 | ||
196 | void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl); | |
197 | ||
198 | void send_image_cache_request() override; | |
199 | ||
200 | void send_object_cache_requests(const ObjectExtents &object_extents, | |
201 | uint64_t journal_tid) override; | |
202 | ||
203 | void send_object_requests(const ObjectExtents &object_extents, | |
204 | const ::SnapContext &snapc, | |
205 | ObjectRequests *aio_object_requests) override; | |
206 | ||
207 | ObjectRequestHandle *create_object_request( | |
208 | const ObjectExtent &object_extent, const ::SnapContext &snapc, | |
209 | Context *on_finish) override; | |
210 | ||
211 | uint64_t append_journal_event(const ObjectRequests &requests, | |
212 | bool synchronous) override; | |
213 | void update_stats(size_t length) override; | |
214 | ||
215 | private: | |
216 | bufferlist m_bl; | |
217 | int m_op_flags; | |
218 | }; | |
219 | ||
220 | template <typename ImageCtxT = ImageCtx> | |
221 | class ImageDiscardRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
222 | public: | |
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) { | |
229 | } | |
230 | ||
231 | protected: | |
232 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
233 | using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents; | |
234 | ||
235 | aio_type_t get_aio_type() const override { | |
236 | return AIO_TYPE_DISCARD; | |
237 | } | |
238 | const char *get_request_type() const override { | |
239 | return "aio_discard"; | |
240 | } | |
241 | ||
242 | void prune_object_extents(ObjectExtents &object_extents) override; | |
243 | ||
244 | void send_image_cache_request() override; | |
245 | ||
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; | |
249 | ||
250 | ObjectRequestHandle *create_object_request( | |
251 | const ObjectExtent &object_extent, const ::SnapContext &snapc, | |
252 | Context *on_finish) override; | |
253 | ||
254 | uint64_t append_journal_event(const ObjectRequests &requests, | |
255 | bool synchronous) override; | |
256 | void update_stats(size_t length) override; | |
257 | private: | |
258 | bool m_skip_partial_discard; | |
259 | }; | |
260 | ||
261 | template <typename ImageCtxT = ImageCtx> | |
262 | class ImageFlushRequest : public ImageRequest<ImageCtxT> { | |
263 | public: | |
264 | ImageFlushRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
265 | const ZTracer::Trace &parent_trace) | |
266 | : ImageRequest<ImageCtxT>(image_ctx, aio_comp, {}, "flush", parent_trace) { | |
267 | } | |
268 | ||
269 | bool is_write_op() const override { | |
270 | return true; | |
271 | } | |
272 | ||
273 | protected: | |
274 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
275 | ||
276 | int clip_request() override { | |
277 | return 0; | |
278 | } | |
279 | void send_request() override; | |
280 | void send_image_cache_request() override; | |
281 | ||
282 | aio_type_t get_aio_type() const override { | |
283 | return AIO_TYPE_FLUSH; | |
284 | } | |
285 | const char *get_request_type() const override { | |
286 | return "aio_flush"; | |
287 | } | |
288 | }; | |
289 | ||
290 | template <typename ImageCtxT = ImageCtx> | |
291 | class ImageWriteSameRequest : public AbstractImageWriteRequest<ImageCtxT> { | |
292 | public: | |
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) { | |
299 | } | |
300 | ||
301 | protected: | |
302 | using typename ImageRequest<ImageCtxT>::ObjectRequests; | |
303 | using typename AbstractImageWriteRequest<ImageCtxT>::ObjectExtents; | |
304 | ||
305 | aio_type_t get_aio_type() const override { | |
306 | return AIO_TYPE_WRITESAME; | |
307 | } | |
308 | const char *get_request_type() const override { | |
309 | return "aio_writesame"; | |
310 | } | |
311 | ||
312 | bool assemble_writesame_extent(const ObjectExtent &object_extent, | |
313 | bufferlist *bl, bool force_write); | |
314 | ||
315 | void send_image_cache_request() override; | |
316 | ||
317 | void send_object_cache_requests(const ObjectExtents &object_extents, | |
318 | uint64_t journal_tid) override; | |
319 | ||
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; | |
326 | ||
327 | uint64_t append_journal_event(const ObjectRequests &requests, | |
328 | bool synchronous) override; | |
329 | void update_stats(size_t length) override; | |
330 | private: | |
331 | bufferlist m_data_bl; | |
332 | int m_op_flags; | |
333 | }; | |
334 | ||
335 | } // namespace io | |
336 | } // namespace librbd | |
337 | ||
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>; | |
345 | ||
346 | #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_H |