}
static bool should_partial_read(
+ const ECUtil::stripe_info_t& sinfo,
+ uint64_t off,
+ uint32_t len,
bool fast_read)
{
// Don't partial read if we are doing a fast_read
if (fast_read) {
return false;
}
- return true;
+ // Same stripe only
+ return sinfo.offset_length_is_same_stripe(off, len);
}
void ECBackend::objects_read_async(
extent_set es;
for (const auto& [read, ctx] : to_read) {
pair<uint64_t, uint64_t> tmp;
- if (!cct->_conf->osd_ec_partial_reads || !should_partial_read(fast_read)) {
+ if (!cct->_conf->osd_ec_partial_reads ||
+ !should_partial_read(sinfo, read.offset, read.size, fast_read)) {
tmp = sinfo.offset_len_to_stripe_bounds(make_pair(read.offset, read.size));
} else {
tmp = sinfo.offset_len_to_chunk_bounds(make_pair(read.offset, read.size));
goto out;
}
bufferlist trimmed;
+ ceph_assert(aligned.first <= read.offset);
auto off = read.offset - aligned.first;
- auto len =
- std::min(read.size, bl.length() - (read.offset - aligned.first));
+ auto len = std::min(read.size, bl.length() - off);
trimmed.substr_of(bl, off, len);
result.insert(
read.offset, trimmed.length(), std::move(trimmed));
const auto last_chunk_idx = (chunk_size - 1 + off + len) / chunk_size;
return {first_chunk_idx, last_chunk_idx};
}
+ bool offset_length_is_same_stripe(
+ uint64_t off, uint64_t len) const {
+ if (len == 0) {
+ return true;
+ }
+ assert(chunk_size > 0);
+ const auto first_stripe_idx = off / stripe_width;
+ const auto last_inc_stripe_idx = (off + len - 1) / stripe_width;
+ return first_stripe_idx == last_inc_stripe_idx;
+ }
};
int decode(
make_pair((uint64_t)0, 2*swidth));
}
+TEST(ECUtil, offset_length_is_same_stripe)
+{
+ const uint64_t swidth = 4096;
+ const uint64_t schunk = 1024;
+ const uint64_t ssize = 4;
+
+ ECUtil::stripe_info_t s(ssize, swidth);
+ ASSERT_EQ(s.get_stripe_width(), swidth);
+ ASSERT_EQ(s.get_chunk_size(), schunk);
+
+ // read nothing at the very beginning
+ // +---+---+---+---+
+ // | 0| | | |
+ // +---+---+---+---+
+ // | | | | |
+ // +---+---+---+---+
+ ASSERT_TRUE(s.offset_length_is_same_stripe(0, 0));
+
+ // read nothing at the stripe end
+ // +---+---+---+---+
+ // | | | | 0|
+ // +---+---+---+---+
+ // | | | | |
+ // +---+---+---+---+
+ ASSERT_TRUE(s.offset_length_is_same_stripe(swidth, 0));
+
+ // read single byte at the stripe end
+ // +---+---+---+---+
+ // | | | | ~1|
+ // +---+---+---+---+
+ // | | | | |
+ // +---+---+---+---+
+ ASSERT_TRUE(s.offset_length_is_same_stripe(swidth - 1, 1));
+
+ // read single stripe
+ // +---+---+---+---+
+ // | 1k| 1k| 1k| 1k|
+ // +---+---+---+---+
+ // | | | | |
+ // +---+---+---+---+
+ ASSERT_TRUE(s.offset_length_is_same_stripe(0, swidth));
+
+ // read single chunk
+ // +---+---+---+---+
+ // | 1k| | | |
+ // +---+---+---+---+
+ // | | | | |
+ // +---+---+---+---+
+ ASSERT_TRUE(s.offset_length_is_same_stripe(0, schunk));
+
+ // read single stripe except its first chunk
+ // +---+---+---+---+
+ // | | 1k| 1k| 1k|
+ // +---+---+---+---+
+ // | | | | |
+ // +---+---+---+---+
+ ASSERT_TRUE(s.offset_length_is_same_stripe(schunk, swidth - schunk));
+
+ // read two stripes
+ // +---+---+---+---+
+ // | 1k| 1k| 1k| 1k|
+ // +---+---+---+---+
+ // | 1k| 1k| 1k| 1k|
+ // +---+---+---+---+
+ ASSERT_FALSE(s.offset_length_is_same_stripe(0, 2*swidth));
+
+ // multistripe read: 1st stripe without 1st byte + 1st byte of 2nd stripe
+ // +-----+---+---+---+
+ // | 1k-1| 1k| 1k| 1k|
+ // +-----+---+---+---+
+ // | 1| | | |
+ // +-----+---+---+---+
+ ASSERT_FALSE(s.offset_length_is_same_stripe(1, swidth));
+}
+
+
TEST(ECCommon, get_min_want_to_read_shards)
{
const uint64_t swidth = 4096;