]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/ImageRequest.h
import 15.2.0 Octopus source
[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 ObjectDispatchSpec;
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,
43 Extents &&image_extents,
44 uint32_t discard_granularity_bytes,
45 const ZTracer::Trace &parent_trace);
46 static void aio_flush(ImageCtxT *ictx, AioCompletion *c,
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);
52
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
58 void send();
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<ObjectDispatchSpec*> 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 virtual bool finish_request_early() {
87 return false;
88 }
89 virtual int clip_request();
90 virtual void update_timestamp();
91 virtual void send_request() = 0;
92 virtual void send_image_cache_request() = 0;
93
94 virtual aio_type_t get_aio_type() const = 0;
95 virtual const char *get_request_type() const = 0;
96 };
97
98 template <typename ImageCtxT = ImageCtx>
99 class ImageReadRequest : public ImageRequest<ImageCtxT> {
100 public:
101 using typename ImageRequest<ImageCtxT>::Extents;
102
103 ImageReadRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
104 Extents &&image_extents, ReadResult &&read_result,
105 int op_flags, const ZTracer::Trace &parent_trace);
106
107 protected:
108 int clip_request() override;
109
110 void send_request() override;
111 void send_image_cache_request() override;
112
113 aio_type_t get_aio_type() const override {
114 return AIO_TYPE_READ;
115 }
116 const char *get_request_type() const override {
117 return "aio_read";
118 }
119 private:
120 int m_op_flags;
121 };
122
123 template <typename ImageCtxT = ImageCtx>
124 class AbstractImageWriteRequest : public ImageRequest<ImageCtxT> {
125 public:
126 inline void flag_synchronous() {
127 m_synchronous = true;
128 }
129
130 protected:
131 using typename ImageRequest<ImageCtxT>::ObjectRequests;
132 using typename ImageRequest<ImageCtxT>::Extents;
133
134 AbstractImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
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),
139 m_synchronous(false) {
140 }
141
142 void send_request() override;
143 bool finish_request_early() override;
144
145 virtual int prune_object_extents(
146 LightweightObjectExtents* object_extents) const {
147 return 0;
148 }
149
150 void send_object_requests(const LightweightObjectExtents &object_extents,
151 const ::SnapContext &snapc, uint64_t journal_tid);
152 virtual ObjectDispatchSpec *create_object_request(
153 const LightweightObjectExtent &object_extent, const ::SnapContext &snapc,
154 uint64_t journal_tid, bool single_extent, Context *on_finish) = 0;
155
156 virtual uint64_t append_journal_event(bool synchronous) = 0;
157 virtual void update_stats(size_t length) = 0;
158
159 private:
160 bool m_synchronous;
161 };
162
163 template <typename ImageCtxT = ImageCtx>
164 class ImageWriteRequest : public AbstractImageWriteRequest<ImageCtxT> {
165 public:
166 using typename ImageRequest<ImageCtxT>::Extents;
167
168 ImageWriteRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
169 Extents &&image_extents, bufferlist &&bl, int op_flags,
170 const ZTracer::Trace &parent_trace)
171 : AbstractImageWriteRequest<ImageCtxT>(
172 image_ctx, aio_comp, std::move(image_extents), "write", parent_trace),
173 m_bl(std::move(bl)), m_op_flags(op_flags) {
174 }
175
176 protected:
177 using typename ImageRequest<ImageCtxT>::ObjectRequests;
178
179 aio_type_t get_aio_type() const override {
180 return AIO_TYPE_WRITE;
181 }
182 const char *get_request_type() const override {
183 return "aio_write";
184 }
185
186 void assemble_extent(const LightweightObjectExtent &object_extent,
187 bufferlist *bl);
188
189 void send_image_cache_request() override;
190
191
192 ObjectDispatchSpec *create_object_request(
193 const LightweightObjectExtent &object_extent, const ::SnapContext &snapc,
194 uint64_t journal_tid, bool single_extent, Context *on_finish) override;
195
196 uint64_t append_journal_event(bool synchronous) override;
197 void update_stats(size_t length) override;
198
199 private:
200 bufferlist m_bl;
201 int m_op_flags;
202 };
203
204 template <typename ImageCtxT = ImageCtx>
205 class ImageDiscardRequest : public AbstractImageWriteRequest<ImageCtxT> {
206 public:
207 ImageDiscardRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
208 Extents&& image_extents,
209 uint32_t discard_granularity_bytes,
210 const ZTracer::Trace &parent_trace)
211 : AbstractImageWriteRequest<ImageCtxT>(
212 image_ctx, aio_comp, std::move(image_extents), "discard", parent_trace),
213 m_discard_granularity_bytes(discard_granularity_bytes) {
214 }
215
216 protected:
217 using typename ImageRequest<ImageCtxT>::ObjectRequests;
218
219 aio_type_t get_aio_type() const override {
220 return AIO_TYPE_DISCARD;
221 }
222 const char *get_request_type() const override {
223 return "aio_discard";
224 }
225
226 void send_image_cache_request() override;
227
228 ObjectDispatchSpec *create_object_request(
229 const LightweightObjectExtent &object_extent, const ::SnapContext &snapc,
230 uint64_t journal_tid, bool single_extent, Context *on_finish) override;
231
232 uint64_t append_journal_event(bool synchronous) override;
233 void update_stats(size_t length) override;
234
235 int prune_object_extents(
236 LightweightObjectExtents* object_extents) const override;
237
238 private:
239 uint32_t m_discard_granularity_bytes;
240 };
241
242 template <typename ImageCtxT = ImageCtx>
243 class ImageFlushRequest : public ImageRequest<ImageCtxT> {
244 public:
245 ImageFlushRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
246 FlushSource flush_source,
247 const ZTracer::Trace &parent_trace)
248 : ImageRequest<ImageCtxT>(image_ctx, aio_comp, {}, "flush", parent_trace),
249 m_flush_source(flush_source) {
250 }
251
252 protected:
253 using typename ImageRequest<ImageCtxT>::ObjectRequests;
254
255 int clip_request() override {
256 return 0;
257 }
258 void update_timestamp() override {
259 }
260 void send_request() override;
261 void send_image_cache_request() override;
262
263 aio_type_t get_aio_type() const override {
264 return AIO_TYPE_FLUSH;
265 }
266 const char *get_request_type() const override {
267 return "aio_flush";
268 }
269
270 private:
271 FlushSource m_flush_source;
272
273 };
274
275 template <typename ImageCtxT = ImageCtx>
276 class ImageWriteSameRequest : public AbstractImageWriteRequest<ImageCtxT> {
277 public:
278 ImageWriteSameRequest(ImageCtxT &image_ctx, AioCompletion *aio_comp,
279 Extents&& image_extents, bufferlist &&bl,
280 int op_flags, const ZTracer::Trace &parent_trace)
281 : AbstractImageWriteRequest<ImageCtxT>(
282 image_ctx, aio_comp, std::move(image_extents), "writesame",
283 parent_trace),
284 m_data_bl(std::move(bl)), m_op_flags(op_flags) {
285 }
286
287 protected:
288 using typename ImageRequest<ImageCtxT>::ObjectRequests;
289
290 aio_type_t get_aio_type() const override {
291 return AIO_TYPE_WRITESAME;
292 }
293 const char *get_request_type() const override {
294 return "aio_writesame";
295 }
296
297 void send_image_cache_request() override;
298
299 ObjectDispatchSpec *create_object_request(
300 const LightweightObjectExtent &object_extent, const ::SnapContext &snapc,
301 uint64_t journal_tid, bool single_extent, Context *on_finish) override;
302
303 uint64_t append_journal_event(bool synchronous) override;
304 void update_stats(size_t length) override;
305 private:
306 bufferlist m_data_bl;
307 int m_op_flags;
308 };
309
310 template <typename ImageCtxT = ImageCtx>
311 class ImageCompareAndWriteRequest : public AbstractImageWriteRequest<ImageCtxT> {
312 public:
313 using typename ImageRequest<ImageCtxT>::ObjectRequests;
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
328 void assemble_extent(const LightweightObjectExtent &object_extent,
329 bufferlist *bl);
330
331 ObjectDispatchSpec *create_object_request(
332 const LightweightObjectExtent &object_extent, const ::SnapContext &snapc,
333 uint64_t journal_tid, bool single_extent, Context *on_finish) override;
334
335 uint64_t append_journal_event(bool synchronous) override;
336 void update_stats(size_t length) override;
337
338 aio_type_t get_aio_type() const override {
339 return AIO_TYPE_COMPARE_AND_WRITE;
340 }
341 const char *get_request_type() const override {
342 return "aio_compare_and_write";
343 }
344
345 int prune_object_extents(
346 LightweightObjectExtents* object_extents) const override;
347
348 private:
349 bufferlist m_cmp_bl;
350 bufferlist m_bl;
351 uint64_t *m_mismatch_offset;
352 int m_op_flags;
353 };
354
355 } // namespace io
356 } // namespace librbd
357
358 extern template class librbd::io::ImageRequest<librbd::ImageCtx>;
359 extern template class librbd::io::ImageReadRequest<librbd::ImageCtx>;
360 extern template class librbd::io::AbstractImageWriteRequest<librbd::ImageCtx>;
361 extern template class librbd::io::ImageWriteRequest<librbd::ImageCtx>;
362 extern template class librbd::io::ImageDiscardRequest<librbd::ImageCtx>;
363 extern template class librbd::io::ImageFlushRequest<librbd::ImageCtx>;
364 extern template class librbd::io::ImageWriteSameRequest<librbd::ImageCtx>;
365 extern template class librbd::io::ImageCompareAndWriteRequest<librbd::ImageCtx>;
366
367 #endif // CEPH_LIBRBD_IO_IMAGE_REQUEST_H