]> git.proxmox.com Git - ceph.git/blame - ceph/src/include/types.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / include / types.h
CommitLineData
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
37extern "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
67typedef long long loff_t;
68typedef long long off64_t;
69#define O_DIRECT 00040000
70#endif
71
72// FreeBSD compatibility
73#ifdef __FreeBSD__
74typedef off_t loff_t;
75typedef off_t off64_t;
76#endif
77
78#if defined(__sun) || defined(_AIX)
79typedef 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 89namespace std {
31f18b77 90template<class A, class B>
11fdf7f2 91inline std::ostream& operator<<(std::ostream&out, const std::pair<A,B>& v);
31f18b77 92template<class A, class Alloc>
11fdf7f2
TL
93inline std::ostream& operator<<(std::ostream& out, const std::vector<A,Alloc>& v);
94template<class A, std::size_t N, class Alloc>
95inline std::ostream& operator<<(std::ostream& out, const boost::container::small_vector<A,N,Alloc>& v);
31f18b77 96template<class A, class Comp, class Alloc>
11fdf7f2
TL
97inline std::ostream& operator<<(std::ostream& out, const std::deque<A,Alloc>& v);
98template<typename... Ts>
99inline std::ostream& operator<<(std::ostream& out, const std::tuple<Ts...> &t);
9f95a23c
TL
100template<typename T>
101inline std::ostream& operator<<(std::ostream& out, const std::optional<T> &t);
31f18b77 102template<class A, class Alloc>
11fdf7f2 103inline std::ostream& operator<<(std::ostream& out, const std::list<A,Alloc>& ilist);
31f18b77 104template<class A, class Comp, class Alloc>
11fdf7f2 105inline std::ostream& operator<<(std::ostream& out, const std::set<A, Comp, Alloc>& iset);
31f18b77 106template<class A, class Comp, class Alloc>
11fdf7f2
TL
107inline std::ostream& operator<<(std::ostream& out, const std::multiset<A,Comp,Alloc>& iset);
108template<class A, class B, class Comp, class Alloc>
109inline std::ostream& operator<<(std::ostream& out, const std::map<A,B,Comp,Alloc>& m);
31f18b77 110template<class A, class B, class Comp, class Alloc>
11fdf7f2
TL
111inline std::ostream& operator<<(std::ostream& out, const std::multimap<A,B,Comp,Alloc>& m);
112}
113
114namespace boost {
115template<typename... Ts>
116inline std::ostream& operator<<(std::ostream& out, const boost::tuple<Ts...> &t);
117
118namespace container {
119template<class A, class Comp, class Alloc>
120inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_set<A, Comp, Alloc>& iset);
31f18b77 121template<class A, class B, class Comp, class Alloc>
11fdf7f2
TL
122inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_map<A, B, Comp, Alloc>& iset);
123}
124}
31f18b77 125
11fdf7f2 126namespace std {
7c673cae 127template<class A, class B>
11fdf7f2 128inline std::ostream& operator<<(std::ostream& out, const std::pair<A,B>& v) {
7c673cae
FG
129 return out << v.first << "," << v.second;
130}
131
132template<class A, class Alloc>
11fdf7f2
TL
133inline 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
145template<class A, std::size_t N, class Alloc>
146inline 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 158template<class A, class Alloc>
11fdf7f2 159inline 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
169template<typename... Ts>
170inline 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
181template<typename T>
182inline 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 190template<class A, class Alloc>
11fdf7f2 191inline 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
201template<class A, class Comp, class Alloc>
11fdf7f2 202inline 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
212template<class A, class Comp, class Alloc>
11fdf7f2 213inline 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
223template<class A, class B, class Comp, class Alloc>
11fdf7f2 224inline 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
237template<class A, class B, class Comp, class Alloc>
11fdf7f2 238inline 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
253namespace boost {
254namespace tuples {
255template<typename A, typename B, typename C>
256inline 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}
262namespace container {
263template<class A, class Comp, class Alloc>
264inline 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
274template<class A, class B, class Comp, class Alloc>
275inline 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;
294struct 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
303struct ltstr
304{
305 bool operator()(const char* s1, const char* s2) const
306 {
307 return strcmp(s1, s2) < 0;
308 }
309};
310
311
312namespace ceph {
313 class Formatter;
314}
315
316#include "encoding.h"
317
318WRITE_RAW_ENCODER(ceph_fsid)
319WRITE_RAW_ENCODER(ceph_file_layout)
320WRITE_RAW_ENCODER(ceph_dir_layout)
321WRITE_RAW_ENCODER(ceph_mds_session_head)
322WRITE_RAW_ENCODER(ceph_mds_request_head_legacy)
323WRITE_RAW_ENCODER(ceph_mds_request_head)
324WRITE_RAW_ENCODER(ceph_mds_request_release)
325WRITE_RAW_ENCODER(ceph_filelock)
326WRITE_RAW_ENCODER(ceph_mds_caps_head)
f67539c2
TL
327WRITE_RAW_ENCODER(ceph_mds_caps_export_body)
328WRITE_RAW_ENCODER(ceph_mds_caps_non_export_body)
7c673cae
FG
329WRITE_RAW_ENCODER(ceph_mds_cap_peer)
330WRITE_RAW_ENCODER(ceph_mds_cap_release)
331WRITE_RAW_ENCODER(ceph_mds_cap_item)
332WRITE_RAW_ENCODER(ceph_mds_lease)
333WRITE_RAW_ENCODER(ceph_mds_snap_head)
334WRITE_RAW_ENCODER(ceph_mds_snap_realm)
335WRITE_RAW_ENCODER(ceph_mds_reply_head)
336WRITE_RAW_ENCODER(ceph_mds_reply_cap)
337WRITE_RAW_ENCODER(ceph_mds_cap_reconnect)
338WRITE_RAW_ENCODER(ceph_mds_snaprealm_reconnect)
339WRITE_RAW_ENCODER(ceph_frag_tree_split)
340WRITE_RAW_ENCODER(ceph_osd_reply_head)
341WRITE_RAW_ENCODER(ceph_osd_op)
342WRITE_RAW_ENCODER(ceph_msg_header)
343WRITE_RAW_ENCODER(ceph_msg_footer)
344WRITE_RAW_ENCODER(ceph_msg_footer_old)
345WRITE_RAW_ENCODER(ceph_mon_subscribe_item)
346
347WRITE_RAW_ENCODER(ceph_mon_statfs)
348WRITE_RAW_ENCODER(ceph_mon_statfs_reply)
349
350// ----------------------
351// some basic types
352
353// NOTE: these must match ceph_fs.h typedefs
354typedef uint64_t ceph_tid_t; // transaction id
355typedef uint64_t version_t;
356typedef __u32 epoch_t; // map epoch (32bits -> 13 epochs/second for 10 years)
357
358// --------------------------------------
359// identify individual mount clients by 64bit value
360
361struct 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};
376WRITE_CLASS_ENCODER(client_t)
377
378static inline bool operator==(const client_t& l, const client_t& r) { return l.v == r.v; }
379static inline bool operator!=(const client_t& l, const client_t& r) { return l.v != r.v; }
380static inline bool operator<(const client_t& l, const client_t& r) { return l.v < r.v; }
381static inline bool operator<=(const client_t& l, const client_t& r) { return l.v <= r.v; }
382static inline bool operator>(const client_t& l, const client_t& r) { return l.v > r.v; }
383static inline bool operator>=(const client_t& l, const client_t& r) { return l.v >= r.v; }
384
385static inline bool operator>=(const client_t& l, int64_t o) { return l.v >= o; }
386static inline bool operator<(const client_t& l, int64_t o) { return l.v < o; }
387
9f95a23c 388inline std::ostream& operator<<(std::ostream& out, const client_t& c) {
7c673cae
FG
389 return out << c.v;
390}
391
392
393
394// --
395
1adf2230 396namespace {
9f95a23c 397inline 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 */
432struct si_u_t {
7c673cae 433 uint64_t v;
1adf2230 434 explicit si_u_t(uint64_t _v) : v(_v) {};
7c673cae
FG
435};
436
9f95a23c 437inline 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 */
460struct byte_u_t {
7c673cae 461 uint64_t v;
1adf2230 462 explicit byte_u_t(uint64_t _v) : v(_v) {};
7c673cae
FG
463};
464
9f95a23c 465inline 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 479inline 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
485struct weightf_t {
486 float v;
487 // cppcheck-suppress noExplicitConstructor
488 weightf_t(float _v) : v(_v) {}
489};
490
9f95a23c 491inline 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
503struct 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};
522WRITE_CLASS_ENCODER(shard_id_t)
523WRITE_EQ_OPERATORS_1(shard_id_t, id)
524WRITE_CMP_OPERATORS_1(shard_id_t, id)
9f95a23c 525std::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)
529extern "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
538struct 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};
564WRITE_CLASS_ENCODER(errorcode32_t)
565WRITE_EQ_OPERATORS_1(errorcode32_t, code)
566WRITE_CMP_OPERATORS_1(errorcode32_t, code)
567
11fdf7f2
TL
568template <uint8_t S>
569struct 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
608template<uint8_t S>
609inline 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
614using sha1_digest_t = sha_digest_t<20>;
615WRITE_CLASS_ENCODER(sha1_digest_t)
616
617using sha256_digest_t = sha_digest_t<32>;
618WRITE_CLASS_ENCODER(sha256_digest_t)
619
9f95a23c
TL
620using sha512_digest_t = sha_digest_t<64>;
621
622using md5_digest_t = sha_digest_t<16>;
623WRITE_CLASS_ENCODER(md5_digest_t)
624
7c673cae
FG
625
626#endif