]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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_DISPATCH_SPEC_H | |
5 | #define CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H | |
6 | ||
7 | #include "include/int_types.h" | |
8 | #include "include/buffer.h" | |
9 | #include "common/zipkin_trace.h" | |
10 | #include "librbd/io/Types.h" | |
11 | #include "librbd/io/ReadResult.h" | |
12 | #include <boost/variant/variant.hpp> | |
13 | ||
14 | namespace librbd { | |
15 | ||
16 | class ImageCtx; | |
17 | ||
18 | namespace io { | |
19 | ||
20 | class AioCompletion; | |
21 | ||
22 | template <typename ImageCtxT = ImageCtx> | |
23 | class ImageDispatchSpec { | |
24 | public: | |
25 | struct Read { | |
26 | ReadResult read_result; | |
27 | ||
28 | Read(ReadResult &&read_result) : read_result(std::move(read_result)) { | |
29 | } | |
30 | }; | |
31 | ||
32 | struct Discard { | |
33 | uint32_t discard_granularity_bytes; | |
34 | ||
35 | Discard(uint32_t discard_granularity_bytes) | |
36 | : discard_granularity_bytes(discard_granularity_bytes) { | |
37 | } | |
38 | }; | |
39 | ||
40 | struct Write { | |
41 | bufferlist bl; | |
42 | ||
43 | Write(bufferlist&& bl) : bl(std::move(bl)) { | |
44 | } | |
45 | }; | |
46 | ||
47 | struct WriteSame { | |
48 | bufferlist bl; | |
49 | ||
50 | WriteSame(bufferlist&& bl) : bl(std::move(bl)) { | |
51 | } | |
52 | }; | |
53 | ||
54 | struct CompareAndWrite { | |
55 | bufferlist cmp_bl; | |
56 | bufferlist bl; | |
57 | uint64_t *mismatch_offset; | |
58 | ||
59 | CompareAndWrite(bufferlist&& cmp_bl, bufferlist&& bl, | |
60 | uint64_t *mismatch_offset) | |
61 | : cmp_bl(std::move(cmp_bl)), bl(std::move(bl)), | |
62 | mismatch_offset(mismatch_offset) { | |
63 | } | |
64 | }; | |
65 | ||
66 | struct Flush { | |
67 | FlushSource flush_source; | |
68 | ||
69 | Flush(FlushSource flush_source) : flush_source(flush_source) { | |
70 | } | |
71 | }; | |
72 | ||
73 | static ImageDispatchSpec* create_read_request( | |
74 | ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents, | |
75 | ReadResult &&read_result, int op_flags, | |
76 | const ZTracer::Trace &parent_trace) { | |
77 | return new ImageDispatchSpec(image_ctx, aio_comp, | |
78 | std::move(image_extents), | |
79 | Read{std::move(read_result)}, | |
80 | op_flags, parent_trace); | |
81 | } | |
82 | ||
83 | static ImageDispatchSpec* create_discard_request( | |
84 | ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len, | |
85 | uint32_t discard_granularity_bytes, const ZTracer::Trace &parent_trace) { | |
86 | return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}}, | |
87 | Discard{discard_granularity_bytes}, | |
88 | 0, parent_trace); | |
89 | } | |
90 | ||
91 | static ImageDispatchSpec* create_write_request( | |
92 | ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents, | |
93 | bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace) { | |
94 | return new ImageDispatchSpec(image_ctx, aio_comp, std::move(image_extents), | |
95 | Write{std::move(bl)}, op_flags, parent_trace); | |
96 | } | |
97 | ||
98 | static ImageDispatchSpec* create_write_same_request( | |
99 | ImageCtxT &image_ctx, AioCompletion *aio_comp, uint64_t off, uint64_t len, | |
100 | bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace) { | |
101 | return new ImageDispatchSpec(image_ctx, aio_comp, {{off, len}}, | |
102 | WriteSame{std::move(bl)}, op_flags, | |
103 | parent_trace); | |
104 | } | |
105 | ||
106 | static ImageDispatchSpec* create_compare_and_write_request( | |
107 | ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents, | |
108 | bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset, | |
109 | int op_flags, const ZTracer::Trace &parent_trace) { | |
110 | return new ImageDispatchSpec(image_ctx, aio_comp, | |
111 | std::move(image_extents), | |
112 | CompareAndWrite{std::move(cmp_bl), | |
113 | std::move(bl), | |
114 | mismatch_offset}, | |
115 | op_flags, parent_trace); | |
116 | } | |
117 | ||
118 | static ImageDispatchSpec* create_flush_request( | |
119 | ImageCtxT &image_ctx, AioCompletion *aio_comp, | |
120 | FlushSource flush_source, const ZTracer::Trace &parent_trace) { | |
121 | return new ImageDispatchSpec(image_ctx, aio_comp, {}, Flush{flush_source}, | |
122 | 0, parent_trace); | |
123 | } | |
124 | ||
125 | void send(); | |
126 | void fail(int r); | |
127 | ||
128 | bool is_write_op() const; | |
129 | ||
130 | void start_op(); | |
131 | ||
81eedcae | 132 | bool tokens_requested(uint64_t flag, uint64_t *tokens); |
11fdf7f2 TL |
133 | |
134 | bool was_throttled(uint64_t flag) { | |
135 | return m_throttled_flag & flag; | |
136 | } | |
137 | ||
138 | void set_throttled(uint64_t flag) { | |
139 | m_throttled_flag |= flag; | |
140 | } | |
141 | ||
142 | bool were_all_throttled() { | |
143 | return (m_throttled_flag & RBD_QOS_MASK) == RBD_QOS_MASK; | |
144 | } | |
145 | ||
146 | private: | |
147 | typedef boost::variant<Read, | |
148 | Discard, | |
149 | Write, | |
150 | WriteSame, | |
151 | CompareAndWrite, | |
152 | Flush> Request; | |
153 | ||
154 | struct SendVisitor; | |
155 | struct IsWriteOpVisitor; | |
156 | struct TokenRequestedVisitor; | |
157 | ||
158 | ImageDispatchSpec(ImageCtxT& image_ctx, AioCompletion* aio_comp, | |
159 | Extents&& image_extents, Request&& request, | |
160 | int op_flags, const ZTracer::Trace& parent_trace) | |
161 | : m_image_ctx(image_ctx), m_aio_comp(aio_comp), | |
162 | m_image_extents(std::move(image_extents)), m_request(std::move(request)), | |
163 | m_op_flags(op_flags), m_parent_trace(parent_trace) { | |
164 | } | |
165 | ||
166 | ImageCtxT& m_image_ctx; | |
167 | AioCompletion* m_aio_comp; | |
168 | Extents m_image_extents; | |
169 | Request m_request; | |
170 | int m_op_flags; | |
171 | ZTracer::Trace m_parent_trace; | |
172 | std::atomic<uint64_t> m_throttled_flag = 0; | |
173 | ||
174 | uint64_t extents_length(); | |
175 | }; | |
176 | ||
177 | } // namespace io | |
178 | } // namespace librbd | |
179 | ||
180 | extern template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>; | |
181 | ||
182 | #endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H |