Skip to content

Commit 1798676

Browse files
authored
Merge pull request ceph#61804 from aainscow/erasure_code_chunks
osd: Modify erasure code plugins ready for new EC Reviewed-by: Radoslaw Zarzynski <[email protected]>
2 parents ea7c0b6 + 6b733e9 commit 1798676

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3459
-868
lines changed

src/erasure-code/ErasureCode.cc

Lines changed: 218 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,26 @@ int ErasureCode::sanity_check_k_m(int k, int m, ostream *ss)
111111
*ss << "m=" << m << " must be >= 1" << std::endl;
112112
return -EINVAL;
113113
}
114+
int max_k_plus_m = std::numeric_limits<decltype(shard_id_t::id)>::max();
115+
if (k+m > max_k_plus_m) {
116+
*ss << "(k+m)=" << (k+m) << " must be <= " << max_k_plus_m << std::endl;
117+
return -EINVAL;
118+
}
114119
return 0;
115120
}
116121

117-
int ErasureCode::chunk_index(unsigned int i) const
122+
shard_id_t ErasureCode::chunk_index(raw_shard_id_t i) const
118123
{
119-
return chunk_mapping.size() > i ? chunk_mapping[i] : i;
124+
return chunk_mapping.size() > uint64_t(i) ? chunk_mapping[static_cast<int>(i)] : shard_id_t(int8_t(i));
120125
}
121126

127+
[[deprecated]]
128+
unsigned int ErasureCode::chunk_index(unsigned int i) const
129+
{
130+
return static_cast<unsigned int>(chunk_mapping.size() > uint64_t(i) ? chunk_mapping[i] : shard_id_t(i));
131+
}
132+
133+
[[deprecated]]
122134
int ErasureCode::_minimum_to_decode(const set<int> &want_to_read,
123135
const set<int> &available_chunks,
124136
set<int> *minimum)
@@ -138,6 +150,26 @@ int ErasureCode::_minimum_to_decode(const set<int> &want_to_read,
138150
return 0;
139151
}
140152

153+
int ErasureCode::_minimum_to_decode(const shard_id_set &want_to_read,
154+
const shard_id_set &available_chunks,
155+
shard_id_set *minimum)
156+
{
157+
if (available_chunks.includes(want_to_read)) {
158+
*minimum = want_to_read;
159+
} else {
160+
unsigned int k = get_data_chunk_count();
161+
if (available_chunks.size() < (unsigned)k)
162+
return -EIO;
163+
shard_id_set::const_iterator i;
164+
unsigned j;
165+
for (i = available_chunks.begin(), j = 0; j < (unsigned)k; ++i, j++)
166+
minimum->insert(*i);
167+
}
168+
return 0;
169+
}
170+
171+
IGNORE_DEPRECATED
172+
[[deprecated]]
141173
int ErasureCode::minimum_to_decode(const set<int> &want_to_read,
142174
const set<int> &available_chunks,
143175
map<int, vector<pair<int, int>>> *minimum)
@@ -154,7 +186,28 @@ int ErasureCode::minimum_to_decode(const set<int> &want_to_read,
154186
}
155187
return 0;
156188
}
189+
END_IGNORE_DEPRECATED
190+
191+
int ErasureCode::minimum_to_decode(const shard_id_set &want_to_read,
192+
const shard_id_set &available_chunks,
193+
shard_id_set &minimum_set,
194+
shard_id_map<vector<pair<int, int>>> *minimum_sub_chunks)
195+
{
196+
int r = _minimum_to_decode(want_to_read, available_chunks, &minimum_set);
197+
if (minimum_sub_chunks == nullptr) return r;
198+
if (r != 0) {
199+
return r;
200+
}
201+
vector<pair<int, int>> default_subchunks;
202+
default_subchunks.push_back(make_pair(0, get_sub_chunk_count()));
203+
for (auto &&id : minimum_set) {
204+
minimum_sub_chunks->emplace(id, default_subchunks);
205+
}
206+
return 0;
207+
}
157208

209+
IGNORE_DEPRECATED
210+
[[deprecated]]
158211
int ErasureCode::minimum_to_decode_with_cost(const set<int> &want_to_read,
159212
const map<int, int> &available,
160213
set<int> *minimum)
@@ -166,7 +219,22 @@ int ErasureCode::minimum_to_decode_with_cost(const set<int> &want_to_read,
166219
available_chunks.insert(i->first);
167220
return _minimum_to_decode(want_to_read, available_chunks, minimum);
168221
}
222+
END_IGNORE_DEPRECATED
169223

