]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/ImageRequest.h
21b88b098cf5736ee2907007357139da61d835c0
[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 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