]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/ImageRequest.h
update sources to v12.1.1
[ceph.git] / ceph / src / librbd / io / ImageRequest.h
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 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
61 static void aio_read(ImageCtxT *ictx, AioCompletion *c,
62 Extents &&image_extents, ReadResult &&read_result,
63 int op_flags, const ZTracer::Trace &parent_trace);
64 static void aio_write(ImageCtxT *ictx, AioCompletion *c,
65 Extents &&image_extents, bufferlist &&bl, int op_flags,
66 const ZTracer::Trace &parent_trace);
67 static void aio_discard(ImageCtxT *ictx, AioCompletion *c, uint64_t off,
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);
72 static void aio_writesame(ImageCtxT *ictx, AioCompletion *c, uint64_t off,
73 uint64_t len, bufferlist &&bl, int op_flags,
74 const ZTracer::Trace &parent_trace);
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
89 inline const ZTracer::Trace &get_trace() const {
90 return m_trace;
91 }
92
93 protected:
94 typedef std::list<ObjectRequestHandle *> ObjectRequests;
95
96 ImageCtxT &m_image_ctx;
97 AioCompletion *m_aio_comp;
98 Extents m_image_extents;
99 ZTracer::Trace m_trace;
100 bool m_bypass_image_cache = false;
101
102 ImageRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
103 Extents &&image_extents, const char *trace_name,
104 const ZTracer::Trace &parent_trace)
105 : m_image_ctx(image_ctx), m_aio_comp(aio_comp),
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");
109 }
110
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,
127 int op_flags, const ZTracer::Trace &parent_trace);
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,
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),
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,
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),
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,
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),
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:
289 ImageFlushRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
290 const ZTracer::Trace &parent_trace)
291 : ImageRequest<ImageCtxT>(image_ctx, aio_comp, {}, "flush", parent_trace) {
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,
320 int op_flags, const ZTracer::Trace &parent_trace)
321 : AbstractImageWriteRequest<ImageCtxT>(
322 image_ctx, aio_comp, {{off, len}}, "writesame", parent_trace),
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