224+
int ErasureCode::minimum_to_decode_with_cost(const shard_id_set &want_to_read,
225+
const shard_id_map<int> &available,
226+
shard_id_set *minimum)
227+
{
228+
shard_id_set available_chunks;
229+
for (shard_id_map<int>::const_iterator i = available.begin();
230+
i != available.end();
231+
++i)
232+
available_chunks.insert(i->first);
233+
return _minimum_to_decode(want_to_read, available_chunks, minimum);
234+
}
235+
236+
IGNORE_DEPRECATED
237+
[[deprecated]]
170238
int ErasureCode::encode_prepare(const bufferlist &raw,
171239
map<int, bufferlist> &encoded) const
172240
{
@@ -203,7 +271,47 @@ int ErasureCode::encode_prepare(const bufferlist &raw,
203271

204272
return 0;
205273
}
274+
END_IGNORE_DEPRECATED
275+
276+
int ErasureCode::encode_prepare(const bufferlist &raw,
277+
shard_id_map<bufferlist> &encoded) const
278+
{
279+
unsigned int k = get_data_chunk_count();
280+
unsigned int m = get_chunk_count() - k;
281+
unsigned blocksize = get_chunk_size(raw.length());
282+
unsigned padded_chunks = k - raw.length() / blocksize;
283+
bufferlist prepared = raw;
284+
285+
for (raw_shard_id_t i; i < k - padded_chunks; ++i) {
286+
bufferlist &chunk = encoded[chunk_index(i)];
287+
chunk.substr_of(prepared, (int)i * blocksize, blocksize);
288+
chunk.rebuild_aligned_size_and_memory(blocksize, SIMD_ALIGN);
289+
ceph_assert(chunk.is_contiguous());
290+
}
291+
if (padded_chunks) {
292+
unsigned remainder = raw.length() - (k - padded_chunks) * blocksize;
293+
bufferptr buf(buffer::create_aligned(blocksize, SIMD_ALIGN));
294+
295+
raw.begin((k - padded_chunks) * blocksize).copy(remainder, buf.c_str());
296+
buf.zero(remainder, blocksize - remainder);
297+
encoded[chunk_index(raw_shard_id_t(k - padded_chunks))].push_back(std::move(buf));
298+
299+
for (raw_shard_id_t i(k - padded_chunks + 1); i < k; ++i) {
300+
bufferptr buf(buffer::create_aligned(blocksize, SIMD_ALIGN));
301+
buf.zero();
302+
encoded[chunk_index(i)].push_back(std::move(buf));
303+
}
304+
}
305+
for (raw_shard_id_t i(k); i < k + m; ++i) {
306+
bufferlist &chunk = encoded[chunk_index(i)];
307+
chunk.push_back(buffer::create_aligned(blocksize, SIMD_ALIGN));
308+
}
309+
310+
return 0;
311+
}
206312

313+
IGNORE_DEPRECATED
314+
[[deprecated]]
207315
int ErasureCode::encode(const set<int> &want_to_encode,
208316
const bufferlist &in,
209317
map<int, bufferlist> *encoded)
@@ -221,7 +329,46 @@ int ErasureCode::encode(const set<int> &want_to_encode,
221329
}
222330
return 0;
223331
}
332+
END_IGNORE_DEPRECATED
333+
334+
int ErasureCode::encode(const shard_id_set &want_to_encode,
335+
const bufferlist &in,
336+
shard_id_map<bufferlist> *encoded)
337+
{
338+
unsigned int k = get_data_chunk_count();
339+
unsigned int m = get_chunk_count() - k;
340+
341+
if (!encoded || !encoded->empty()){
342+
return -EINVAL;
343+
}
344+
int err = encode_prepare(in, *encoded);
345+
if (err)
346+
return err;
347+
348+
shard_id_map<bufferptr> in_shards(get_chunk_count());
349+
shard_id_map<bufferptr> out_shards(get_chunk_count());
350+
351+
for (raw_shard_id_t raw_shard; raw_shard < get_chunk_count(); ++raw_shard) {
352+
shard_id_t shard = chunk_index(raw_shard);
353+
if (!encoded->contains(shard)) continue;
354+
355+
auto bp = encoded->at(shard).begin().get_current_ptr();
356+
ceph_assert(bp.length() == encoded->at(shard).length());
357+
358+
if (raw_shard < k) in_shards[shard] = bp;
359+
else out_shards[shard] = bp;
360+
}
361+
362+
encode_chunks(in_shards, out_shards);
363+
for (shard_id_t i; i < k + m; ++i) {
364+
if (want_to_encode.count(i) == 0)
365+
encoded->erase(i);}
366+
367+
return 0;
368+
}
224369

