1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
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.
17 // this is needed for ceph_fs to compile in userland
18 #include "int_types.h"
19 #include "byteorder.h"
23 #include <netinet/in.h>
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
33 #include "ceph_frag.h"
34 #include "rbd_types.h"
42 #ifndef _BACKWARD_BACKWARD_WARNING_H
43 #define _BACKWARD_BACKWARD_WARNING_H // make gcc 4.3 shut up about hash_*
49 #include <sys/types.h>
64 #include "include/unordered_map.h"
73 // DARWIN compatibility
75 typedef long long loff_t
;
76 typedef long long off64_t
;
77 #define O_DIRECT 00040000
80 // FreeBSD compatibility
83 typedef off_t off64_t
;
86 #if defined(__sun) || defined(_AIX)
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.
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
);
116 template<class A
, class B
>
117 inline ostream
& operator<<(ostream
& out
, const pair
<A
,B
>& v
) {
118 return out
<< v
.first
<< "," << v
.second
;
121 template<class A
, class Alloc
>
122 inline ostream
& operator<<(ostream
& out
, const vector
<A
,Alloc
>& v
) {
124 for (auto p
= v
.begin(); p
!= v
.end(); ++p
) {
125 if (p
!= v
.begin()) out
<< ",";
131 template<class A
, class Alloc
>
132 inline ostream
& operator<<(ostream
& out
, const deque
<A
,Alloc
>& v
) {
134 for (auto p
= v
.begin(); p
!= v
.end(); ++p
) {
135 if (p
!= v
.begin()) out
<< ",";
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
);
148 template<class A
, class Alloc
>
149 inline ostream
& operator<<(ostream
& out
, const list
<A
,Alloc
>& ilist
) {
150 for (auto it
= ilist
.begin();
153 if (it
!= ilist
.begin()) out
<< ",";
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();
164 if (it
!= iset
.begin()) out
<< ",";
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();
175 if (it
!= iset
.begin()) out
<< ",";
181 template<class A
, class B
, class Comp
, class Alloc
>
182 inline ostream
& operator<<(ostream
& out
, const map
<A
,B
,Comp
,Alloc
>& m
)
185 for (auto it
= m
.begin();
188 if (it
!= m
.begin()) out
<< ",";
189 out
<< it
->first
<< "=" << it
->second
;
195 template<class A
, class B
, class Comp
, class Alloc
>
196 inline ostream
& operator<<(ostream
& out
, const multimap
<A
,B
,Comp
,Alloc
>& m
)
199 for (auto it
= m
.begin();
202 if (it
!= m
.begin()) out
<< ",";
203 out
<< it
->first
<< "=" << it
->second
;
213 * comparators for stl containers
215 // for ceph::unordered_map:
216 // ceph::unordered_map<const char*, long, hash<const char*>, eqstr> vals;
219 bool operator()(const char* s1
, const char* s2
) const
221 return strcmp(s1
, s2
) == 0;
228 bool operator()(const char* s1
, const char* s2
) const
230 return strcmp(s1
, s2
) < 0;
239 #include "encoding.h"
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
)
269 WRITE_RAW_ENCODER(ceph_mon_statfs
)
270 WRITE_RAW_ENCODER(ceph_mon_statfs_reply
)
272 // ----------------------
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)
280 // --------------------------------------
281 // identify individual mount clients by 64bit value
286 // cppcheck-suppress noExplicitConstructor
287 client_t(int64_t _v
= -2) : v(_v
) {}
289 void encode(bufferlist
& bl
) const {
292 void decode(bufferlist::iterator
& bl
) {
296 WRITE_CLASS_ENCODER(client_t
)
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
; }
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
; }
308 inline ostream
& operator<<(ostream
& out
, const client_t
& c
) {
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
)
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
);
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.
337 for (i
= 2; i
>= 0; i
--) {
338 if (snprintf(buffer
, sizeof(buffer
), "%.*f%s", i
,
339 static_cast<double>(v
) / mult
, u
) <= 7)
344 return out
<< buffer
;
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.
354 explicit si_u_t(uint64_t _v
) : v(_v
) {};
357 inline ostream
& operator<<(ostream
& out
, const si_u_t
& b
)
362 const char* u
[] = {"", "k", "M", "G", "T", "P", "E"};
364 while (n
>= 1000 && index
< 7) {
370 return format_u(out
, b
.v
, n
, index
, mult
, u
[index
]);
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.
382 explicit byte_u_t(uint64_t _v
) : v(_v
) {};
385 inline ostream
& operator<<(ostream
& out
, const byte_u_t
& b
)
389 const char* u
[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"};
391 while (n
>= 1024 && index
< 7) {
396 return format_u(out
, b
.v
, n
, index
, 1ULL << (10 * index
), u
[index
]);
399 inline ostream
& operator<<(ostream
& out
, const ceph_mon_subscribe_item
& i
)
401 return out
<< i
.start
402 << ((i
.flags
& CEPH_SUBSCRIBE_ONETIME
) ? "" : "+");
407 // cppcheck-suppress noExplicitConstructor
408 weightf_t(float _v
) : v(_v
) {}
411 inline ostream
& operator<<(ostream
& out
, const weightf_t
& w
)
415 } else if (w
.v
< 0.000001) {
418 std::streamsize p
= out
.precision();
419 return out
<< std::fixed
<< std::setprecision(5) << w
.v
<< std::setprecision(p
);
426 shard_id_t() : id(0) {}
427 explicit shard_id_t(int8_t _id
) : id(_id
) {}
429 operator int8_t() const { return id
; }
431 const static shard_id_t NO_SHARD
;
433 void encode(bufferlist
&bl
) const {
436 void decode(bufferlist::iterator
&bl
) {
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
);
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
);
449 #define ceph_to_hostos_errno(e) (e)
450 #define hostos_to_ceph_errno(e) (e)
453 struct errorcode32_t
{
456 errorcode32_t() : code(0) {}
457 // cppcheck-suppress noExplicitConstructor
458 errorcode32_t(int32_t i
) : code(i
) {}
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
; }
468 void encode(bufferlist
&bl
) const {
469 __s32 newcode
= hostos_to_ceph_errno(code
);
470 ::encode(newcode
, bl
);
472 void decode(bufferlist::iterator
&bl
) {
474 code
= ceph_to_hostos_errno(code
);
477 WRITE_CLASS_ENCODER(errorcode32_t
)
478 WRITE_EQ_OPERATORS_1(errorcode32_t
, code
)
479 WRITE_CMP_OPERATORS_1(errorcode32_t
, code
)