]> git.proxmox.com Git - ceph.git/blob - ceph/src/include/types.h
update sources to 12.2.8
[ceph.git] / ceph / src / include / 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 * 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
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
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
27 // <macro hackery>
28 // temporarily remap __le* to ceph_le* for benefit of shared kernel/userland headers
29 #define __le16 ceph_le16
30 #define __le32 ceph_le32
31 #define __le64 ceph_le64
32 #include "ceph_fs.h"
33 #include "ceph_frag.h"
34 #include "rbd_types.h"
35 #undef __le16
36 #undef __le32
37 #undef __le64
38 // </macro hackery>
39
40
41 #ifdef __cplusplus
42 #ifndef _BACKWARD_BACKWARD_WARNING_H
43 #define _BACKWARD_BACKWARD_WARNING_H // make gcc 4.3 shut up about hash_*
44 #endif
45 #endif
46
47 extern "C" {
48 #include <stdint.h>
49 #include <sys/types.h>
50 #include <sys/stat.h>
51 #include "statlite.h"
52 }
53
54 #include <string>
55 #include <list>
56 #include <set>
57 #include <map>
58 #include <vector>
59 #include <iostream>
60 #include <iomanip>
61
62 using namespace std;
63
64 #include "include/unordered_map.h"
65
66 #include "object.h"
67 #include "intarith.h"
68
69 #include "acconfig.h"
70
71 #include "assert.h"
72
73 // DARWIN compatibility
74 #ifdef DARWIN
75 typedef long long loff_t;
76 typedef long long off64_t;
77 #define O_DIRECT 00040000
78 #endif
79
80 // FreeBSD compatibility
81 #ifdef __FreeBSD__
82 typedef off_t loff_t;
83 typedef off_t off64_t;
84 #endif
85
86 #if defined(__sun) || defined(_AIX)
87 typedef off_t loff_t;
88 #endif
89
90
91 // -- io helpers --
92
93 // Forward declare all the I/O helpers so strict ADL can find them in
94 // the case of containers of containers. I'm tempted to abstract this
95 // stuff using template templates like I did for denc.
96
97 template<class A, class B>
98 inline ostream& operator<<(ostream&out, const pair<A,B>& v);
99 template<class A, class Alloc>
100 inline ostream& operator<<(ostream& out, const vector<A,Alloc>& v);
101 template<class A, class Comp, class Alloc>
102 inline ostream& operator<<(ostream& out, const deque<A,Alloc>& v);
103 template<class A, class B, class C>
104 inline ostream& operator<<(ostream&out, const boost::tuple<A, B, C> &t);
105 template<class A, class Alloc>
106 inline ostream& operator<<(ostream& out, const list<A,Alloc>& ilist);
107 template<class A, class Comp, class Alloc>
108 inline ostream& operator<<(ostream& out, const set<A, Comp, Alloc>& iset);
109 template<class A, class Comp, class Alloc>
110 inline ostream& operator<<(ostream& out, const multiset<A,Comp,Alloc>& iset);
111 template<class A, class B, class Comp, class Alloc>
112 inline ostream& operator<<(ostream& out, const map<A,B,Comp,Alloc>& m);
113 template<class A, class B, class Comp, class Alloc>
114 inline ostream& operator<<(ostream& out, const multimap<A,B,Comp,Alloc>& m);
115
116 template<class A, class B>
117 inline ostream& operator<<(ostream& out, const pair<A,B>& v) {
118 return out << v.first << "," << v.second;
119 }
120
121 template<class A, class Alloc>
122 inline ostream& operator<<(ostream& out, const vector<A,Alloc>& v) {
123 out << "[";
124 for (auto p = v.begin(); p != v.end(); ++p) {
125 if (p != v.begin()) out << ",";
126 out << *p;
127 }
128 out << "]";
129 return out;
130 }
131 template<class A, class Alloc>
132 inline ostream& operator<<(ostream& out, const deque<A,Alloc>& v) {
133 out << "<";
134 for (auto p = v.begin(); p != v.end(); ++p) {
135 if (p != v.begin()) out << ",";
136 out << *p;
137 }
138 out << ">";
139 return out;
140 }
141
142 template<class A, class B, class C>
143 inline ostream& operator<<(ostream&out, const boost::tuple<A, B, C> &t) {
144 out << boost::get<0>(t) <<"," << boost::get<1>(t) << "," << boost::get<2>(t);
145 return out;
146 }
147
148 template<class A, class Alloc>
149 inline ostream& operator<<(ostream& out, const list<A,Alloc>& ilist) {
150 for (auto it = ilist.begin();
151 it != ilist.end();
152 ++it) {
153 if (it != ilist.begin()) out << ",";
154 out << *it;
155 }
156 return out;
157 }
158
159 template<class A, class Comp, class Alloc>
160 inline ostream& operator<<(ostream& out, const set<A, Comp, Alloc>& iset) {
161 for (auto it = iset.begin();
162 it != iset.end();
163 ++it) {
164 if (it != iset.begin()) out << ",";
165 out << *it;
166 }
167 return out;
168 }
169
170 template<class A, class Comp, class Alloc>
171 inline ostream& operator<<(ostream& out, const multiset<A,Comp,Alloc>& iset) {
172 for (auto it = iset.begin();
173 it != iset.end();
174 ++it) {
175 if (it != iset.begin()) out << ",";
176 out << *it;
177 }
178 return out;
179 }
180
181 template<class A, class B, class Comp, class Alloc>
182 inline ostream& operator<<(ostream& out, const map<A,B,Comp,Alloc>& m)
183 {
184 out << "{";
185 for (auto it = m.begin();
186 it != m.end();
187 ++it) {
188 if (it != m.begin()) out << ",";
189 out << it->first << "=" << it->second;
190 }
191 out << "}";
192 return out;
193 }
194
195 template<class A, class B, class Comp, class Alloc>
196 inline ostream& operator<<(ostream& out, const multimap<A,B,Comp,Alloc>& m)
197 {
198 out << "{{";
199 for (auto it = m.begin();
200 it != m.end();
201 ++it) {
202 if (it != m.begin()) out << ",";
203 out << it->first << "=" << it->second;
204 }
205 out << "}}";
206 return out;
207 }
208
209
210
211
212 /*
213 * comparators for stl containers
214 */
215 // for ceph::unordered_map:
216 // ceph::unordered_map<const char*, long, hash<const char*>, eqstr> vals;
217 struct eqstr
218 {
219 bool operator()(const char* s1, const char* s2) const
220 {
221 return strcmp(s1, s2) == 0;
222 }
223 };
224
225 // for set, map
226 struct ltstr
227 {
228 bool operator()(const char* s1, const char* s2) const
229 {
230 return strcmp(s1, s2) < 0;
231 }
232 };
233
234
235 namespace ceph {
236 class Formatter;
237 }
238
239 #include "encoding.h"
240
241 WRITE_RAW_ENCODER(ceph_fsid)
242 WRITE_RAW_ENCODER(ceph_file_layout)
243 WRITE_RAW_ENCODER(ceph_dir_layout)
244 WRITE_RAW_ENCODER(ceph_mds_session_head)
245 WRITE_RAW_ENCODER(ceph_mds_request_head_legacy)
246 WRITE_RAW_ENCODER(ceph_mds_request_head)
247 WRITE_RAW_ENCODER(ceph_mds_request_release)
248 WRITE_RAW_ENCODER(ceph_filelock)
249 WRITE_RAW_ENCODER(ceph_mds_caps_head)
250 WRITE_RAW_ENCODER(ceph_mds_caps_body_legacy)
251 WRITE_RAW_ENCODER(ceph_mds_cap_peer)
252 WRITE_RAW_ENCODER(ceph_mds_cap_release)
253 WRITE_RAW_ENCODER(ceph_mds_cap_item)
254 WRITE_RAW_ENCODER(ceph_mds_lease)
255 WRITE_RAW_ENCODER(ceph_mds_snap_head)
256 WRITE_RAW_ENCODER(ceph_mds_snap_realm)
257 WRITE_RAW_ENCODER(ceph_mds_reply_head)
258 WRITE_RAW_ENCODER(ceph_mds_reply_cap)
259 WRITE_RAW_ENCODER(ceph_mds_cap_reconnect)
260 WRITE_RAW_ENCODER(ceph_mds_snaprealm_reconnect)
261 WRITE_RAW_ENCODER(ceph_frag_tree_split)
262 WRITE_RAW_ENCODER(ceph_osd_reply_head)
263 WRITE_RAW_ENCODER(ceph_osd_op)
264 WRITE_RAW_ENCODER(ceph_msg_header)
265 WRITE_RAW_ENCODER(ceph_msg_footer)
266 WRITE_RAW_ENCODER(ceph_msg_footer_old)
267 WRITE_RAW_ENCODER(ceph_mon_subscribe_item)
268
269 WRITE_RAW_ENCODER(ceph_mon_statfs)
270 WRITE_RAW_ENCODER(ceph_mon_statfs_reply)
271
272 // ----------------------
273 // some basic types
274
275 // NOTE: these must match ceph_fs.h typedefs
276 typedef uint64_t ceph_tid_t; // transaction id
277 typedef uint64_t version_t;
278 typedef __u32 epoch_t; // map epoch (32bits -> 13 epochs/second for 10 years)
279
280 // --------------------------------------
281 // identify individual mount clients by 64bit value
282
283 struct client_t {
284 int64_t v;
285
286 // cppcheck-suppress noExplicitConstructor
287 client_t(int64_t _v = -2) : v(_v) {}
288
289 void encode(bufferlist& bl) const {
290 ::encode(v, bl);
291 }
292 void decode(bufferlist::iterator& bl) {
293 ::decode(v, bl);
294 }
295 };
296 WRITE_CLASS_ENCODER(client_t)
297
298 static inline bool operator==(const client_t& l, const client_t& r) { return l.v == r.v; }
299 static inline bool operator!=(const client_t& l, const client_t& r) { return l.v != r.v; }
300 static inline bool operator<(const client_t& l, const client_t& r) { return l.v < r.v; }
301 static inline bool operator<=(const client_t& l, const client_t& r) { return l.v <= r.v; }
302 static inline bool operator>(const client_t& l, const client_t& r) { return l.v > r.v; }
303 static inline bool operator>=(const client_t& l, const client_t& r) { return l.v >= r.v; }
304
305 static inline bool operator>=(const client_t& l, int64_t o) { return l.v >= o; }
306 static inline bool operator<(const client_t& l, int64_t o) { return l.v < o; }
307
308 inline ostream& operator<<(ostream& out, const client_t& c) {
309 return out << c.v;
310 }
311
312
313
314 // --
315
316 namespace {
317 inline ostream& format_u(ostream& out, const uint64_t v, const uint64_t n,
318 const int index, const uint64_t mult, const char* u)
319 {
320 char buffer[32];
321
322 if (index == 0) {
323 (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u);
324 } else if ((v % mult) == 0) {
325 // If this is an even multiple of the base, always display
326 // without any decimal fraction.
327 (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u);
328 } else {
329 // We want to choose a precision that reflects the best choice
330 // for fitting in 5 characters. This can get rather tricky when
331 // we have numbers that are very close to an order of magnitude.
332 // For example, when displaying 10239 (which is really 9.999K),
333 // we want only a single place of precision for 10.0K. We could
334 // develop some complex heuristics for this, but it's much
335 // easier just to try each combination in turn.
336 int i;
337 for (i = 2; i >= 0; i--) {
338 if (snprintf(buffer, sizeof(buffer), "%.*f%s", i,
339 static_cast<double>(v) / mult, u) <= 7)
340 break;
341 }
342 }
343
344 return out << buffer;
345 }
346 }
347
348 /*
349 * Use this struct to pretty print values that should be formatted with a
350 * decimal unit prefix (the classic SI units). No actual unit will be added.
351 */
352 struct si_u_t {
353 uint64_t v;
354 explicit si_u_t(uint64_t _v) : v(_v) {};
355 };
356
357 inline ostream& operator<<(ostream& out, const si_u_t& b)
358 {
359 uint64_t n = b.v;
360 int index = 0;
361 uint64_t mult = 1;
362 const char* u[] = {"", "k", "M", "G", "T", "P", "E"};
363
364 while (n >= 1000 && index < 7) {
365 n /= 1000;
366 index++;
367 mult *= 1000;
368 }
369
370 return format_u(out, b.v, n, index, mult, u[index]);
371 }
372
373 /*
374 * Use this struct to pretty print values that should be formatted with a
375 * binary unit prefix (IEC units). Since binary unit prefixes are to be used for
376 * "multiples of units in data processing, data transmission, and digital
377 * information" (so bits and bytes) and so far bits are not printed, the unit
378 * "B" for "byte" is added besides the multiplier.
379 */
380 struct byte_u_t {
381 uint64_t v;
382 explicit byte_u_t(uint64_t _v) : v(_v) {};
383 };
384
385 inline ostream& operator<<(ostream& out, const byte_u_t& b)
386 {
387 uint64_t n = b.v;
388 int index = 0;
389 const char* u[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"};
390
391 while (n >= 1024 && index < 7) {
392 n /= 1024;
393 index++;
394 }
395
396 return format_u(out, b.v, n, index, 1ULL << (10 * index), u[index]);
397 }
398
399 inline ostream& operator<<(ostream& out, const ceph_mon_subscribe_item& i)
400 {
401 return out << i.start
402 << ((i.flags & CEPH_SUBSCRIBE_ONETIME) ? "" : "+");
403 }
404
405 struct weightf_t {
406 float v;
407 // cppcheck-suppress noExplicitConstructor
408 weightf_t(float _v) : v(_v) {}
409 };
410
411 inline ostream& operator<<(ostream& out, const weightf_t& w)
412 {
413 if (w.v < -0.01) {
414 return out << "-";
415 } else if (w.v < 0.000001) {
416 return out << "0";
417 } else {
418 std::streamsize p = out.precision();
419 return out << std::fixed << std::setprecision(5) << w.v << std::setprecision(p);
420 }
421 }
422
423 struct shard_id_t {
424 int8_t id;
425
426 shard_id_t() : id(0) {}
427 explicit shard_id_t(int8_t _id) : id(_id) {}
428
429 operator int8_t() const { return id; }
430
431 const static shard_id_t NO_SHARD;
432
433 void encode(bufferlist &bl) const {
434 ::encode(id, bl);
435 }
436 void decode(bufferlist::iterator &bl) {
437 ::decode(id, bl);
438 }
439 };
440 WRITE_CLASS_ENCODER(shard_id_t)
441 WRITE_EQ_OPERATORS_1(shard_id_t, id)
442 WRITE_CMP_OPERATORS_1(shard_id_t, id)
443 ostream &operator<<(ostream &lhs, const shard_id_t &rhs);
444
445 #if defined(__sun) || defined(_AIX) || defined(DARWIN) || defined(__FreeBSD__)
446 __s32 ceph_to_hostos_errno(__s32 e);
447 __s32 hostos_to_ceph_errno(__s32 e);
448 #else
449 #define ceph_to_hostos_errno(e) (e)
450 #define hostos_to_ceph_errno(e) (e)
451 #endif
452
453 struct errorcode32_t {
454 int32_t code;
455
456 errorcode32_t() : code(0) {}
457 // cppcheck-suppress noExplicitConstructor
458 errorcode32_t(int32_t i) : code(i) {}
459
460 operator int() const { return code; }
461 int* operator&() { return &code; }
462 int operator==(int i) { return code == i; }
463 int operator>(int i) { return code > i; }
464 int operator>=(int i) { return code >= i; }
465 int operator<(int i) { return code < i; }
466 int operator<=(int i) { return code <= i; }
467
468 void encode(bufferlist &bl) const {
469 __s32 newcode = hostos_to_ceph_errno(code);
470 ::encode(newcode, bl);
471 }
472 void decode(bufferlist::iterator &bl) {
473 ::decode(code, bl);
474 code = ceph_to_hostos_errno(code);
475 }
476 };
477 WRITE_CLASS_ENCODER(errorcode32_t)
478 WRITE_EQ_OPERATORS_1(errorcode32_t, code)
479 WRITE_CMP_OPERATORS_1(errorcode32_t, code)
480
481
482 #endif