370+
IGNORE_DEPRECATED
371+
[[deprecated]]
225372
int ErasureCode::_decode(const set<int> &want_to_read,
226373
const map<int, bufferlist> &chunks,
227374
map<int, bufferlist> *decoded)
@@ -259,21 +406,84 @@ int ErasureCode::_decode(const set<int> &want_to_read,
259406
}
260407
return decode_chunks(want_to_read, chunks, decoded);
261408
}
409+
END_IGNORE_DEPRECATED
410+
411+
int ErasureCode::_decode(const shard_id_set &want_to_read,
412+
const shard_id_map<bufferlist> &chunks,
413+
shard_id_map<bufferlist> *decoded)
414+
{
415+
shard_id_set have;
416+
417+
if (!decoded || !decoded->empty()){
418+
return -EINVAL;
419+
}
420+
if (!want_to_read.empty() && chunks.empty()) {
421+
return -1;
422+
}
423+
424+
for (auto &&[shard, _] : chunks) {
425+
have.insert(shard);
426+
}
427+
if (have.includes(want_to_read)) {
428+
for (auto &&shard : want_to_read) {
429+
(*decoded)[shard] = chunks.at(shard);
430+
}
431+
return 0;
432+
}
433+
unsigned int k = get_data_chunk_count();
434+
unsigned int m = get_chunk_count() - k;
435+
unsigned blocksize = (*chunks.begin()).second.length();
436+
shard_id_set erasures;
437+
for (shard_id_t i; i < k + m; ++i) {
438+
if (!chunks.contains(i)) {
439+
bufferlist tmp;
440+
bufferptr ptr(buffer::create_aligned(blocksize, SIMD_ALIGN));
441+
tmp.push_back(ptr);
442+
tmp.claim_append((*decoded)[i]);
443+
(*decoded)[i].swap(tmp);
444+
erasures.insert(i);
445+
} else {
446+
(*decoded)[i] = chunks.find(i)->second;
447+
(*decoded)[i].rebuild_aligned(SIMD_ALIGN);
448+
}
449+
bufferlist &bl = (*decoded)[i];
450+
if (bl.length() != bl.begin().get_current_ptr().length()) {
451+
bl.rebuild();
452+
}
453+
}
454+
shard_id_map<bufferptr> in(get_chunk_count());
455+
shard_id_map<bufferptr> out(get_chunk_count());
456+
for (auto&& [shard, list] : *decoded) {
457+
auto bp = list.begin().get_current_ptr();
458+
ceph_assert(bp.length() == list.length());
459+
if (erasures.find(shard) == erasures.end()) in[shard] = bp;
460+
else out[shard] = bp;
461+
}
462+
return decode_chunks(want_to_read, in, out);
463+
}
262464

465+
[[deprecated]]
263466
int ErasureCode::decode(const set<int> &want_to_read,
264467
const map<int, bufferlist> &chunks,
265468
map<int, bufferlist> *decoded, int chunk_size)
266469
{
267470
return _decode(want_to_read, chunks, decoded);
268471
}
269472

473+
int ErasureCode::decode(const shard_id_set &want_to_read,
474+
const shard_id_map<bufferlist> &chunks,
475+
shard_id_map<bufferlist> *decoded, int chunk_size)
476+
{
477+
return _decode(want_to_read, chunks, decoded);
478+
}
479+
270480
int ErasureCode::parse(const ErasureCodeProfile &profile,
271481
ostream *ss)
272482
{
273483
return to_mapping(profile, ss);
274484
}
275485

276-
const vector<int> &ErasureCode::get_chunk_mapping() const {
486+
const vector<shard_id_t> &ErasureCode::get_chunk_mapping() const {
277487
return chunk_mapping;
278488
}
279489

@@ -286,7 +496,7 @@ int ErasureCode::to_mapping(const ErasureCodeProfile &profile,
286496
vector<int> coding_chunk_mapping;
287497
for(std::string::iterator it = mapping.begin(); it != mapping.end(); ++it) {
288498
if (*it == 'D')
289-
chunk_mapping.push_back(position);
499+
chunk_mapping.push_back(shard_id_t(position));
290500
else
291501
coding_chunk_mapping.push_back(position);
292502
position++;
@@ -348,6 +558,8 @@ int ErasureCode::to_string(const std::string &name,
348558
return 0;
349559
}
350560

561+
IGNORE_DEPRECATED
562+
[[deprecated]]
351563
int ErasureCode::decode_concat(const set<int>& want_to_read,
352564
const map<int, bufferlist> &chunks,
353565
bufferlist *decoded)
@@ -370,6 +582,7 @@ int ErasureCode::decode_concat(const set<int>& want_to_read,
370582
return r;
371583
}
372584

585+
[[deprecated]]
373586
int ErasureCode::decode_concat(const map<int, bufferlist> &chunks,
374587
bufferlist *decoded)
375588
{
@@ -379,4 +592,5 @@ int ErasureCode::decode_concat(const map<int, bufferlist> &chunks,
379592
}
380593
return decode_concat(want_to_read, chunks, decoded);
381594
}
595+
END_IGNORE_DEPRECATED
382596
}

0 commit comments

Comments
 (0)