1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_OS_BLUESTORE_CHECKSUMMER
5 #define CEPH_OS_BLUESTORE_CHECKSUMMER
7 #include "xxHash/xxhash.h"
12 CSUM_NONE = 1, //intentionally set to 1 to be aligned with OSDMnitor's pool_opts_t handling - it treats 0 as unset while we need to distinguish none and unset cases
16 CSUM_CRC32C_16 = 5, // low 16 bits of crc32c
17 CSUM_CRC32C_8 = 6, // low 8 bits of crc32c
20 static const char *get_csum_type_string(unsigned t) {
22 case CSUM_NONE: return "none";
23 case CSUM_XXHASH32: return "xxhash32";
24 case CSUM_XXHASH64: return "xxhash64";
25 case CSUM_CRC32C: return "crc32c";
26 case CSUM_CRC32C_16: return "crc32c_16";
27 case CSUM_CRC32C_8: return "crc32c_8";
28 default: return "???";
31 static int get_csum_string_type(const std::string &s) {
41 return CSUM_CRC32C_16;
47 static size_t get_csum_init_value_size(int csum_type) {
49 case CSUM_NONE: return 0;
50 case CSUM_XXHASH32: return sizeof(xxhash32::init_value_t);
51 case CSUM_XXHASH64: return sizeof(xxhash64::init_value_t);
52 case CSUM_CRC32C: return sizeof(crc32c::init_value_t);
53 case CSUM_CRC32C_16: return sizeof(crc32c_16::init_value_t);
54 case CSUM_CRC32C_8: return sizeof(crc32c_8::init_value_t);
58 static size_t get_csum_value_size(int csum_type) {
60 case CSUM_NONE: return 0;
61 case CSUM_XXHASH32: return 4;
62 case CSUM_XXHASH64: return 8;
63 case CSUM_CRC32C: return 4;
64 case CSUM_CRC32C_16: return 2;
65 case CSUM_CRC32C_8: return 1;
71 typedef uint32_t init_value_t;
72 typedef __le32 value_t;
74 // we have no execution context/state.
76 static void init(state_t *state) {
78 static void fini(state_t *state) {
83 init_value_t init_value,
85 bufferlist::const_iterator& p
87 return p.crc32c(len, init_value);
92 typedef uint32_t init_value_t;
93 typedef __le16 value_t;
95 // we have no execution context/state.
97 static void init(state_t *state) {
99 static void fini(state_t *state) {
104 init_value_t init_value,
106 bufferlist::const_iterator& p
108 return p.crc32c(len, init_value) & 0xffff;
113 typedef uint32_t init_value_t;
114 typedef __u8 value_t;
116 // we have no execution context/state.
118 static void init(state_t *state) {
120 static void fini(state_t *state) {
125 init_value_t init_value,
127 bufferlist::const_iterator& p
129 return p.crc32c(len, init_value) & 0xff;
134 typedef uint32_t init_value_t;
135 typedef __le32 value_t;
137 typedef XXH32_state_t *state_t;
138 static void init(state_t *s) {
139 *s = XXH32_createState();
141 static void fini(state_t *s) {
147 init_value_t init_value,
149 bufferlist::const_iterator& p
151 XXH32_reset(state, init_value);
154 size_t l = p.get_ptr_and_advance(len, &data);
155 XXH32_update(state, data, l);
158 return XXH32_digest(state);
163 typedef uint64_t init_value_t;
164 typedef __le64 value_t;
166 typedef XXH64_state_t *state_t;
167 static void init(state_t *s) {
168 *s = XXH64_createState();
170 static void fini(state_t *s) {
176 init_value_t init_value,
178 bufferlist::const_iterator& p
180 XXH64_reset(state, init_value);
183 size_t l = p.get_ptr_and_advance(len, &data);
184 XXH64_update(state, data, l);
187 return XXH64_digest(state);
192 static int calculate(
193 size_t csum_block_size,
196 const bufferlist &bl,
199 return calculate<Alg>(-1, csum_block_size, offset, length, bl, csum_data);
203 static int calculate(
204 typename Alg::init_value_t init_value,
205 size_t csum_block_size,
208 const bufferlist &bl,
209 bufferptr* csum_data) {
210 assert(length % csum_block_size == 0);
211 size_t blocks = length / csum_block_size;
212 bufferlist::const_iterator p = bl.begin();
213 assert(bl.length() >= length);
215 typename Alg::state_t state;
218 assert(csum_data->length() >= (offset + length) / csum_block_size *
219 sizeof(typename Alg::value_t));
221 typename Alg::value_t *pv =
222 reinterpret_cast<typename Alg::value_t*>(csum_data->c_str());
223 pv += offset / csum_block_size;
225 *pv = Alg::calc(state, init_value, csum_block_size, p);
234 size_t csum_block_size,
237 const bufferlist &bl,
238 const bufferptr& csum_data,
241 assert(length % csum_block_size == 0);
242 bufferlist::const_iterator p = bl.begin();
243 assert(bl.length() >= length);
245 typename Alg::state_t state;
248 const typename Alg::value_t *pv =
249 reinterpret_cast<const typename Alg::value_t*>(csum_data.c_str());
250 pv += offset / csum_block_size;
253 typename Alg::value_t v = Alg::calc(state, -1, csum_block_size, p);
262 pos += csum_block_size;
263 length -= csum_block_size;
266 return -1; // no errors