]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/SloppyCRCMap.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "common/SloppyCRCMap.h"
5 #include "common/Formatter.h"
8 using ceph::bufferlist
;
10 void SloppyCRCMap::write(uint64_t offset
, uint64_t len
, const bufferlist
& bl
,
14 uint64_t pos
= offset
;
15 unsigned o
= offset
% block_size
;
17 crc_map
.erase(offset
- o
);
19 *out
<< "write invalidate " << (offset
- o
) << "\n";
20 pos
+= (block_size
- o
);
21 left
-= (block_size
- o
);
23 while (left
>= block_size
) {
25 t
.substr_of(bl
, pos
- offset
, block_size
);
26 crc_map
[pos
] = t
.crc32c(crc_iv
);
28 *out
<< "write set " << pos
<< " " << crc_map
[pos
] << "\n";
35 *out
<< "write invalidate " << pos
<< "\n";
39 int SloppyCRCMap::read(uint64_t offset
, uint64_t len
, const bufferlist
& bl
,
44 uint64_t pos
= offset
;
45 unsigned o
= offset
% block_size
;
47 pos
+= (block_size
- o
);
48 left
-= (block_size
- o
);
50 while (left
>= block_size
) {
51 // FIXME: this could be more efficient if we avoid doing a find()
53 std::map
<uint64_t,uint32_t>::iterator p
= crc_map
.find(pos
);
54 if (p
!= crc_map
.end()) {
56 t
.substr_of(bl
, pos
- offset
, block_size
);
57 uint32_t crc
= t
.crc32c(crc_iv
);
58 if (p
->second
!= crc
) {
61 *err
<< "offset " << pos
<< " len " << block_size
62 << " has crc " << crc
<< " expected " << p
->second
<< "\n";
71 void SloppyCRCMap::truncate(uint64_t offset
)
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())
79 void SloppyCRCMap::zero(uint64_t offset
, uint64_t len
)
82 uint64_t pos
= offset
;
83 unsigned o
= offset
% block_size
;
85 crc_map
.erase(offset
- o
);
86 pos
+= (block_size
- o
);
87 left
-= (block_size
- o
);
89 while (left
>= block_size
) {
90 crc_map
[pos
] = zero_crc
;
98 void SloppyCRCMap::clone_range(uint64_t offset
, uint64_t len
,
99 uint64_t srcoff
, const SloppyCRCMap
& src
,
103 uint64_t pos
= offset
;
104 uint64_t srcpos
= srcoff
;
105 unsigned o
= offset
% block_size
;
107 crc_map
.erase(offset
- o
);
108 pos
+= (block_size
- o
);
109 srcpos
+= (block_size
- o
);
110 left
-= (block_size
- o
);
112 *out
<< "clone_range invalidate " << (offset
- o
) << "\n";
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
;
121 *out
<< "clone_range copy " << pos
<< " " << p
->second
<< "\n";
125 *out
<< "clone_range invalidate " << pos
<< "\n";
130 *out
<< "clone_range invalidate " << pos
<< "\n";
133 srcpos
+= block_size
;
139 *out
<< "clone_range invalidate " << pos
<< "\n";
143 void SloppyCRCMap::encode(bufferlist
& bl
) const
145 ENCODE_START(1, 1, bl
);
146 encode(block_size
, bl
);
151 void SloppyCRCMap::decode(bufferlist::const_iterator
& bl
)
161 void SloppyCRCMap::dump(ceph::Formatter
*f
) const
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
);
174 void SloppyCRCMap::generate_test_instances(list
<SloppyCRCMap
*>& ls
)
176 ls
.push_back(new SloppyCRCMap
);
177 ls
.push_back(new SloppyCRCMap(2));
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);