Skip to content

Commit beb4d22

Browse files
committed
osd: fix partial reading during multi-region EC reads
Fixes: https://tracker.ceph.com/issues/67087 Signed-off-by: Radoslaw Zarzynski <[email protected]>
1 parent 51fd35d commit beb4d22

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

src/osd/ECCommon.cc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -327,15 +327,14 @@ void ECCommon::ReadPipeline::get_min_want_to_read_shards(
327327
{
328328
const auto [left_chunk_index, right_chunk_index] =
329329
sinfo.offset_length_to_data_chunk_indices(offset, length);
330-
for(uint64_t i = left_chunk_index; i < right_chunk_index; i++) {
331-
auto raw_chunk = i % sinfo.get_data_chunk_count();
330+
const auto distance =
331+
std::min(right_chunk_index - left_chunk_index,
332+
sinfo.get_data_chunk_count());
333+
for(uint64_t i = 0; i < distance; i++) {
334+
auto raw_chunk = (left_chunk_index + i) % sinfo.get_data_chunk_count();
332335
auto chunk = chunk_mapping.size() > raw_chunk ?
333336
chunk_mapping[raw_chunk] : static_cast<int>(raw_chunk);
334-
if (auto [_, inserted] = want_to_read->insert(chunk); !inserted) {
335-
// aready processed all chunks
336-
ceph_assert(want_to_read->size() == sinfo.get_data_chunk_count());
337-
break;
338-
}
337+
want_to_read->insert(chunk);
339338
}
340339
}
341340

src/test/osd/TestECBackend.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,28 @@ TEST(ECCommon, get_min_want_to_read_shards)
230230
ASSERT_TRUE(want_to_read == (std::set<int>{0, 1, 2, 3}));
231231
}
232232
}
233+
234+
TEST(ECCommon, get_min_want_to_read_shards_bug67087)
235+
{
236+
const uint64_t swidth = 4096;
237+
const uint64_t ssize = 4;
238+
239+
ECUtil::stripe_info_t s(ssize, swidth);
240+
ASSERT_EQ(s.get_stripe_width(), swidth);
241+
ASSERT_EQ(s.get_chunk_size(), 1024);
242+
243+
const std::vector<int> chunk_mapping = {}; // no remapping
244+
245+
std::set<int> want_to_read;
246+
247+
// multitple calls with the same want_to_read can happen during
248+
// multi-region reads.
249+
{
250+
ECCommon::ReadPipeline::get_min_want_to_read_shards(
251+
512, 512, s, chunk_mapping, &want_to_read);
252+
ASSERT_EQ(want_to_read, std::set<int>{0});
253+
ECCommon::ReadPipeline::get_min_want_to_read_shards(
254+
512+16*1024, 512, s, chunk_mapping, &want_to_read);
255+
ASSERT_EQ(want_to_read, std::set<int>{0});
256+
}
257+
}

0 commit comments

Comments
 (0)