]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/SloppyCRCMap.cc
update ceph source to reef 18.2.0
[ceph.git] / ceph / src / common / SloppyCRCMap.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "common/SloppyCRCMap.h"
11fdf7f2 5#include "common/Formatter.h"
7c673cae
FG
6
7using namespace std;
f67539c2 8using ceph::bufferlist;
7c673cae
FG
9
10void SloppyCRCMap::write(uint64_t offset, uint64_t len, const bufferlist& bl,
11 std::ostream *out)
12{
13 int64_t left = len;
14 uint64_t pos = offset;
15 unsigned o = offset % block_size;
16 if (o) {
17 crc_map.erase(offset - o);
18 if (out)
19 *out << "write invalidate " << (offset - o) << "\n";
20 pos += (block_size - o);
21 left -= (block_size - o);
22 }
23 while (left >= block_size) {
24 bufferlist t;
25 t.substr_of(bl, pos - offset, block_size);
26 crc_map[pos] = t.crc32c(crc_iv);
27 if (out)
28 *out << "write set " << pos << " " << crc_map[pos] << "\n";
29 pos += block_size;
30 left -= block_size;
31 }
32 if (left > 0) {
33 crc_map.erase(pos);
34 if (out)
35 *out << "write invalidate " << pos << "\n";
36 }
37}
38
39int SloppyCRCMap::read(uint64_t offset, uint64_t len, const bufferlist& bl,
40 std::ostream *err)
41{
42 int errors = 0;
43 int64_t left = len;
44 uint64_t pos = offset;
45 unsigned o = offset % block_size;
46 if (o) {
47 pos += (block_size - o);
48 left -= (block_size - o);
49 }
50 while (left >= block_size) {
51 // FIXME: this could be more efficient if we avoid doing a find()
52 // on each iteration
53 std::map<uint64_t,uint32_t>::iterator p = crc_map.find(pos);
54 if (p != crc_map.end()) {
55 bufferlist t;
56 t.substr_of(bl, pos - offset, block_size);
57 uint32_t crc = t.crc32c(crc_iv);
58 if (p->second != crc) {
59 errors++;
60 if (err)
61 *err << "offset " << pos << " len " << block_size
62 << " has crc " << crc << " expected " << p->second << "\n";
63 }
64 }
65 pos += block_size;
66 left -= block_size;
67 }
68 return errors;
69}
70
71void SloppyCRCMap::truncate(uint64_t offset)
72{
73 offset -= offset % block_size;
74 std::map<uint64_t,uint32_t>::iterator p = crc_map.lower_bound(offset);
75 while (p != crc_map.end())
76 crc_map.erase(p++);
77}
78
79void SloppyCRCMap::zero(uint64_t offset, uint64_t len)
80{
81 int64_t left = len;
82 uint64_t pos = offset;
83 unsigned o = offset % block_size;
84 if (o) {
85 crc_map.erase(offset - o);
86 pos += (block_size - o);
87 left -= (block_size - o);
88 }
89 while (left >= block_size) {
90 crc_map[pos] = zero_crc;
91 pos += block_size;
92 left -= block_size;
93 }
94 if (left > 0)
95 crc_map.erase(pos);
96}
97
98void SloppyCRCMap::clone_range(uint64_t offset, uint64_t len,
99 uint64_t srcoff, const SloppyCRCMap& src,
100 std::ostream *out)
101{
102 int64_t left = len;
103 uint64_t pos = offset;
104 uint64_t srcpos = srcoff;
105 unsigned o = offset % block_size;
106 if (o) {
107 crc_map.erase(offset - o);
108 pos += (block_size - o);
109 srcpos += (block_size - o);
110 left -= (block_size - o);
111 if (out)
112 *out << "clone_range invalidate " << (offset - o) << "\n";
113 }
114 while (left >= block_size) {
115 // FIXME: this could be more efficient.
116 if (block_size == src.block_size) {
117 map<uint64_t,uint32_t>::const_iterator p = src.crc_map.find(srcpos);
118 if (p != src.crc_map.end()) {
119 crc_map[pos] = p->second;
120 if (out)
121 *out << "clone_range copy " << pos << " " << p->second << "\n";
122 } else {
123 crc_map.erase(pos);
124 if (out)
125 *out << "clone_range invalidate " << pos << "\n";
126 }
127 } else {
128 crc_map.erase(pos);
129 if (out)
130 *out << "clone_range invalidate " << pos << "\n";
131 }
132 pos += block_size;
133 srcpos += block_size;
134 left -= block_size;
135 }
136 if (left > 0) {
137 crc_map.erase(pos);
138 if (out)
139 *out << "clone_range invalidate " << pos << "\n";
140 }
141}
142
143void SloppyCRCMap::encode(bufferlist& bl) const
144{
145 ENCODE_START(1, 1, bl);
11fdf7f2
TL
146 encode(block_size, bl);
147 encode(crc_map, bl);
7c673cae
FG
148 ENCODE_FINISH(bl);
149}
150
11fdf7f2 151void SloppyCRCMap::decode(bufferlist::const_iterator& bl)
7c673cae
FG
152{
153 DECODE_START(1, bl);
154 uint32_t bs;
11fdf7f2 155 decode(bs, bl);
7c673cae 156 set_block_size(bs);
11fdf7f2 157 decode(crc_map, bl);
7c673cae
FG
158 DECODE_FINISH(bl);
159}
160
11fdf7f2 161void SloppyCRCMap::dump(ceph::Formatter *f) const
7c673cae
FG
162{
163 f->dump_unsigned("block_size", block_size);
164 f->open_array_section("crc_map");
165 for (map<uint64_t,uint32_t>::const_iterator p = crc_map.begin(); p != crc_map.end(); ++p) {
166 f->open_object_section("crc");
167 f->dump_unsigned("offset", p->first);
168 f->dump_unsigned("crc", p->second);
169 f->close_section();
170 }
171 f->close_section();
172}
173
174void SloppyCRCMap::generate_test_instances(list<SloppyCRCMap*>& ls)
175{
176 ls.push_back(new SloppyCRCMap);
177 ls.push_back(new SloppyCRCMap(2));
178 bufferlist bl;
179 bl.append("some data");
180 ls.back()->write(1, bl.length(), bl);
181 ls.back()->write(10, bl.length(), bl);
182 ls.back()->zero(4, 2);
183}