]>
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) | |
323 | WRITE_RAW_ENCODER(ceph_mds_request_head) | |
324 | WRITE_RAW_ENCODER(ceph_mds_request_release) | |
325 | WRITE_RAW_ENCODER(ceph_filelock) | |
326 | WRITE_RAW_ENCODER(ceph_mds_caps_head) | |
f67539c2 TL |
327 | WRITE_RAW_ENCODER(ceph_mds_caps_export_body) |
328 | WRITE_RAW_ENCODER(ceph_mds_caps_non_export_body) | |
7c673cae FG |
329 | WRITE_RAW_ENCODER(ceph_mds_cap_peer) |
330 | WRITE_RAW_ENCODER(ceph_mds_cap_release) | |
331 | WRITE_RAW_ENCODER(ceph_mds_cap_item) | |
332 | WRITE_RAW_ENCODER(ceph_mds_lease) | |
333 | WRITE_RAW_ENCODER(ceph_mds_snap_head) | |
334 | WRITE_RAW_ENCODER(ceph_mds_snap_realm) | |
335 | WRITE_RAW_ENCODER(ceph_mds_reply_head) | |
336 | WRITE_RAW_ENCODER(ceph_mds_reply_cap) | |
337 | WRITE_RAW_ENCODER(ceph_mds_cap_reconnect) | |
338 | WRITE_RAW_ENCODER(ceph_mds_snaprealm_reconnect) | |
339 | WRITE_RAW_ENCODER(ceph_frag_tree_split) | |
340 | WRITE_RAW_ENCODER(ceph_osd_reply_head) | |
341 | WRITE_RAW_ENCODER(ceph_osd_op) | |
342 | WRITE_RAW_ENCODER(ceph_msg_header) | |
343 | WRITE_RAW_ENCODER(ceph_msg_footer) | |
344 | WRITE_RAW_ENCODER(ceph_msg_footer_old) | |
345 | WRITE_RAW_ENCODER(ceph_mon_subscribe_item) | |
346 | ||
347 | WRITE_RAW_ENCODER(ceph_mon_statfs) | |
348 | WRITE_RAW_ENCODER(ceph_mon_statfs_reply) | |
349 | ||
350 | // ---------------------- | |
351 | // some basic types | |
352 | ||
353 | // NOTE: these must match ceph_fs.h typedefs | |
354 | typedef uint64_t ceph_tid_t; // transaction id | |
355 | typedef uint64_t version_t; | |
356 | typedef __u32 epoch_t; // map epoch (32bits -> 13 epochs/second for 10 years) | |
357 | ||
358 | // -------------------------------------- | |
359 | // identify individual mount clients by 64bit value | |
360 | ||
361 | struct client_t { | |
362 | int64_t v; | |
363 | ||
364 | // cppcheck-suppress noExplicitConstructor | |
365 | client_t(int64_t _v = -2) : v(_v) {} | |
11fdf7f2 | 366 | |
9f95a23c | 367 | void encode(ceph::buffer::list& bl) const { |
11fdf7f2 TL |
368 | using ceph::encode; |
369 | encode(v, bl); | |
7c673cae | 370 | } |
9f95a23c | 371 | void decode(ceph::buffer::list::const_iterator& bl) { |
11fdf7f2 TL |
372 | using ceph::decode; |
373 | decode(v, bl); | |
7c673cae FG |
374 | } |
375 | }; | |
376 | WRITE_CLASS_ENCODER(client_t) | |
377 | ||
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 | static inline bool operator>=(const client_t& l, const client_t& r) { return l.v >= r.v; } | |
384 | ||
385 | static inline bool operator>=(const client_t& l, int64_t o) { return l.v >= o; } | |
386 | static inline bool operator<(const client_t& l, int64_t o) { return l.v < o; } | |
387 | ||
9f95a23c | 388 | inline std::ostream& operator<<(std::ostream& out, const client_t& c) { |
7c673cae FG |
389 | return out << c.v; |
390 | } | |
391 | ||
392 | ||
393 | ||
394 | // -- | |
395 | ||
1adf2230 | 396 | namespace { |
9f95a23c | 397 | inline std::ostream& format_u(std::ostream& out, const uint64_t v, const uint64_t n, |
1adf2230 AA |
398 | const int index, const uint64_t mult, const char* u) |
399 | { | |
400 | char buffer[32]; | |
401 | ||
402 | if (index == 0) { | |
403 | (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u); | |
404 | } else if ((v % mult) == 0) { | |
405 | // If this is an even multiple of the base, always display | |
406 | // without any decimal fraction. | |
407 | (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u); | |
408 | } else { | |
409 | // We want to choose a precision that reflects the best choice | |
410 | // for fitting in 5 characters. This can get rather tricky when | |
411 | // we have numbers that are very close to an order of magnitude. | |
412 | // For example, when displaying 10239 (which is really 9.999K), | |
413 | // we want only a single place of precision for 10.0K. We could | |
414 | // develop some complex heuristics for this, but it's much | |
415 | // easier just to try each combination in turn. | |
416 | int i; | |
417 | for (i = 2; i >= 0; i--) { | |
418 | if (snprintf(buffer, sizeof(buffer), "%.*f%s", i, | |
419 | static_cast<double>(v) / mult, u) <= 7) | |
420 | break; | |
421 | } | |
422 | } | |
423 | ||
424 | return out << buffer; | |
425 | } | |
7c673cae FG |
426 | } |
427 | ||
1adf2230 AA |
428 | /* |
429 | * Use this struct to pretty print values that should be formatted with a | |
430 | * decimal unit prefix (the classic SI units). No actual unit will be added. | |
431 | */ | |
432 | struct si_u_t { | |
7c673cae | 433 | uint64_t v; |
1adf2230 | 434 | explicit si_u_t(uint64_t _v) : v(_v) {}; |
7c673cae FG |
435 | }; |
436 | ||
9f95a23c | 437 | inline std::ostream& operator<<(std::ostream& out, const si_u_t& b) |
7c673cae | 438 | { |
1adf2230 AA |
439 | uint64_t n = b.v; |
440 | int index = 0; | |
441 | uint64_t mult = 1; | |
442 | const char* u[] = {"", "k", "M", "G", "T", "P", "E"}; | |
443 | ||
444 | while (n >= 1000 && index < 7) { | |
445 | n /= 1000; | |
446 | index++; | |
447 | mult *= 1000; | |
448 | } | |
449 | ||
450 | return format_u(out, b.v, n, index, mult, u[index]); | |
7c673cae FG |
451 | } |
452 | ||
1adf2230 AA |
453 | /* |
454 | * Use this struct to pretty print values that should be formatted with a | |
455 | * binary unit prefix (IEC units). Since binary unit prefixes are to be used for | |
456 | * "multiples of units in data processing, data transmission, and digital | |
457 | * information" (so bits and bytes) and so far bits are not printed, the unit | |
458 | * "B" for "byte" is added besides the multiplier. | |
459 | */ | |
460 | struct byte_u_t { | |
7c673cae | 461 | uint64_t v; |
1adf2230 | 462 | explicit byte_u_t(uint64_t _v) : v(_v) {}; |
7c673cae FG |
463 | }; |
464 | ||
9f95a23c | 465 | inline std::ostream& operator<<(std::ostream& out, const byte_u_t& b) |
7c673cae | 466 | { |
1adf2230 AA |
467 | uint64_t n = b.v; |
468 | int index = 0; | |
11fdf7f2 | 469 | const char* u[] = {" B", " KiB", " MiB", " GiB", " TiB", " PiB", " EiB"}; |
7c673cae | 470 | |
1adf2230 AA |
471 | while (n >= 1024 && index < 7) { |
472 | n /= 1024; | |
473 | index++; | |
474 | } | |
7c673cae | 475 | |
1adf2230 | 476 | return format_u(out, b.v, n, index, 1ULL << (10 * index), u[index]); |
7c673cae FG |
477 | } |
478 | ||
9f95a23c | 479 | inline std::ostream& operator<<(std::ostream& out, const ceph_mon_subscribe_item& i) |
7c673cae FG |
480 | { |
481 | return out << i.start | |
482 | << ((i.flags & CEPH_SUBSCRIBE_ONETIME) ? "" : "+"); | |
483 | } | |
484 | ||
7c673cae FG |
485 | struct weightf_t { |
486 | float v; | |
487 | // cppcheck-suppress noExplicitConstructor | |
488 | weightf_t(float _v) : v(_v) {} | |
489 | }; | |
490 | ||
9f95a23c | 491 | inline std::ostream& operator<<(std::ostream& out, const weightf_t& w) |
7c673cae | 492 | { |
11fdf7f2 | 493 | if (w.v < -0.01F) { |
7c673cae | 494 | return out << "-"; |
11fdf7f2 | 495 | } else if (w.v < 0.000001F) { |
7c673cae FG |
496 | return out << "0"; |
497 | } else { | |
498 | std::streamsize p = out.precision(); | |
499 | return out << std::fixed << std::setprecision(5) << w.v << std::setprecision(p); | |
500 | } | |
501 | } | |
502 | ||
503 | struct shard_id_t { | |
504 | int8_t id; | |
505 | ||
506 | shard_id_t() : id(0) {} | |
507 | explicit shard_id_t(int8_t _id) : id(_id) {} | |
508 | ||
509 | operator int8_t() const { return id; } | |
510 | ||
511 | const static shard_id_t NO_SHARD; | |
512 | ||
9f95a23c | 513 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 TL |
514 | using ceph::encode; |
515 | encode(id, bl); | |
7c673cae | 516 | } |
9f95a23c | 517 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
518 | using ceph::decode; |
519 | decode(id, bl); | |
7c673cae FG |
520 | } |
521 | }; | |
522 | WRITE_CLASS_ENCODER(shard_id_t) | |
523 | WRITE_EQ_OPERATORS_1(shard_id_t, id) | |
524 | WRITE_CMP_OPERATORS_1(shard_id_t, id) | |
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 | |
543 | errorcode32_t(int32_t i) : code(i) {} | |
544 | ||
224ce89b WB |
545 | operator int() const { return code; } |
546 | int* operator&() { return &code; } | |
547 | int operator==(int i) { return code == i; } | |
548 | int operator>(int i) { return code > i; } | |
549 | int operator>=(int i) { return code >= i; } | |
550 | int operator<(int i) { return code < i; } | |
551 | int operator<=(int i) { return code <= i; } | |
7c673cae | 552 | |
9f95a23c | 553 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 | 554 | using ceph::encode; |
31f18b77 | 555 | __s32 newcode = hostos_to_ceph_errno(code); |
11fdf7f2 | 556 | encode(newcode, bl); |
7c673cae | 557 | } |
9f95a23c | 558 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
559 | using ceph::decode; |
560 | decode(code, bl); | |
31f18b77 | 561 | code = ceph_to_hostos_errno(code); |
7c673cae FG |
562 | } |
563 | }; | |
564 | WRITE_CLASS_ENCODER(errorcode32_t) | |
565 | WRITE_EQ_OPERATORS_1(errorcode32_t, code) | |
566 | WRITE_CMP_OPERATORS_1(errorcode32_t, code) | |
567 | ||
11fdf7f2 TL |
568 | template <uint8_t S> |
569 | struct sha_digest_t { | |
570 | constexpr static uint32_t SIZE = S; | |
571 | // TODO: we might consider std::array in the future. Avoiding it for now | |
572 | // as sha_digest_t is a part of our public API. | |
573 | unsigned char v[S] = {0}; | |
574 | ||
9f95a23c | 575 | std::string to_str() const { |
11fdf7f2 TL |
576 | char str[S * 2 + 1] = {0}; |
577 | str[0] = '\0'; | |
578 | for (size_t i = 0; i < S; i++) { | |
579 | ::sprintf(&str[i * 2], "%02x", static_cast<int>(v[i])); | |
580 | } | |
f67539c2 | 581 | return std::string(str); |
11fdf7f2 TL |
582 | } |
583 | sha_digest_t(const unsigned char *_v) { memcpy(v, _v, SIZE); }; | |
584 | sha_digest_t() {} | |
585 | ||
586 | bool operator==(const sha_digest_t& r) const { | |
587 | return ::memcmp(v, r.v, SIZE) == 0; | |
588 | } | |
589 | bool operator!=(const sha_digest_t& r) const { | |
590 | return ::memcmp(v, r.v, SIZE) != 0; | |
591 | } | |
592 | ||
9f95a23c | 593 | void encode(ceph::buffer::list &bl) const { |
11fdf7f2 TL |
594 | // copy to avoid reinterpret_cast, is_pod and other nasty things |
595 | using ceph::encode; | |
596 | std::array<unsigned char, SIZE> tmparr; | |
597 | memcpy(tmparr.data(), v, SIZE); | |
598 | encode(tmparr, bl); | |
599 | } | |
9f95a23c | 600 | void decode(ceph::buffer::list::const_iterator &bl) { |
11fdf7f2 TL |
601 | using ceph::decode; |
602 | std::array<unsigned char, SIZE> tmparr; | |
603 | decode(tmparr, bl); | |
604 | memcpy(v, tmparr.data(), SIZE); | |
605 | } | |
606 | }; | |
607 | ||
9f95a23c TL |
608 | template<uint8_t S> |
609 | inline std::ostream &operator<<(std::ostream &out, const sha_digest_t<S> &b) { | |
610 | std::string str = b.to_str(); | |
11fdf7f2 TL |
611 | return out << str; |
612 | } | |
613 | ||
614 | using sha1_digest_t = sha_digest_t<20>; | |
615 | WRITE_CLASS_ENCODER(sha1_digest_t) | |
616 | ||
617 | using sha256_digest_t = sha_digest_t<32>; | |
618 | WRITE_CLASS_ENCODER(sha256_digest_t) | |
619 | ||
9f95a23c TL |
620 | using sha512_digest_t = sha_digest_t<64>; |
621 | ||
622 | using md5_digest_t = sha_digest_t<16>; | |
623 | WRITE_CLASS_ENCODER(md5_digest_t) | |
624 | ||
7c673cae FG |
625 | |
626 | #endif |