1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef CEPH_COMMON_SLOPPYCRCMAP_H
#define CEPH_COMMON_SLOPPYCRCMAP_H
#include "include/encoding.h"
namespace ceph {
class Formatter;
}
/**
* SloppyCRCMap
*
* Opportunistically track CRCs on any reads or writes that cover full
* blocks. Verify read results when we have CRC data available for
* the given extent.
*/
class SloppyCRCMap {
static const int crc_iv = 0xffffffff;
std::map<uint64_t, uint32_t> crc_map; // offset -> crc(-1)
uint32_t block_size;
uint32_t zero_crc;
public:
SloppyCRCMap(uint32_t b=0) {
set_block_size(b);
}
void set_block_size(uint32_t b) {
block_size = b;
//zero_crc = ceph_crc32c(0xffffffff, NULL, block_size);
if (b) {
ceph::buffer::list bl;
bl.append_zero(block_size);
zero_crc = bl.crc32c(crc_iv);
} else {
zero_crc = crc_iv;
}
}
/// update based on a write
void write(uint64_t offset, uint64_t len, const ceph::buffer::list& bl,
std::ostream *out = NULL);
/// update based on a truncate
void truncate(uint64_t offset);
/// update based on a zero/punch_hole
void zero(uint64_t offset, uint64_t len);
/// update based on a zero/punch_hole
void clone_range(uint64_t offset, uint64_t len, uint64_t srcoff, const SloppyCRCMap& src,
std::ostream *out = NULL);
/**
* validate a read result
*
* @param offset offset
* @param length length
* @param bl data read
* @param err option ostream to describe errors in detail
* @returns error count, 0 for success
*/
int read(uint64_t offset, uint64_t len, const ceph::buffer::list& bl, std::ostream *err);
void encode(ceph::buffer::list& bl) const;
void decode(ceph::buffer::list::const_iterator& bl);
void dump(ceph::Formatter *f) const;
static void generate_test_instances(std::list<SloppyCRCMap*>& ls);
};
WRITE_CLASS_ENCODER(SloppyCRCMap)
#endif
|