]> git.proxmox.com Git - ceph.git/blame - ceph/src/osd/ECUtil.cc
update sources to v12.1.0
[ceph.git] / ceph / src / osd / ECUtil.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2
3#include <errno.h>
4#include "include/encoding.h"
5#include "ECUtil.h"
31f18b77 6using namespace std;
7c673cae
FG
7
8int ECUtil::decode(
9 const stripe_info_t &sinfo,
10 ErasureCodeInterfaceRef &ec_impl,
11 map<int, bufferlist> &to_decode,
12 bufferlist *out) {
13 assert(to_decode.size());
14
15 uint64_t total_data_size = to_decode.begin()->second.length();
16 assert(total_data_size % sinfo.get_chunk_size() == 0);
17
18 assert(out);
19 assert(out->length() == 0);
20
21 for (map<int, bufferlist>::iterator i = to_decode.begin();
22 i != to_decode.end();
23 ++i) {
24 assert(i->second.length() == total_data_size);
25 }
26
27 if (total_data_size == 0)
28 return 0;
29
30 for (uint64_t i = 0; i < total_data_size; i += sinfo.get_chunk_size()) {
31 map<int, bufferlist> chunks;
32 for (map<int, bufferlist>::iterator j = to_decode.begin();
33 j != to_decode.end();
34 ++j) {
35 chunks[j->first].substr_of(j->second, i, sinfo.get_chunk_size());
36 }
37 bufferlist bl;
38 int r = ec_impl->decode_concat(chunks, &bl);
39 assert(bl.length() == sinfo.get_stripe_width());
40 assert(r == 0);
41 out->claim_append(bl);
42 }
43 return 0;
44}
45
46int ECUtil::decode(
47 const stripe_info_t &sinfo,
48 ErasureCodeInterfaceRef &ec_impl,
49 map<int, bufferlist> &to_decode,
50 map<int, bufferlist*> &out) {
51 assert(to_decode.size());
52
53 uint64_t total_data_size = to_decode.begin()->second.length();
54 assert(total_data_size % sinfo.get_chunk_size() == 0);
55
56 for (map<int, bufferlist>::iterator i = to_decode.begin();
57 i != to_decode.end();
58 ++i) {
59 assert(i->second.length() == total_data_size);
60 }
61
62 if (total_data_size == 0)
63 return 0;
64
65 set<int> need;
66 for (map<int, bufferlist*>::iterator i = out.begin();
67 i != out.end();
68 ++i) {
69 assert(i->second);
70 assert(i->second->length() == 0);
71 need.insert(i->first);
72 }
73
74 for (uint64_t i = 0; i < total_data_size; i += sinfo.get_chunk_size()) {
75 map<int, bufferlist> chunks;
76 for (map<int, bufferlist>::iterator j = to_decode.begin();
77 j != to_decode.end();
78 ++j) {
79 chunks[j->first].substr_of(j->second, i, sinfo.get_chunk_size());
80 }
81 map<int, bufferlist> out_bls;
82 int r = ec_impl->decode(need, chunks, &out_bls);
83 assert(r == 0);
84 for (map<int, bufferlist*>::iterator j = out.begin();
85 j != out.end();
86 ++j) {
87 assert(out_bls.count(j->first));
88 assert(out_bls[j->first].length() == sinfo.get_chunk_size());
89 j->second->claim_append(out_bls[j->first]);
90 }
91 }
92 for (map<int, bufferlist*>::iterator i = out.begin();
93 i != out.end();
94 ++i) {
95 assert(i->second->length() == total_data_size);
96 }
97 return 0;
98}
99
100int ECUtil::encode(
101 const stripe_info_t &sinfo,
102 ErasureCodeInterfaceRef &ec_impl,
103 bufferlist &in,
104 const set<int> &want,
105 map<int, bufferlist> *out) {
106
107 uint64_t logical_size = in.length();
108
109 assert(logical_size % sinfo.get_stripe_width() == 0);
110 assert(out);
111 assert(out->empty());
112
113 if (logical_size == 0)
114 return 0;
115
116 for (uint64_t i = 0; i < logical_size; i += sinfo.get_stripe_width()) {
117 map<int, bufferlist> encoded;
118 bufferlist buf;
119 buf.substr_of(in, i, sinfo.get_stripe_width());
120 int r = ec_impl->encode(want, buf, &encoded);
121 assert(r == 0);
122 for (map<int, bufferlist>::iterator i = encoded.begin();
123 i != encoded.end();
124 ++i) {
125 assert(i->second.length() == sinfo.get_chunk_size());
126 (*out)[i->first].claim_append(i->second);
127 }
128 }
129
130 for (map<int, bufferlist>::iterator i = out->begin();
131 i != out->end();
132 ++i) {
133 assert(i->second.length() % sinfo.get_chunk_size() == 0);
134 assert(
135 sinfo.aligned_chunk_offset_to_logical_offset(i->second.length()) ==
136 logical_size);
137 }
138 return 0;
139}
140
141void ECUtil::HashInfo::append(uint64_t old_size,
142 map<int, bufferlist> &to_append) {
143 assert(old_size == total_chunk_size);
144 uint64_t size_to_append = to_append.begin()->second.length();
145 if (has_chunk_hash()) {
146 assert(to_append.size() == cumulative_shard_hashes.size());
147 for (map<int, bufferlist>::iterator i = to_append.begin();
148 i != to_append.end();
149 ++i) {
150 assert(size_to_append == i->second.length());
151 assert((unsigned)i->first < cumulative_shard_hashes.size());
152 uint32_t new_hash = i->second.crc32c(cumulative_shard_hashes[i->first]);
153 cumulative_shard_hashes[i->first] = new_hash;
154 }
155 }
156 total_chunk_size += size_to_append;
157}
158
159void ECUtil::HashInfo::encode(bufferlist &bl) const
160{
161 ENCODE_START(1, 1, bl);
162 ::encode(total_chunk_size, bl);
163 ::encode(cumulative_shard_hashes, bl);
164 ENCODE_FINISH(bl);
165}
166
167void ECUtil::HashInfo::decode(bufferlist::iterator &bl)
168{
169 DECODE_START(1, bl);
170 ::decode(total_chunk_size, bl);
171 ::decode(cumulative_shard_hashes, bl);
172 projected_total_chunk_size = total_chunk_size;
173 DECODE_FINISH(bl);
174}
175
176void ECUtil::HashInfo::dump(Formatter *f) const
177{
178 f->dump_unsigned("total_chunk_size", total_chunk_size);
179 f->open_object_section("cumulative_shard_hashes");
180 for (unsigned i = 0; i != cumulative_shard_hashes.size(); ++i) {
181 f->open_object_section("hash");
182 f->dump_unsigned("shard", i);
183 f->dump_unsigned("hash", cumulative_shard_hashes[i]);
184 f->close_section();
185 }
186 f->close_section();
187}
188
189void ECUtil::HashInfo::generate_test_instances(list<HashInfo*>& o)
190{
191 o.push_back(new HashInfo(3));
192 {
193 bufferlist bl;
194 bl.append_zero(20);
195 map<int, bufferlist> buffers;
196 buffers[0] = bl;
197 buffers[1] = bl;
198 buffers[2] = bl;
199 o.back()->append(0, buffers);
200 o.back()->append(20, buffers);
201 }
202 o.push_back(new HashInfo(4));
203}
204
205const string HINFO_KEY = "hinfo_key";
206
207bool ECUtil::is_hinfo_key_string(const string &key)
208{
209 return key == HINFO_KEY;
210}
211
212const string &ECUtil::get_hinfo_key()
213{
214 return HINFO_KEY;
215}