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
) {
316 struct prettybyte_t
{
318 // cppcheck-suppress noExplicitConstructor
319 prettybyte_t(uint64_t _v
) : v(_v
) {}
322 inline ostream
& operator<<(ostream
& out
, const prettybyte_t
& b
)
324 uint64_t bump_after
= 100;
325 if (b
.v
> bump_after
<< 60)
326 return out
<< (b
.v
>> 60) << " EB";
327 if (b
.v
> bump_after
<< 50)
328 return out
<< (b
.v
>> 50) << " PB";
329 if (b
.v
> bump_after
<< 40)
330 return out
<< (b
.v
>> 40) << " TB";
331 if (b
.v
> bump_after
<< 30)
332 return out
<< (b
.v
>> 30) << " GB";
333 if (b
.v
> bump_after
<< 20)
334 return out
<< (b
.v
>> 20) << " MB";
335 if (b
.v
> bump_after
<< 10)
336 return out
<< (b
.v
>> 10) << " kB";
337 return out
<< b
.v
<< " bytes";
342 // cppcheck-suppress noExplicitConstructor
343 si_t(uint64_t _v
) : v(_v
) {}
346 inline ostream
& operator<<(ostream
& out
, const si_t
& b
)
348 uint64_t bump_after
= 100;
349 if (b
.v
> bump_after
<< 60)
350 return out
<< (b
.v
>> 60) << "E";
351 if (b
.v
> bump_after
<< 50)
352 return out
<< (b
.v
>> 50) << "P";
353 if (b
.v
> bump_after
<< 40)
354 return out
<< (b
.v
>> 40) << "T";
355 if (b
.v
> bump_after
<< 30)
356 return out
<< (b
.v
>> 30) << "G";
357 if (b
.v
> bump_after
<< 20)
358 return out
<< (b
.v
>> 20) << "M";
359 if (b
.v
> bump_after
<< 10)
360 return out
<< (b
.v
>> 10) << "k";
366 // cppcheck-suppress noExplicitConstructor
367 pretty_si_t(uint64_t _v
) : v(_v
) {}
370 inline ostream
& operator<<(ostream
& out
, const pretty_si_t
& b
)
372 uint64_t bump_after
= 100;
373 if (b
.v
> bump_after
<< 60)
374 return out
<< (b
.v
>> 60) << " E";
375 if (b
.v
> bump_after
<< 50)
376 return out
<< (b
.v
>> 50) << " P";
377 if (b
.v
> bump_after
<< 40)
378 return out
<< (b
.v
>> 40) << " T";
379 if (b
.v
> bump_after
<< 30)
380 return out
<< (b
.v
>> 30) << " G";
381 if (b
.v
> bump_after
<< 20)
382 return out
<< (b
.v
>> 20) << " M";
383 if (b
.v
> bump_after
<< 10)
384 return out
<< (b
.v
>> 10) << " k";
385 return out
<< b
.v
<< " ";
390 // cppcheck-suppress noExplicitConstructor
391 kb_t(uint64_t _v
) : v(_v
) {}
394 inline ostream
& operator<<(ostream
& out
, const kb_t
& kb
)
396 uint64_t bump_after
= 100;
397 if (kb
.v
> bump_after
<< 40)
398 return out
<< (kb
.v
>> 40) << " PB";
399 if (kb
.v
> bump_after
<< 30)
400 return out
<< (kb
.v
>> 30) << " TB";
401 if (kb
.v
> bump_after
<< 20)
402 return out
<< (kb
.v
>> 20) << " GB";
403 if (kb
.v
> bump_after
<< 10)
404 return out
<< (kb
.v
>> 10) << " MB";
405 return out
<< kb
.v
<< " kB";
408 inline ostream
& operator<<(ostream
& out
, const ceph_mon_subscribe_item
& i
)
410 return out
<< i
.start
411 << ((i
.flags
& CEPH_SUBSCRIBE_ONETIME
) ? "" : "+");
414 enum health_status_t
{
421 inline ostream
& operator<<(ostream
&oss
, const health_status_t status
) {
427 oss
<< "HEALTH_WARN";
439 // cppcheck-suppress noExplicitConstructor
440 weightf_t(float _v
) : v(_v
) {}
443 inline ostream
& operator<<(ostream
& out
, const weightf_t
& w
)
447 } else if (w
.v
< 0.000001) {
450 std::streamsize p
= out
.precision();
451 return out
<< std::fixed
<< std::setprecision(5) << w
.v
<< std::setprecision(p
);
458 shard_id_t() : id(0) {}
459 explicit shard_id_t(int8_t _id
) : id(_id
) {}
461 operator int8_t() const { return id
; }
463 const static shard_id_t NO_SHARD
;
465 void encode(bufferlist
&bl
) const {
468 void decode(bufferlist::iterator
&bl
) {
472 WRITE_CLASS_ENCODER(shard_id_t
)
473 WRITE_EQ_OPERATORS_1(shard_id_t
, id
)
474 WRITE_CMP_OPERATORS_1(shard_id_t
, id
)
475 ostream
&operator<<(ostream
&lhs
, const shard_id_t
&rhs
);
477 #if defined(__sun) || defined(_AIX) || defined(DARWIN) || defined(__FreeBSD__)
478 __s32
ceph_to_hostos_errno(__s32 e
);
479 __s32
hostos_to_ceph_errno(__s32 e
);
481 #define ceph_to_hostos_errno(e) (e)
482 #define hostos_to_ceph_errno(e) (e)
485 struct errorcode32_t
{
488 errorcode32_t() : code(0) {}
489 // cppcheck-suppress noExplicitConstructor
490 errorcode32_t(int32_t i
) : code(i
) {}
492 operator int() const { return code
; }
493 int operator==(int i
) {
497 void encode(bufferlist
&bl
) const {
498 __s32 newcode
= hostos_to_ceph_errno(code
);
499 ::encode(newcode
, bl
);
501 void decode(bufferlist::iterator
&bl
) {
503 code
= ceph_to_hostos_errno(code
);
506 WRITE_CLASS_ENCODER(errorcode32_t
)
507 WRITE_EQ_OPERATORS_1(errorcode32_t
, code
)
508 WRITE_CMP_OPERATORS_1(errorcode32_t
, code
)