]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
7c673cae FG |
2 | // vim: ts=8 sw=2 smarttab |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net> | |
7 | * | |
8 | * This is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
11fdf7f2 | 10 | * License version 2.1, as published by the Free Software |
7c673cae | 11 | * Foundation. See file COPYING. |
11fdf7f2 | 12 | * |
7c673cae FG |
13 | */ |
14 | #ifndef CEPH_TYPES_H | |
15 | #define CEPH_TYPES_H | |
16 | ||
17 | // this is needed for ceph_fs to compile in userland | |
18 | #include "int_types.h" | |
19 | #include "byteorder.h" | |
20 | ||
21 | #include "uuid.h" | |
22 | ||
23 | #include <netinet/in.h> | |
24 | #include <fcntl.h> | |
25 | #include <string.h> | |
26 | ||
7c673cae FG |
27 | #include "ceph_fs.h" |
28 | #include "ceph_frag.h" | |
29 | #include "rbd_types.h" | |
7c673cae FG |
30 | |
31 | #ifdef __cplusplus | |
32 | #ifndef _BACKWARD_BACKWARD_WARNING_H | |
33 | #define _BACKWARD_BACKWARD_WARNING_H // make gcc 4.3 shut up about hash_* | |
34 | #endif | |
35 | #endif | |
36 | ||
37 | extern "C" { | |
38 | #include <stdint.h> | |
39 | #include <sys/types.h> | |
40 | #include <sys/stat.h> | |
41 | #include "statlite.h" | |
42 | } | |
43 | ||
44 | #include <string> | |
45 | #include <list> | |
46 | #include <set> | |
11fdf7f2 TL |
47 | #include <boost/container/flat_set.hpp> |
48 | #include <boost/container/flat_map.hpp> | |
7c673cae FG |
49 | #include <map> |
50 | #include <vector> | |
9f95a23c | 51 | #include <optional> |
f67539c2 | 52 | #include <ostream> |
7c673cae FG |
53 | #include <iomanip> |
54 | ||
7c673cae FG |
55 | |
56 | #include "include/unordered_map.h" | |
57 | ||
58 | #include "object.h" | |
59 | #include "intarith.h" | |
60 | ||
61 | #include "acconfig.h" | |
62 | ||
63 | #include "assert.h" | |
64 | ||
65 | // DARWIN compatibility | |
11fdf7f2 | 66 | #ifdef __APPLE__ |
7c673cae FG |
67 | typedef long long loff_t; |
68 | typedef long long off64_t; | |
69 | #define O_DIRECT 00040000 | |
70 | #endif | |
71 | ||
72 | // FreeBSD compatibility | |
73 | #ifdef __FreeBSD__ | |
74 | typedef off_t loff_t; | |
75 | typedef off_t off64_t; | |
76 | #endif | |
77 | ||
78 | #if defined(__sun) || defined(_AIX) | |
79 | typedef off_t loff_t; | |
80 | #endif | |
81 | ||
82 | ||
83 | // -- io helpers -- | |
84 | ||
31f18b77 FG |
85 | // Forward declare all the I/O helpers so strict ADL can find them in |
86 | // the case of containers of containers. I'm tempted to abstract this | |
87 | // stuff using template templates like I did for denc. | |
88 | ||
11fdf7f2 | 89 | namespace std { |
31f18b77 | 90 | template<class A, class B> |
11fdf7f2 | 91 | inline std::ostream& operator<<(std::ostream&out, const std::pair<A,B>& v); |
31f18b77 | 92 | template<class A, class Alloc> |
11fdf7f2 TL |
93 | inline std::ostream& operator<<(std::ostream& out, const std::vector<A,Alloc>& v); |
94 | template<class A, std::size_t N, class Alloc> | |
95 | inline std::ostream& operator<<(std::ostream& out, const boost::container::small_vector<A,N,Alloc>& v); | |
31f18b77 | 96 | template<class A, class Comp, class Alloc> |
11fdf7f2 TL |
97 | inline std::ostream& operator<<(std::ostream& out, const std::deque<A,Alloc>& v); |
98 | template<typename... Ts> | |
99 | inline std::ostream& operator<<(std::ostream& out, const std::tuple<Ts...> &t); | |
9f95a23c TL |
100 | template<typename T> |
101 | inline std::ostream& operator<<(std::ostream& out, const std::optional<T> &t); | |
31f18b77 | 102 | template<class A, class Alloc> |
11fdf7f2 | 103 | inline std::ostream& operator<<(std::ostream& out, const std::list<A,Alloc>& ilist); |
31f18b77 | 104 | template<class A, class Comp, class Alloc> |
11fdf7f2 | 105 | inline std::ostream& operator<<(std::ostream& out, const std::set<A, Comp, Alloc>& iset); |
31f18b77 | 106 | template<class A, class Comp, class Alloc> |
11fdf7f2 TL |
107 | inline std::ostream& operator<<(std::ostream& out, const std::multiset<A,Comp,Alloc>& iset); |
108 | template<class A, class B, class Comp, class Alloc> | |
109 | inline std::ostream& operator<<(std::ostream& out, const std::map<A,B,Comp,Alloc>& m); | |
31f18b77 | 110 | template<class A, class B, class Comp, class Alloc> |
11fdf7f2 TL |
111 | inline std::ostream& operator<<(std::ostream& out, const std::multimap<A,B,Comp,Alloc>& m); |
112 | } | |
113 | ||
114 | namespace boost { | |
115 | template<typename... Ts> | |
116 | inline std::ostream& operator<<(std::ostream& out, const boost::tuple<Ts...> &t); | |
117 | ||
118 | namespace container { | |
119 | template<class A, class Comp, class Alloc> | |
120 | inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_set<A, Comp, Alloc>& iset); | |
31f18b77 | 121 | template<class A, class B, class Comp, class Alloc> |
11fdf7f2 TL |
122 | inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_map<A, B, Comp, Alloc>& iset); |
123 | } | |
124 | } | |
31f18b77 | 125 | |
11fdf7f2 | 126 | namespace std { |
7c673cae | 127 | template<class A, class B> |
11fdf7f2 | 128 | inline std::ostream& operator<<(std::ostream& out, const std::pair<A,B>& v) { |
7c673cae FG |
129 | return out << v.first << "," << v.second; |
130 | } | |
131 | ||
132 | template<class A, class Alloc> | |
11fdf7f2 TL |
133 | inline std::ostream& operator<<(std::ostream& out, const std::vector<A,Alloc>& v) { |
134 | bool first = true; | |
7c673cae | 135 | out << "["; |
11fdf7f2 TL |
136 | for (const auto& p : v) { |
137 | if (!first) out << ","; | |
138 | out << p; | |
139 | first = false; | |
7c673cae FG |
140 | } |
141 | out << "]"; | |
142 | return out; | |
143 | } | |
11fdf7f2 TL |
144 | |
145 | template<class A, std::size_t N, class Alloc> | |
146 | inline std::ostream& operator<<(std::ostream& out, const boost::container::small_vector<A,N,Alloc>& v) { | |
147 | bool first = true; | |
148 | out << "["; | |
149 | for (const auto& p : v) { | |
150 | if (!first) out << ","; | |
151 | out << p; | |
152 | first = false; | |
153 | } | |
154 | out << "]"; | |
155 | return out; | |
156 | } | |
157 | ||
7c673cae | 158 | template<class A, class Alloc> |
11fdf7f2 | 159 | inline std::ostream& operator<<(std::ostream& out, const std::deque<A,Alloc>& v) { |
7c673cae FG |
160 | out << "<"; |
161 | for (auto p = v.begin(); p != v.end(); ++p) { | |
162 | if (p != v.begin()) out << ","; | |
163 | out << *p; | |
164 | } | |
165 | out << ">"; | |
166 | return out; | |
167 | } | |
168 | ||
11fdf7f2 TL |
169 | template<typename... Ts> |
170 | inline std::ostream& operator<<(std::ostream& out, const std::tuple<Ts...> &t) { | |
171 | auto f = [n = sizeof...(Ts), i = 0U, &out](const auto& e) mutable { | |
172 | out << e; | |
173 | if (++i != n) | |
174 | out << ","; | |
175 | }; | |
176 | ceph::for_each(t, f); | |
7c673cae FG |
177 | return out; |
178 | } | |
179 | ||
9f95a23c TL |
180 | // Mimics boost::optional |
181 | template<typename T> | |
182 | inline std::ostream& operator<<(std::ostream& out, const std::optional<T> &t) { | |
183 | if (!t) | |
184 | out << "--" ; | |
185 | else | |
186 | out << ' ' << *t ; | |
187 | return out; | |
188 | } | |
189 | ||
7c673cae | 190 | template<class A, class Alloc> |
11fdf7f2 | 191 | inline std::ostream& operator<<(std::ostream& out, const std::list<A,Alloc>& ilist) { |
7c673cae FG |
192 | for (auto it = ilist.begin(); |
193 | it != ilist.end(); | |
194 | ++it) { | |
195 | if (it != ilist.begin()) out << ","; | |
196 | out << *it; | |
197 | } | |
198 | return out; | |
199 | } | |
200 | ||
201 | template<class A, class Comp, class Alloc> | |
11fdf7f2 | 202 | inline std::ostream& operator<<(std::ostream& out, const std::set<A, Comp, Alloc>& iset) { |
7c673cae FG |
203 | for (auto it = iset.begin(); |
204 | it != iset.end(); | |
205 | ++it) { | |
206 | if (it != iset.begin()) out << ","; | |
207 | out << *it; | |
208 | } | |
209 | return out; | |
210 | } | |
211 | ||
212 | template<class A, class Comp, class Alloc> | |
11fdf7f2 | 213 | inline std::ostream& operator<<(std::ostream& out, const std::multiset<A,Comp,Alloc>& iset) { |
7c673cae FG |
214 | for (auto it = iset.begin(); |
215 | it != iset.end(); | |
216 | ++it) { | |
217 | if (it != iset.begin()) out << ","; | |
218 | out << *it; | |
219 | } | |
220 | return out; | |
221 | } | |
222 | ||
223 | template<class A, class B, class Comp, class Alloc> | |
11fdf7f2 | 224 | inline std::ostream& operator<<(std::ostream& out, const std::map<A,B,Comp,Alloc>& m) |
7c673cae FG |
225 | { |
226 | out << "{"; | |
227 | for (auto it = m.begin(); | |
228 | it != m.end(); | |
229 | ++it) { | |
230 | if (it != m.begin()) out << ","; | |
231 | out << it->first << "=" << it->second; | |
232 | } | |
233 | out << "}"; | |
234 | return out; | |
235 | } | |
236 | ||
237 | template<class A, class B, class Comp, class Alloc> | |
11fdf7f2 | 238 | inline std::ostream& operator<<(std::ostream& out, const std::multimap<A,B,Comp,Alloc>& m) |
7c673cae FG |
239 | { |
240 | out << "{{"; | |
241 | for (auto it = m.begin(); | |
242 | it != m.end(); | |
243 | ++it) { | |
244 | if (it != m.begin()) out << ","; | |
245 | out << it->first << "=" << it->second; | |
246 | } | |
247 | out << "}}"; | |
248 | return out; | |
249 | } | |
250 | ||
11fdf7f2 TL |
251 | } // namespace std |
252 | ||
253 | namespace boost { | |
254 | namespace tuples { | |
255 | template<typename A, typename B, typename C> | |
256 | inline std::ostream& operator<<(std::ostream& out, const boost::tuples::tuple<A, B, C> &t) { | |
257 | return out << boost::get<0>(t) << "," | |
258 | << boost::get<1>(t) << "," | |
259 | << boost::get<2>(t); | |
260 | } | |
261 | } | |
262 | namespace container { | |
263 | template<class A, class Comp, class Alloc> | |
264 | inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_set<A, Comp, Alloc>& iset) { | |
265 | for (auto it = iset.begin(); | |
266 | it != iset.end(); | |
267 | ++it) { | |
268 | if (it != iset.begin()) out << ","; | |
269 | out << *it; | |
270 | } | |
271 | return out; | |
272 | } | |
273 | ||
274 | template<class A, class B, class Comp, class Alloc> | |
275 | inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_map<A, B, Comp, Alloc>& m) { | |
276 | for (auto it = m.begin(); | |
277 | it != m.end(); | |
278 | ++it) { | |
279 | if (it != m.begin()) out << ","; | |
280 | out << it->first << "=" << it->second; | |
281 | } | |
282 | return out; | |
283 | } | |
284 | } | |
285 | } // namespace boost | |
7c673cae FG |
286 | |
287 | ||
288 | ||
289 | /* | |
290 | * comparators for stl containers | |
291 | */ | |
292 | // for ceph::unordered_map: | |
293 | // ceph::unordered_map<const char*, long, hash<const char*>, eqstr> vals; | |
294 | struct eqstr | |
295 | { | |
296 | bool operator()(const char* s1, const char* s2) const | |
297 | { | |
298 | return strcmp(s1, s2) == 0; | |
299 | } | |
300 | }; | |
301 | ||
302 | // for set, map | |
303 | struct ltstr | |
304 | { | |
305 | bool operator()(const char* s1, const char* s2) const | |
306 | { | |
307 | return strcmp(s1, s2) < 0; | |
308 | } | |
309 | }; | |
310 | ||
311 | ||
312 | namespace ceph { | |
313 | class Formatter; | |
314 | } | |
315 | ||
316 | #include "encoding.h" | |
317 | ||
318 | WRITE_RAW_ENCODER(ceph_fsid) | |
319 | WRITE_RAW_ENCODER(ceph_file_layout) | |
320 | WRITE_RAW_ENCODER(ceph_dir_layout) | |
321 | WRITE_RAW_ENCODER(ceph_mds_session_head) | |
322 | WRITE_RAW_ENCODER(ceph_mds_request_head_legacy) | |
7c673cae FG |
323 | WRITE_RAW_ENCODER(ceph_mds_request_release) |
324 | WRITE_RAW_ENCODER(ceph_filelock) | |
325 | WRITE_RAW_ENCODER(ceph_mds_caps_head) | |
f67539c2 TL |
326 | WRITE_RAW_ENCODER(ceph_mds_caps_export_body) |
327 | WRITE_RAW_ENCODER(ceph_mds_caps_non_export_body) | |
7c673cae FG |
328 | WRITE_RAW_ENCODER(ceph_mds_cap_peer) |
329 | WRITE_RAW_ENCODER(ceph_mds_cap_release) | |
330 | WRITE_RAW_ENCODER(ceph_mds_cap_item) | |
331 | WRITE_RAW_ENCODER(ceph_mds_lease) | |
332 | WRITE_RAW_ENCODER(ceph_mds_snap_head) | |
333 | WRITE_RAW_ENCODER(ceph_mds_snap_realm) | |
334 | WRITE_RAW_ENCODER(ceph_mds_reply_head) | |
335 | WRITE_RAW_ENCODER(ceph_mds_reply_cap) | |
336 | WRITE_RAW_ENCODER(ceph_mds_cap_reconnect) | |
337 | WRITE_RAW_ENCODER(ceph_mds_snaprealm_reconnect) | |
338 | WRITE_RAW_ENCODER(ceph_frag_tree_split) | |
339 | WRITE_RAW_ENCODER(ceph_osd_reply_head) | |
340 | WRITE_RAW_ENCODER(ceph_osd_op) | |
341 | WRITE_RAW_ENCODER(ceph_msg_header) | |
342 | WRITE_RAW_ENCODER(ceph_msg_footer) | |
343 | WRITE_RAW_ENCODER(ceph_msg_footer_old) | |
344 | WRITE_RAW_ENCODER(ceph_mon_subscribe_item) | |
345 | ||
346 | WRITE_RAW_ENCODER(ceph_mon_statfs) | |
347 | WRITE_RAW_ENCODER(ceph_mon_statfs_reply) | |
348 | ||
349 | // ---------------------- | |
350 | // some basic types | |
351 | ||
352 | // NOTE: these must match ceph_fs.h typedefs | |
353 | typedef uint64_t ceph_tid_t; // transaction id | |
354 | typedef uint64_t version_t; | |
355 | typedef __u32 epoch_t; // map epoch (32bits -> 13 epochs/second for 10 years) | |
356 | ||
357 | // -------------------------------------- | |
358 | // identify individual mount clients by 64bit value | |
359 | ||
360 | struct client_t { | |
361 | int64_t v; | |
362 | ||
363 | // cppcheck-suppress noExplicitConstructor | |
364 | client_t(int64_t _v = -2) : v(_v) {} | |
11fdf7f2 | 365 | |
9f95a23c | 366 | void encode(ceph::buffer::list& bl) const { |
11fdf7f2 TL |
367 | using ceph::encode; |
368 | encode(v, bl); | |
7c673cae | 369 | } |
9f95a23c | 370 | void decode(ceph::buffer::list::const_iterator& bl) { |
11fdf7f2 TL |
371 | using ceph::decode; |
372 | decode(v, bl); | |
7c673cae FG |
373 | } |
374 | }; | |
375 | WRITE_CLASS_ENCODER(client_t) | |
376 | ||
377 | static inline bool operator==(const client_t& l, const client_t& r) { return l.v == r.v; } | |
378 | static inline bool operator!=(const client_t& l, const client_t& r) { return l.v != r.v; } | |
379 | static inline bool operator<(const client_t& l, const client_t& r) { return l.v < r.v; } | |
380 | static inline bool operator<=(const client_t& l, const client_t& r) { return l.v <= r.v; } | |
381 | static inline bool operator>(const client_t& l, const client_t& r) { return l.v > r.v; } | |
382 | static inline bool operator>=(const client_t& l, const client_t& r) { return l.v >= r.v; } | |
383 | ||
384 | static inline bool operator>=(const client_t& l, int64_t o) { return l.v >= o; } | |
385 | static inline bool operator<(const client_t& l, int64_t o) { return l.v < o; } | |
386 | ||
9f95a23c | 387 | inline std::ostream& operator<<(std::ostream& out, const client_t& c) { |
7c673cae FG |
388 | return out << c.v; |
389 | } | |
390 | ||
391 | ||
392 | ||
393 | // -- | |
394 | ||
1adf2230 | 395 | namespace { |
9f95a23c | 396 | inline std::ostream& format_u(std::ostream& out, const uint64_t v, const uint64_t n, |
1adf2230 AA |
397 | const int index, const uint64_t mult, const char* u) |
398 | { | |
399 | char buffer[32]; | |
400 | ||
401 | if (index == 0) { | |
402 | (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u); | |
403 | } else if ((v % mult) == 0) { | |
404 | // If this is an even multiple of the base, always display | |
405 | // without any decimal fraction. | |
406 | (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u); | |
407 | } else { | |
408 | // We want to choose a precision that reflects the best choice | |
409 | // for fitting in 5 characters. This can get rather tricky when | |
410 | // we have numbers that are very close to an order of magnitude. | |
411 | // For example, when displaying 10239 (which is really 9.999K), | |
412 | // we want only a single place of precision for 10.0K. We could | |
413 | // develop some complex heuristics for this, but it's much | |
414 | // easier just to try each combination in turn. | |
415 | int i; | |
416 | for (i = 2; i >= 0; i--) { | |
417 | if (snprintf(buffer, sizeof(buffer), "%.*f%s", i, | |
418 | static_cast<double>(v) / mult, u) <= 7) | |
419 | break; | |
420 | } | |
421 | } | |
422 | ||
423 | return out << buffer; | |
424 | } | |
7c673cae FG |
425 | } |
426 | ||
1adf2230 AA |
427 | /* |
428 | * Use this struct to pretty print values that should be formatted with a | |
429 | * decimal unit prefix (the classic SI units). No actual unit will be added. | |
430 | */ | |
431 | struct si_u_t { | |
7c673cae | 432 | uint64_t v; |
1adf2230 | 433 | explicit si_u_t(uint64_t _v) : v(_v) {}; |
7c673cae FG |
434 | }; |
435 | ||
9f95a23c | 436 | inline std::ostream& operator<<(std::ostream& out, const si_u_t& b) |
7c673cae | 437 | { |
1adf2230 AA |
438 | uint64_t n = b.v; |
439 | int index = 0; | |
440 | uint64_t mult = 1; | |
441 | const char* u[] = {"", "k", "M", "G", "T", "P", "E"}; | |
442 | ||
443 | while (n >= 1000 && index < 7) { | |
444 | n /= 1000; | |
445 | index++; | |
446 | mult *= 1000; | |
447 | } | |
448 | ||
449 | return format_u(out, b.v, n, index, mult, u[index]); | |
7c673cae FG |
450 | } |
451 | ||
1adf2230 AA |
452 | /* |
453 | * Use this struct to pretty print values that should be formatted with a | |
454 | * binary unit prefix (IEC units). Since binary unit prefixes are to be used for | |
455 | * "multiples of units in data processing, data transmission, and digital | |
456 | * information" (so bits and bytes) and so far bits are not printed, the unit | |
457 | * "B" for "byte" is added besides the multiplier. | |
458 | */ | |
459 | struct byte_u_t { | |
7c673cae | 460 | uint64_t v; |
1adf2230 | 461 | explicit byte_u_t(uint64_t _v) : v(_v) {}; |
7c673cae FG |
462 | }; |
463 | ||
9f95a23c | 464 | inline std::ostream& operator<<(std::ostream& out, const byte_u_t& b) |
7c673cae | 465 | { |
1adf2230 AA |
466 | uint64_t n = b.v; |
467 | int index = 0; | |
11fdf7f2 | 468 | const char* u[] = {" B", " KiB", " MiB", " GiB", " TiB", " PiB", " EiB"}; |
7c673cae | 469 | |
1adf2230 AA |
470 | while (n >= 1024 && index < 7) { |
471 | n /= 1024; | |
472 | index++; | |
473 | } | |
7c673cae | 474 | |
1adf2230 | 475 | return format_u(out, b.v, n, index, 1ULL << (10 * index), u[index]); |
7c673cae FG |
476 | } |
477 | ||
9f95a23c | 478 | inline std::ostream& operator<<(std::ostream& out, const ceph_mon_subscribe_item& i) |
7c673cae | 479 | { |
20effc67 | 480 | return out << (long)i.start |
7c673cae FG |
481 | << ((i.flags & CEPH_SUBSCRIBE_ONETIME) ? "" : "+"); |
482 | } | |
483 | ||
7c673cae FG |
484 | struct weightf_t { |
485 | float v; | |
486 | // cppcheck-suppress noExplicitConstructor | |
487 | weightf_t(float _v) : v(_v) {} | |
488 | }; | |
489 | ||
9f95a23c | 490 | inline std::ostream& operator<<(std::ostream& out, const weightf_t& w) |
7c673cae | 491 | { |
11fdf7f2 | 492 | if (w.v < -0.01F) { |
7c673cae | 493 | return out << "-"; |
11fdf7f2 | 494 | } else if (w.v < 0.000001F) { |
7c673cae FG |
495 | return out << "0"; |
496 | } else { | |
497 | std::streamsize p = out.precision(); | |
498 | return out << std::fixed << std::setprecision(5) << w.v << std::setprecision(p); | |
499 | } | |
500 | } | |
501 | ||
502 | struct shard_id_t { | |
503 | int8_t id; | |
504 | ||
505 | shard_id_t() : id(0) {} | |
506 | explicit shard_id_t(int8_t _id) : id(_id) {} | |
507 | ||
508 | operator int8_t() const { return id; } | |
509 | ||
510 | const static shard_id_t NO_SHARD; | |
511 | ||
9f95a23c | 512 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 TL |
513 | using ceph::encode; |
514 | encode(id, bl); | |
7c673cae | 515 | } |
9f95a23c | 516 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
517 | using ceph::decode; |
518 | decode(id, bl); | |
7c673cae | 519 | } |
1e59de90 TL |
520 | |
521 | bool operator==(const shard_id_t&) const = default; | |
522 | auto operator<=>(const shard_id_t&) const = default; | |
7c673cae FG |
523 | }; |
524 | WRITE_CLASS_ENCODER(shard_id_t) | |
9f95a23c | 525 | std::ostream &operator<<(std::ostream &lhs, const shard_id_t &rhs); |
7c673cae | 526 | |
f67539c2 TL |
527 | #if defined(__sun) || defined(_AIX) || defined(__APPLE__) || \ |
528 | defined(__FreeBSD__) || defined(_WIN32) | |
529 | extern "C" { | |
31f18b77 FG |
530 | __s32 ceph_to_hostos_errno(__s32 e); |
531 | __s32 hostos_to_ceph_errno(__s32 e); | |
f67539c2 | 532 | } |
7c673cae | 533 | #else |
31f18b77 FG |
534 | #define ceph_to_hostos_errno(e) (e) |
535 | #define hostos_to_ceph_errno(e) (e) | |
7c673cae FG |
536 | #endif |
537 | ||
538 | struct errorcode32_t { | |
539 | int32_t code; | |
540 | ||
541 | errorcode32_t() : code(0) {} | |
542 | // cppcheck-suppress noExplicitConstructor | |
1e59de90 | 543 | explicit errorcode32_t(int32_t i) : code(i) {} |
7c673cae | 544 | |
224ce89b WB |
545 | operator int() const { return code; } |
546 | int* operator&() { return &code; } | |
1e59de90 TL |
547 | errorcode32_t& operator=(int32_t i) { |
548 | code = i; | |
549 | return *this; | |
550 | } | |
551 | bool operator==(const errorcode32_t&) const = default; | |
552 | auto operator<=>(const errorcode32_t&) const = default; | |
7c673cae | 553 | |
9f95a23c | 554 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 | 555 | using ceph::encode; |
31f18b77 | 556 | __s32 newcode = hostos_to_ceph_errno(code); |
11fdf7f2 | 557 | encode(newcode, bl); |
7c673cae | 558 | } |
9f95a23c | 559 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
560 | using ceph::decode; |
561 | decode(code, bl); | |
31f18b77 | 562 | code = ceph_to_hostos_errno(code); |
7c673cae FG |
563 | } |
564 | }; | |
565 | WRITE_CLASS_ENCODER(errorcode32_t) | |
7c673cae | 566 | |
11fdf7f2 TL |
567 | template <uint8_t S> |
568 | struct sha_digest_t { | |
569 | constexpr static uint32_t SIZE = S; | |
570 | // TODO: we might consider std::array in the future. Avoiding it for now | |
571 | // as sha_digest_t is a part of our public API. | |
572 | unsigned char v[S] = {0}; | |
573 | ||
9f95a23c | 574 | std::string to_str() const { |
11fdf7f2 TL |
575 | char str[S * 2 + 1] = {0}; |
576 | str[0] = '\0'; | |
577 | for (size_t i = 0; i < S; i++) { | |
578 | ::sprintf(&str[i * 2], "%02x", static_cast<int>(v[i])); | |
579 | } | |
f67539c2 | 580 | return std::string(str); |
11fdf7f2 TL |
581 | } |
582 | sha_digest_t(const unsigned char *_v) { memcpy(v, _v, SIZE); }; | |
583 | sha_digest_t() {} | |
584 | ||
585 | bool operator==(const sha_digest_t& r) const { | |
586 | return ::memcmp(v, r.v, SIZE) == 0; | |
587 | } | |
588 | bool operator!=(const sha_digest_t& r) const { | |
589 | return ::memcmp(v, r.v, SIZE) != 0; | |
590 | } | |
591 | ||
9f95a23c | 592 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 TL |
593 | // copy to avoid reinterpret_cast, is_pod and other nasty things |
594 | using ceph::encode; | |
595 | std::array<unsigned char, SIZE> tmparr; | |
596 | memcpy(tmparr.data(), v, SIZE); | |
597 | encode(tmparr, bl); | |
598 | } | |
9f95a23c | 599 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
600 | using ceph::decode; |
601 | std::array<unsigned char, SIZE> tmparr; | |
602 | decode(tmparr, bl); | |
603 | memcpy(v, tmparr.data(), SIZE); | |
604 | } | |
605 | }; | |
606 | ||
9f95a23c TL |
607 | template<uint8_t S> |
608 | inline std::ostream &operator<<(std::ostream &out, const sha_digest_t<S> &b) { | |
609 | std::string str = b.to_str(); | |
11fdf7f2 TL |
610 | return out << str; |
611 | } | |
612 | ||
1e59de90 TL |
613 | #if FMT_VERSION >= 90000 |
614 | template <uint8_t S> struct fmt::formatter<sha_digest_t<S>> : fmt::ostream_formatter {}; | |
615 | #endif | |
616 | ||
11fdf7f2 TL |
617 | using sha1_digest_t = sha_digest_t<20>; |
618 | WRITE_CLASS_ENCODER(sha1_digest_t) | |
619 | ||
620 | using sha256_digest_t = sha_digest_t<32>; | |
621 | WRITE_CLASS_ENCODER(sha256_digest_t) | |
622 | ||
9f95a23c TL |
623 | using sha512_digest_t = sha_digest_t<64>; |
624 | ||
625 | using md5_digest_t = sha_digest_t<16>; | |
626 | WRITE_CLASS_ENCODER(md5_digest_t) | |
627 | ||
7c673cae FG |
628 | |
629 | #endif |