From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/include/types.h | 626 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 626 insertions(+) create mode 100644 src/include/types.h (limited to 'src/include/types.h') diff --git a/src/include/types.h b/src/include/types.h new file mode 100644 index 000000000..60d1fb305 --- /dev/null +++ b/src/include/types.h @@ -0,0 +1,626 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ +#ifndef CEPH_TYPES_H +#define CEPH_TYPES_H + +// this is needed for ceph_fs to compile in userland +#include "int_types.h" +#include "byteorder.h" + +#include "uuid.h" + +#include +#include +#include + +#include "ceph_fs.h" +#include "ceph_frag.h" +#include "rbd_types.h" + +#ifdef __cplusplus +#ifndef _BACKWARD_BACKWARD_WARNING_H +#define _BACKWARD_BACKWARD_WARNING_H // make gcc 4.3 shut up about hash_* +#endif +#endif + +extern "C" { +#include +#include +#include +#include "statlite.h" +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "include/unordered_map.h" + +#include "object.h" +#include "intarith.h" + +#include "acconfig.h" + +#include "assert.h" + +// DARWIN compatibility +#ifdef __APPLE__ +typedef long long loff_t; +typedef long long off64_t; +#define O_DIRECT 00040000 +#endif + +// FreeBSD compatibility +#ifdef __FreeBSD__ +typedef off_t loff_t; +typedef off_t off64_t; +#endif + +#if defined(__sun) || defined(_AIX) +typedef off_t loff_t; +#endif + + +// -- io helpers -- + +// Forward declare all the I/O helpers so strict ADL can find them in +// the case of containers of containers. I'm tempted to abstract this +// stuff using template templates like I did for denc. + +namespace std { +template +inline std::ostream& operator<<(std::ostream&out, const std::pair& v); +template +inline std::ostream& operator<<(std::ostream& out, const std::vector& v); +template +inline std::ostream& operator<<(std::ostream& out, const boost::container::small_vector& v); +template +inline std::ostream& operator<<(std::ostream& out, const std::deque& v); +template +inline std::ostream& operator<<(std::ostream& out, const std::tuple &t); +template +inline std::ostream& operator<<(std::ostream& out, const std::optional &t); +template +inline std::ostream& operator<<(std::ostream& out, const std::list& ilist); +template +inline std::ostream& operator<<(std::ostream& out, const std::set& iset); +template +inline std::ostream& operator<<(std::ostream& out, const std::multiset& iset); +template +inline std::ostream& operator<<(std::ostream& out, const std::map& m); +template +inline std::ostream& operator<<(std::ostream& out, const std::multimap& m); +} + +namespace boost { +template +inline std::ostream& operator<<(std::ostream& out, const boost::tuple &t); + +namespace container { +template +inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_set& iset); +template +inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_map& iset); +} +} + +namespace std { +template +inline std::ostream& operator<<(std::ostream& out, const std::pair& v) { + return out << v.first << "," << v.second; +} + +template +inline std::ostream& operator<<(std::ostream& out, const std::vector& v) { + bool first = true; + out << "["; + for (const auto& p : v) { + if (!first) out << ","; + out << p; + first = false; + } + out << "]"; + return out; +} + +template +inline std::ostream& operator<<(std::ostream& out, const boost::container::small_vector& v) { + bool first = true; + out << "["; + for (const auto& p : v) { + if (!first) out << ","; + out << p; + first = false; + } + out << "]"; + return out; +} + +template +inline std::ostream& operator<<(std::ostream& out, const std::deque& v) { + out << "<"; + for (auto p = v.begin(); p != v.end(); ++p) { + if (p != v.begin()) out << ","; + out << *p; + } + out << ">"; + return out; +} + +template +inline std::ostream& operator<<(std::ostream& out, const std::tuple &t) { + auto f = [n = sizeof...(Ts), i = 0U, &out](const auto& e) mutable { + out << e; + if (++i != n) + out << ","; + }; + ceph::for_each(t, f); + return out; +} + +// Mimics boost::optional +template +inline std::ostream& operator<<(std::ostream& out, const std::optional &t) { + if (!t) + out << "--" ; + else + out << ' ' << *t ; + return out; +} + +template +inline std::ostream& operator<<(std::ostream& out, const std::list& ilist) { + for (auto it = ilist.begin(); + it != ilist.end(); + ++it) { + if (it != ilist.begin()) out << ","; + out << *it; + } + return out; +} + +template +inline std::ostream& operator<<(std::ostream& out, const std::set& iset) { + for (auto it = iset.begin(); + it != iset.end(); + ++it) { + if (it != iset.begin()) out << ","; + out << *it; + } + return out; +} + +template +inline std::ostream& operator<<(std::ostream& out, const std::multiset& iset) { + for (auto it = iset.begin(); + it != iset.end(); + ++it) { + if (it != iset.begin()) out << ","; + out << *it; + } + return out; +} + +template +inline std::ostream& operator<<(std::ostream& out, const std::map& m) +{ + out << "{"; + for (auto it = m.begin(); + it != m.end(); + ++it) { + if (it != m.begin()) out << ","; + out << it->first << "=" << it->second; + } + out << "}"; + return out; +} + +template +inline std::ostream& operator<<(std::ostream& out, const std::multimap& m) +{ + out << "{{"; + for (auto it = m.begin(); + it != m.end(); + ++it) { + if (it != m.begin()) out << ","; + out << it->first << "=" << it->second; + } + out << "}}"; + return out; +} + +} // namespace std + +namespace boost { +namespace tuples { +template +inline std::ostream& operator<<(std::ostream& out, const boost::tuples::tuple &t) { + return out << boost::get<0>(t) << "," + << boost::get<1>(t) << "," + << boost::get<2>(t); +} +} +namespace container { +template +inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_set& iset) { + for (auto it = iset.begin(); + it != iset.end(); + ++it) { + if (it != iset.begin()) out << ","; + out << *it; + } + return out; +} + +template +inline std::ostream& operator<<(std::ostream& out, const boost::container::flat_map& m) { + for (auto it = m.begin(); + it != m.end(); + ++it) { + if (it != m.begin()) out << ","; + out << it->first << "=" << it->second; + } + return out; +} +} +} // namespace boost + + + +/* + * comparators for stl containers + */ +// for ceph::unordered_map: +// ceph::unordered_map, eqstr> vals; +struct eqstr +{ + bool operator()(const char* s1, const char* s2) const + { + return strcmp(s1, s2) == 0; + } +}; + +// for set, map +struct ltstr +{ + bool operator()(const char* s1, const char* s2) const + { + return strcmp(s1, s2) < 0; + } +}; + + +namespace ceph { + class Formatter; +} + +#include "encoding.h" + +WRITE_RAW_ENCODER(ceph_fsid) +WRITE_RAW_ENCODER(ceph_file_layout) +WRITE_RAW_ENCODER(ceph_dir_layout) +WRITE_RAW_ENCODER(ceph_mds_session_head) +WRITE_RAW_ENCODER(ceph_mds_request_head_legacy) +WRITE_RAW_ENCODER(ceph_mds_request_head) +WRITE_RAW_ENCODER(ceph_mds_request_release) +WRITE_RAW_ENCODER(ceph_filelock) +WRITE_RAW_ENCODER(ceph_mds_caps_head) +WRITE_RAW_ENCODER(ceph_mds_caps_export_body) +WRITE_RAW_ENCODER(ceph_mds_caps_non_export_body) +WRITE_RAW_ENCODER(ceph_mds_cap_peer) +WRITE_RAW_ENCODER(ceph_mds_cap_release) +WRITE_RAW_ENCODER(ceph_mds_cap_item) +WRITE_RAW_ENCODER(ceph_mds_lease) +WRITE_RAW_ENCODER(ceph_mds_snap_head) +WRITE_RAW_ENCODER(ceph_mds_snap_realm) +WRITE_RAW_ENCODER(ceph_mds_reply_head) +WRITE_RAW_ENCODER(ceph_mds_reply_cap) +WRITE_RAW_ENCODER(ceph_mds_cap_reconnect) +WRITE_RAW_ENCODER(ceph_mds_snaprealm_reconnect) +WRITE_RAW_ENCODER(ceph_frag_tree_split) +WRITE_RAW_ENCODER(ceph_osd_reply_head) +WRITE_RAW_ENCODER(ceph_osd_op) +WRITE_RAW_ENCODER(ceph_msg_header) +WRITE_RAW_ENCODER(ceph_msg_footer) +WRITE_RAW_ENCODER(ceph_msg_footer_old) +WRITE_RAW_ENCODER(ceph_mon_subscribe_item) + +WRITE_RAW_ENCODER(ceph_mon_statfs) +WRITE_RAW_ENCODER(ceph_mon_statfs_reply) + +// ---------------------- +// some basic types + +// NOTE: these must match ceph_fs.h typedefs +typedef uint64_t ceph_tid_t; // transaction id +typedef uint64_t version_t; +typedef __u32 epoch_t; // map epoch (32bits -> 13 epochs/second for 10 years) + +// -------------------------------------- +// identify individual mount clients by 64bit value + +struct client_t { + int64_t v; + + // cppcheck-suppress noExplicitConstructor + client_t(int64_t _v = -2) : v(_v) {} + + void encode(ceph::buffer::list& bl) const { + using ceph::encode; + encode(v, bl); + } + void decode(ceph::buffer::list::const_iterator& bl) { + using ceph::decode; + decode(v, bl); + } +}; +WRITE_CLASS_ENCODER(client_t) + +static inline bool operator==(const client_t& l, const client_t& r) { return l.v == r.v; } +static inline bool operator!=(const client_t& l, const client_t& r) { return l.v != r.v; } +static inline bool operator<(const client_t& l, const client_t& r) { return l.v < r.v; } +static inline bool operator<=(const client_t& l, const client_t& r) { return l.v <= r.v; } +static inline bool operator>(const client_t& l, const client_t& r) { return l.v > r.v; } +static inline bool operator>=(const client_t& l, const client_t& r) { return l.v >= r.v; } + +static inline bool operator>=(const client_t& l, int64_t o) { return l.v >= o; } +static inline bool operator<(const client_t& l, int64_t o) { return l.v < o; } + +inline std::ostream& operator<<(std::ostream& out, const client_t& c) { + return out << c.v; +} + + + +// -- + +namespace { +inline std::ostream& format_u(std::ostream& out, const uint64_t v, const uint64_t n, + const int index, const uint64_t mult, const char* u) + { + char buffer[32]; + + if (index == 0) { + (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u); + } else if ((v % mult) == 0) { + // If this is an even multiple of the base, always display + // without any decimal fraction. + (void) snprintf(buffer, sizeof(buffer), "%" PRId64 "%s", n, u); + } else { + // We want to choose a precision that reflects the best choice + // for fitting in 5 characters. This can get rather tricky when + // we have numbers that are very close to an order of magnitude. + // For example, when displaying 10239 (which is really 9.999K), + // we want only a single place of precision for 10.0K. We could + // develop some complex heuristics for this, but it's much + // easier just to try each combination in turn. + int i; + for (i = 2; i >= 0; i--) { + if (snprintf(buffer, sizeof(buffer), "%.*f%s", i, + static_cast(v) / mult, u) <= 7) + break; + } + } + + return out << buffer; + } +} + +/* + * Use this struct to pretty print values that should be formatted with a + * decimal unit prefix (the classic SI units). No actual unit will be added. + */ +struct si_u_t { + uint64_t v; + explicit si_u_t(uint64_t _v) : v(_v) {}; +}; + +inline std::ostream& operator<<(std::ostream& out, const si_u_t& b) +{ + uint64_t n = b.v; + int index = 0; + uint64_t mult = 1; + const char* u[] = {"", "k", "M", "G", "T", "P", "E"}; + + while (n >= 1000 && index < 7) { + n /= 1000; + index++; + mult *= 1000; + } + + return format_u(out, b.v, n, index, mult, u[index]); +} + +/* + * Use this struct to pretty print values that should be formatted with a + * binary unit prefix (IEC units). Since binary unit prefixes are to be used for + * "multiples of units in data processing, data transmission, and digital + * information" (so bits and bytes) and so far bits are not printed, the unit + * "B" for "byte" is added besides the multiplier. + */ +struct byte_u_t { + uint64_t v; + explicit byte_u_t(uint64_t _v) : v(_v) {}; +}; + +inline std::ostream& operator<<(std::ostream& out, const byte_u_t& b) +{ + uint64_t n = b.v; + int index = 0; + const char* u[] = {" B", " KiB", " MiB", " GiB", " TiB", " PiB", " EiB"}; + + while (n >= 1024 && index < 7) { + n /= 1024; + index++; + } + + return format_u(out, b.v, n, index, 1ULL << (10 * index), u[index]); +} + +inline std::ostream& operator<<(std::ostream& out, const ceph_mon_subscribe_item& i) +{ + return out << i.start + << ((i.flags & CEPH_SUBSCRIBE_ONETIME) ? "" : "+"); +} + +struct weightf_t { + float v; + // cppcheck-suppress noExplicitConstructor + weightf_t(float _v) : v(_v) {} +}; + +inline std::ostream& operator<<(std::ostream& out, const weightf_t& w) +{ + if (w.v < -0.01F) { + return out << "-"; + } else if (w.v < 0.000001F) { + return out << "0"; + } else { + std::streamsize p = out.precision(); + return out << std::fixed << std::setprecision(5) << w.v << std::setprecision(p); + } +} + +struct shard_id_t { + int8_t id; + + shard_id_t() : id(0) {} + explicit shard_id_t(int8_t _id) : id(_id) {} + + operator int8_t() const { return id; } + + const static shard_id_t NO_SHARD; + + void encode(ceph::buffer::list &bl) const { + using ceph::encode; + encode(id, bl); + } + void decode(ceph::buffer::list::const_iterator &bl) { + using ceph::decode; + decode(id, bl); + } +}; +WRITE_CLASS_ENCODER(shard_id_t) +WRITE_EQ_OPERATORS_1(shard_id_t, id) +WRITE_CMP_OPERATORS_1(shard_id_t, id) +std::ostream &operator<<(std::ostream &lhs, const shard_id_t &rhs); + +#if defined(__sun) || defined(_AIX) || defined(__APPLE__) || \ + defined(__FreeBSD__) || defined(_WIN32) +extern "C" { +__s32 ceph_to_hostos_errno(__s32 e); +__s32 hostos_to_ceph_errno(__s32 e); +} +#else +#define ceph_to_hostos_errno(e) (e) +#define hostos_to_ceph_errno(e) (e) +#endif + +struct errorcode32_t { + int32_t code; + + errorcode32_t() : code(0) {} + // cppcheck-suppress noExplicitConstructor + errorcode32_t(int32_t i) : code(i) {} + + operator int() const { return code; } + int* operator&() { return &code; } + int operator==(int i) { return code == i; } + int operator>(int i) { return code > i; } + int operator>=(int i) { return code >= i; } + int operator<(int i) { return code < i; } + int operator<=(int i) { return code <= i; } + + void encode(ceph::buffer::list &bl) const { + using ceph::encode; + __s32 newcode = hostos_to_ceph_errno(code); + encode(newcode, bl); + } + void decode(ceph::buffer::list::const_iterator &bl) { + using ceph::decode; + decode(code, bl); + code = ceph_to_hostos_errno(code); + } +}; +WRITE_CLASS_ENCODER(errorcode32_t) +WRITE_EQ_OPERATORS_1(errorcode32_t, code) +WRITE_CMP_OPERATORS_1(errorcode32_t, code) + +template +struct sha_digest_t { + constexpr static uint32_t SIZE = S; + // TODO: we might consider std::array in the future. Avoiding it for now + // as sha_digest_t is a part of our public API. + unsigned char v[S] = {0}; + + std::string to_str() const { + char str[S * 2 + 1] = {0}; + str[0] = '\0'; + for (size_t i = 0; i < S; i++) { + ::sprintf(&str[i * 2], "%02x", static_cast(v[i])); + } + return std::string(str); + } + sha_digest_t(const unsigned char *_v) { memcpy(v, _v, SIZE); }; + sha_digest_t() {} + + bool operator==(const sha_digest_t& r) const { + return ::memcmp(v, r.v, SIZE) == 0; + } + bool operator!=(const sha_digest_t& r) const { + return ::memcmp(v, r.v, SIZE) != 0; + } + + void encode(ceph::buffer::list &bl) const { + // copy to avoid reinterpret_cast, is_pod and other nasty things + using ceph::encode; + std::array tmparr; + memcpy(tmparr.data(), v, SIZE); + encode(tmparr, bl); + } + void decode(ceph::buffer::list::const_iterator &bl) { + using ceph::decode; + std::array tmparr; + decode(tmparr, bl); + memcpy(v, tmparr.data(), SIZE); + } +}; + +template +inline std::ostream &operator<<(std::ostream &out, const sha_digest_t &b) { + std::string str = b.to_str(); + return out << str; +} + +using sha1_digest_t = sha_digest_t<20>; +WRITE_CLASS_ENCODER(sha1_digest_t) + +using sha256_digest_t = sha_digest_t<32>; +WRITE_CLASS_ENCODER(sha256_digest_t) + +using sha512_digest_t = sha_digest_t<64>; + +using md5_digest_t = sha_digest_t<16>; +WRITE_CLASS_ENCODER(md5_digest_t) + + +#endif -- cgit v1.2.3