]> git.proxmox.com Git - ceph.git/blob - ceph/src/librbd/io/Types.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / librbd / io / Types.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_TYPES_H
5 #define CEPH_LIBRBD_IO_TYPES_H
6
7 #include "include/int_types.h"
8 #include "include/rados/rados_types.hpp"
9 #include "common/interval_map.h"
10 #include "osdc/StriperTypes.h"
11 #include <iosfwd>
12 #include <map>
13 #include <vector>
14
15 struct Context;
16
17 namespace librbd {
18 namespace io {
19
20 typedef enum {
21 AIO_TYPE_NONE = 0,
22 AIO_TYPE_GENERIC,
23 AIO_TYPE_OPEN,
24 AIO_TYPE_CLOSE,
25 AIO_TYPE_READ,
26 AIO_TYPE_WRITE,
27 AIO_TYPE_DISCARD,
28 AIO_TYPE_FLUSH,
29 AIO_TYPE_WRITESAME,
30 AIO_TYPE_COMPARE_AND_WRITE,
31 } aio_type_t;
32
33 enum FlushSource {
34 FLUSH_SOURCE_USER,
35 FLUSH_SOURCE_INTERNAL,
36 FLUSH_SOURCE_SHUTDOWN,
37 FLUSH_SOURCE_EXCLUSIVE_LOCK,
38 FLUSH_SOURCE_EXCLUSIVE_LOCK_SKIP_REFRESH,
39 FLUSH_SOURCE_REFRESH,
40 FLUSH_SOURCE_WRITEBACK,
41 FLUSH_SOURCE_WRITE_BLOCK,
42 };
43
44 enum Direction {
45 DIRECTION_READ,
46 DIRECTION_WRITE,
47 DIRECTION_BOTH
48 };
49
50 enum DispatchResult {
51 DISPATCH_RESULT_INVALID,
52 DISPATCH_RESULT_RESTART,
53 DISPATCH_RESULT_CONTINUE,
54 DISPATCH_RESULT_COMPLETE
55 };
56
57 enum ImageDispatchLayer {
58 IMAGE_DISPATCH_LAYER_NONE = 0,
59 IMAGE_DISPATCH_LAYER_API_START = IMAGE_DISPATCH_LAYER_NONE,
60 IMAGE_DISPATCH_LAYER_QUEUE,
61 IMAGE_DISPATCH_LAYER_QOS,
62 IMAGE_DISPATCH_LAYER_EXCLUSIVE_LOCK,
63 IMAGE_DISPATCH_LAYER_REFRESH,
64 IMAGE_DISPATCH_LAYER_INTERNAL_START = IMAGE_DISPATCH_LAYER_REFRESH,
65 IMAGE_DISPATCH_LAYER_MIGRATION,
66 IMAGE_DISPATCH_LAYER_JOURNAL,
67 IMAGE_DISPATCH_LAYER_WRITE_BLOCK,
68 IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE,
69 IMAGE_DISPATCH_LAYER_CRYPTO,
70 IMAGE_DISPATCH_LAYER_CORE,
71 IMAGE_DISPATCH_LAYER_LAST
72 };
73
74 enum {
75 IMAGE_DISPATCH_FLAG_QOS_IOPS_THROTTLE = 1 << 0,
76 IMAGE_DISPATCH_FLAG_QOS_BPS_THROTTLE = 1 << 1,
77 IMAGE_DISPATCH_FLAG_QOS_READ_IOPS_THROTTLE = 1 << 2,
78 IMAGE_DISPATCH_FLAG_QOS_WRITE_IOPS_THROTTLE = 1 << 3,
79 IMAGE_DISPATCH_FLAG_QOS_READ_BPS_THROTTLE = 1 << 4,
80 IMAGE_DISPATCH_FLAG_QOS_WRITE_BPS_THROTTLE = 1 << 5,
81 IMAGE_DISPATCH_FLAG_QOS_BPS_MASK = (
82 IMAGE_DISPATCH_FLAG_QOS_BPS_THROTTLE |
83 IMAGE_DISPATCH_FLAG_QOS_READ_BPS_THROTTLE |
84 IMAGE_DISPATCH_FLAG_QOS_WRITE_BPS_THROTTLE),
85 IMAGE_DISPATCH_FLAG_QOS_IOPS_MASK = (
86 IMAGE_DISPATCH_FLAG_QOS_IOPS_THROTTLE |
87 IMAGE_DISPATCH_FLAG_QOS_READ_IOPS_THROTTLE |
88 IMAGE_DISPATCH_FLAG_QOS_WRITE_IOPS_THROTTLE),
89 IMAGE_DISPATCH_FLAG_QOS_READ_MASK = (
90 IMAGE_DISPATCH_FLAG_QOS_READ_IOPS_THROTTLE |
91 IMAGE_DISPATCH_FLAG_QOS_READ_BPS_THROTTLE),
92 IMAGE_DISPATCH_FLAG_QOS_WRITE_MASK = (
93 IMAGE_DISPATCH_FLAG_QOS_WRITE_IOPS_THROTTLE |
94 IMAGE_DISPATCH_FLAG_QOS_WRITE_BPS_THROTTLE),
95 IMAGE_DISPATCH_FLAG_QOS_MASK = (
96 IMAGE_DISPATCH_FLAG_QOS_BPS_MASK |
97 IMAGE_DISPATCH_FLAG_QOS_IOPS_MASK),
98
99 // TODO: pass area through ImageDispatchInterface and remove
100 // this flag
101 IMAGE_DISPATCH_FLAG_CRYPTO_HEADER = 1 << 6
102 };
103
104 enum {
105 RBD_IO_OPERATIONS_DEFAULT = 0,
106 RBD_IO_OPERATION_READ = 1 << 0,
107 RBD_IO_OPERATION_WRITE = 1 << 1,
108 RBD_IO_OPERATION_DISCARD = 1 << 2,
109 RBD_IO_OPERATION_WRITE_SAME = 1 << 3,
110 RBD_IO_OPERATION_COMPARE_AND_WRITE = 1 << 4,
111 RBD_IO_OPERATIONS_ALL = (
112 RBD_IO_OPERATION_READ |
113 RBD_IO_OPERATION_WRITE |
114 RBD_IO_OPERATION_DISCARD |
115 RBD_IO_OPERATION_WRITE_SAME |
116 RBD_IO_OPERATION_COMPARE_AND_WRITE)
117 };
118
119 enum ObjectDispatchLayer {
120 OBJECT_DISPATCH_LAYER_NONE = 0,
121 OBJECT_DISPATCH_LAYER_CACHE,
122 OBJECT_DISPATCH_LAYER_CRYPTO,
123 OBJECT_DISPATCH_LAYER_JOURNAL,
124 OBJECT_DISPATCH_LAYER_PARENT_CACHE,
125 OBJECT_DISPATCH_LAYER_SCHEDULER,
126 OBJECT_DISPATCH_LAYER_CORE,
127 OBJECT_DISPATCH_LAYER_LAST
128 };
129
130 enum {
131 READ_FLAG_DISABLE_READ_FROM_PARENT = 1UL << 0,
132 READ_FLAG_DISABLE_CLIPPING = 1UL << 1,
133 };
134
135 enum {
136 OBJECT_WRITE_FLAG_CREATE_EXCLUSIVE = 1UL << 0
137 };
138
139 enum {
140 OBJECT_DISCARD_FLAG_DISABLE_CLONE_REMOVE = 1UL << 0,
141 OBJECT_DISCARD_FLAG_DISABLE_OBJECT_MAP_UPDATE = 1UL << 1
142 };
143
144 enum {
145 OBJECT_DISPATCH_FLAG_FLUSH = 1UL << 0,
146 OBJECT_DISPATCH_FLAG_WILL_RETRY_ON_ERROR = 1UL << 1
147 };
148
149 enum {
150 LIST_SNAPS_FLAG_DISABLE_LIST_FROM_PARENT = 1UL << 0,
151 LIST_SNAPS_FLAG_WHOLE_OBJECT = 1UL << 1,
152 LIST_SNAPS_FLAG_IGNORE_ZEROED_EXTENTS = 1UL << 2,
153 };
154
155 enum SparseExtentState {
156 SPARSE_EXTENT_STATE_DNE, /* does not exist */
157 SPARSE_EXTENT_STATE_ZEROED,
158 SPARSE_EXTENT_STATE_DATA
159 };
160
161 std::ostream& operator<<(std::ostream& os, SparseExtentState state);
162
163 struct SparseExtent {
164 SparseExtentState state;
165 uint64_t length;
166
167 SparseExtent(SparseExtentState state, uint64_t length)
168 : state(state), length(length) {
169 }
170
171 operator SparseExtentState() const {
172 return state;
173 }
174
175 bool operator==(const SparseExtent& rhs) const {
176 return state == rhs.state && length == rhs.length;
177 }
178 };
179
180 std::ostream& operator<<(std::ostream& os, const SparseExtent& state);
181
182 struct SparseExtentSplitMerge {
183 SparseExtent split(uint64_t offset, uint64_t length, SparseExtent &se) const {
184 return SparseExtent(se.state, se.length);
185 }
186
187 bool can_merge(const SparseExtent& left, const SparseExtent& right) const {
188 return left.state == right.state;
189 }
190
191 SparseExtent merge(SparseExtent&& left, SparseExtent&& right) const {
192 SparseExtent se(left);
193 se.length += right.length;
194 return se;
195 }
196
197 uint64_t length(const SparseExtent& se) const {
198 return se.length;
199 }
200 };
201
202 typedef interval_map<uint64_t,
203 SparseExtent,
204 SparseExtentSplitMerge> SparseExtents;
205
206 typedef std::vector<uint64_t> SnapIds;
207
208 typedef std::pair<librados::snap_t, librados::snap_t> WriteReadSnapIds;
209 extern const WriteReadSnapIds INITIAL_WRITE_READ_SNAP_IDS;
210
211 typedef std::map<WriteReadSnapIds, SparseExtents> SnapshotDelta;
212
213 struct SparseBufferlistExtent : public SparseExtent {
214 ceph::bufferlist bl;
215
216 SparseBufferlistExtent(SparseExtentState state, uint64_t length)
217 : SparseExtent(state, length) {
218 ceph_assert(state != SPARSE_EXTENT_STATE_DATA);
219 }
220 SparseBufferlistExtent(SparseExtentState state, uint64_t length,
221 ceph::bufferlist&& bl_)
222 : SparseExtent(state, length), bl(std::move(bl_)) {
223 ceph_assert(state != SPARSE_EXTENT_STATE_DATA || length == bl.length());
224 }
225
226 bool operator==(const SparseBufferlistExtent& rhs) const {
227 return (state == rhs.state &&
228 length == rhs.length &&
229 bl.contents_equal(rhs.bl));
230 }
231 };
232
233 struct SparseBufferlistExtentSplitMerge {
234 SparseBufferlistExtent split(uint64_t offset, uint64_t length,
235 SparseBufferlistExtent& sbe) const {
236 ceph::bufferlist bl;
237 if (sbe.state == SPARSE_EXTENT_STATE_DATA) {
238 bl.substr_of(bl, offset, length);
239 }
240 return SparseBufferlistExtent(sbe.state, length, std::move(bl));
241 }
242
243 bool can_merge(const SparseBufferlistExtent& left,
244 const SparseBufferlistExtent& right) const {
245 return left.state == right.state;
246 }
247
248 SparseBufferlistExtent merge(SparseBufferlistExtent&& left,
249 SparseBufferlistExtent&& right) const {
250 if (left.state == SPARSE_EXTENT_STATE_DATA) {
251 ceph::bufferlist bl{std::move(left.bl)};
252 bl.claim_append(std::move(right.bl));
253 return SparseBufferlistExtent(SPARSE_EXTENT_STATE_DATA,
254 bl.length(), std::move(bl));
255 } else {
256 return SparseBufferlistExtent(left.state, left.length + right.length, {});
257 }
258 }
259
260 uint64_t length(const SparseBufferlistExtent& sbe) const {
261 return sbe.length;
262 }
263 };
264
265 typedef interval_map<uint64_t,
266 SparseBufferlistExtent,
267 SparseBufferlistExtentSplitMerge> SparseBufferlist;
268 typedef std::map<uint64_t, SparseBufferlist> SnapshotSparseBufferlist;
269
270 using striper::LightweightBufferExtents;
271 using striper::LightweightObjectExtent;
272 using striper::LightweightObjectExtents;
273
274 typedef std::pair<uint64_t,uint64_t> Extent;
275 typedef std::vector<Extent> Extents;
276
277 enum class ImageArea {
278 DATA,
279 CRYPTO_HEADER
280 };
281
282 std::ostream& operator<<(std::ostream& os, ImageArea area);
283
284 struct ReadExtent {
285 const uint64_t offset;
286 const uint64_t length;
287 const LightweightBufferExtents buffer_extents;
288 ceph::bufferlist bl;
289 Extents extent_map;
290
291 ReadExtent(uint64_t offset,
292 uint64_t length) : offset(offset), length(length) {};
293 ReadExtent(uint64_t offset,
294 uint64_t length,
295 const LightweightBufferExtents&& buffer_extents)
296 : offset(offset),
297 length(length),
298 buffer_extents(buffer_extents) {}
299 ReadExtent(uint64_t offset,
300 uint64_t length,
301 const LightweightBufferExtents&& buffer_extents,
302 ceph::bufferlist&& bl,
303 Extents&& extent_map) : offset(offset),
304 length(length),
305 buffer_extents(buffer_extents),
306 bl(bl),
307 extent_map(extent_map) {};
308
309 friend inline std::ostream& operator<<(
310 std::ostream& os,
311 const ReadExtent &extent) {
312 os << "offset=" << extent.offset << ", "
313 << "length=" << extent.length << ", "
314 << "buffer_extents=" << extent.buffer_extents << ", "
315 << "bl.length=" << extent.bl.length() << ", "
316 << "extent_map=" << extent.extent_map;
317 return os;
318 }
319 };
320
321 typedef std::vector<ReadExtent> ReadExtents;
322
323 typedef std::map<uint64_t, uint64_t> ExtentMap;
324
325 } // namespace io
326 } // namespace librbd
327
328 #endif // CEPH_LIBRBD_IO_TYPES_H