: (m_depth == scrub_level_t::deep ? "deep-scrub"sv : "scrub"sv));
}
-uint64_t ScrubBackend::logical_to_ondisk_size(uint64_t logical_size) const
+uint64_t ScrubBackend::logical_to_ondisk_size(uint64_t logical_size,
+ int8_t shard_id) const
{
- return m_pg.logical_to_ondisk_size(logical_size);
+ return m_pg.logical_to_ondisk_size(logical_size, shard_id);
}
void ScrubBackend::update_repair_status(bool should_repair)
}
}
- if (test_error_cond(smap_obj.size != logical_to_ondisk_size(oi.size),
- shard_info,
+ uint64_t ondisk_size = logical_to_ondisk_size(oi.size, srd.shard.id);
+ if (test_error_cond(smap_obj.size != ondisk_size, shard_info,
&shard_info_wrapper::set_obj_size_info_mismatch)) {
errstream << sep(err) << "candidate size " << smap_obj.size << " info size "
- << logical_to_ondisk_size(oi.size) << " mismatch";
+ << ondisk_size << " mismatch";
}
std::optional<uint32_t> digest;
// ------------------------------------------------------------------------
// sizes:
-
- uint64_t oi_size = logical_to_ondisk_size(auth_oi.size);
+ // NOTE: This will be fixed as a later PR as part of the optimized EC work.
+ uint64_t oi_size = logical_to_ondisk_size(auth_oi.size, 0);
if (oi_size != candidate.size) {
fmt::format_to(std::back_inserter(out),
"{}size {} != size {} from auth oi {}",
}
if (oi) {
- if (logical_to_ondisk_size(oi->size) != p->second.size) {
+ // NOTE: Fix planned as part of the optimized EC work.
+ if (logical_to_ondisk_size(oi->size, 0) != p->second.size) {
clog.error() << m_mode_desc << " " << m_pg_id << " " << soid
<< " : on disk size (" << p->second.size
<< ") does not match object info size (" << oi->size
<< ") adjusted for ondisk to ("
- << logical_to_ondisk_size(oi->size) << ")";
+ << logical_to_ondisk_size(oi->size, 0) << ")";
soid_error.set_size_mismatch();
this_chunk->m_error_counts.shallow_errors++;
}
so_set_ss(obj, std::invoke(std::forward<F>(f), so_get_ss(obj)));
}
-void so_set_hinfo(
- ScrubMap::object &obj, const std::optional<ECUtil::HashInfo> &hinfo)
-{
- return so_set_attr_type<ECUtil::HashInfo>(obj, ECUtil::get_hinfo_key(), hinfo);
-}
-
-std::optional<ECUtil::HashInfo> so_get_hinfo(ScrubMap::object &obj)
-{
- return so_get_attr_type<ECUtil::HashInfo>(obj, ECUtil::get_hinfo_key());
-}
-
-template <typename F>
-void so_mut_hinfo(ScrubMap::object &obj, F &&f) {
- auto maybe_hinfo = so_get_hinfo(obj);
- auto new_maybe_hinfo = std::invoke(std::forward<F>(f), std::move(maybe_hinfo));
- so_set_hinfo(obj, new_maybe_hinfo);
-}
-
/**
* so_builder_t
*
return ret;
}
- static so_builder_t make_ec_head(std::string name) {
- auto ret = make_head(name);
- so_set_hinfo(ret.so, ECUtil::HashInfo{});
- return ret;
- }
-
- static so_builder_t make_ec_clone(
- std::string name,
- snapid_t cloneid = 4
- ) {
- auto ret = make_clone(name, cloneid);
- so_set_hinfo(ret.so, ECUtil::HashInfo{});
- return ret;
- }
-
- so_builder_t &set_size(
- size_t size,
- const std::optional<ECUtil::stripe_info_t> stripe_info = std::nullopt) {
- if (stripe_info) {
- so.size = stripe_info->logical_to_next_chunk_offset(size);
- } else {
- so.size = size;
- }
+ so_builder_t &set_size(size_t size) {
+ so.size = size;
so_mut_oi(so, [size](auto maybe_oi) {
if (maybe_oi) {
}
return maybe_oi;
});
- so_mut_hinfo(so, [size, &stripe_info](auto maybe_hinfo) {
- if (maybe_hinfo) {
- ceph_assert(stripe_info);
- maybe_hinfo->set_total_chunk_size_clear_hash(
- stripe_info->logical_to_next_chunk_offset(size));
- }
- return maybe_hinfo;
- });
return *this;
}
* a stripe_info.
*/
struct test_obj_t : so_builder_t {
- std::optional<ECUtil::stripe_info_t> stripe_info;
std::string desc;
hobject_t hoid;
test_obj_t(
so_builder_t _builder,
- std::optional<ECUtil::stripe_info_t> _stripe_info,
std::string _desc,
hobject_t _hoid) :
so_builder_t(std::move(_builder)),
- stripe_info(std::move(_stripe_info)),
desc(std::move(_desc)),
hoid(std::move(_hoid)) {
ceph_assert(!desc.empty());
static test_obj_t make(
const std::string &desc,
- std::optional<ECUtil::stripe_info_t> stripe_info,
so_builder_t builder) {
hobject_t hoid = so_get_oi(builder.so)->soid;
return test_obj_t{
std::move(builder),
- stripe_info,
desc,
std::move(hoid)};
}
static test_obj_t make_head(const std::string &desc, Args&&... args) {
return make(
desc,
- std::nullopt,
so_builder_t::make_head(std::forward<Args>(args)...));
}
static test_obj_t make_clone(const std::string &desc, Args&&... args) {
return make(
desc,
- std::nullopt,
so_builder_t::make_clone(std::forward<Args>(args)...));
}
- template <typename... Args>
- static test_obj_t make_ec_head(const std::string &desc, Args&&... args) {
- return make(
- desc,
- ECUtil::stripe_info_t{4, 2, 1<<20},
- so_builder_t::make_ec_head(std::forward<Args>(args)...));
- }
-
- template <typename... Args>
- static test_obj_t make_ec_clone(const std::string &desc, Args&&... args) {
- return make(
- desc,
- ECUtil::stripe_info_t{4, 2, 1<<20},
- so_builder_t::make_ec_clone(std::forward<Args>(args)...));
- }
-
- test_obj_t &set_size(
- size_t size) {
- so_builder_t::set_size(size, stripe_info);
+ test_obj_t &set_size(size_t size) {
+ so_builder_t::set_size(size);
return *this;
}
}
};
-struct MissingHinfo : SingleErrorTestCaseT<MissingHinfo> {
- constexpr static librados::err_t shard_error_sig{
- librados::err_t::HINFO_MISSING
- };
- constexpr static librados::obj_err_t object_error_sig{
- librados::obj_err_t::HINFO_INCONSISTENCY
- };
- constexpr static bool REQUIRES_EC = true;
-
- std::string_view get_description() const {
- return "MissingHinfo";
- };
- test_obj_t inject_error(test_obj_t obj) const {
- ceph_assert(obj.stripe_info);
- so_mut_hinfo(obj.so, [](auto) { return std::nullopt; });
- return obj;
- }
-};
-
-struct CorruptHinfo : SingleErrorTestCaseT<CorruptHinfo> {
- constexpr static librados::err_t shard_error_sig{
- librados::err_t::HINFO_CORRUPTED
- };
- constexpr static librados::obj_err_t object_error_sig{
- librados::obj_err_t::HINFO_INCONSISTENCY
- };
- constexpr static bool REQUIRES_EC = true;
-
- std::string_view get_description() const {
- return "CorruptHinfo";
- };
- test_obj_t inject_error(test_obj_t obj) const {
- ceph_assert(obj.stripe_info);
- so_set_attr_len(obj.so, ECUtil::get_hinfo_key(), 10);
- return obj;
- }
-};
-
struct DataDigestMismatch : SingleErrorTestCaseT<DataDigestMismatch> {
constexpr static librados::err_t shard_error_sig{
librados::err_t::DATA_DIGEST_MISMATCH_INFO
std::make_unique<CorruptOndiskSize>(),
std::make_unique<MissingSS>(),
std::make_unique<CorruptSS>(),
- std::make_unique<MissingHinfo>(),
- std::make_unique<CorruptHinfo>(),
std::make_unique<DataDigestMismatch>(),
std::make_unique<OmapDigestMismatch>(),
std::make_unique<ExtraAttribute>(),
const pg_shard_t replica(1, shard_id_t::NO_SHARD);
crimson::osd::scrub::chunk_validation_policy_t policy {
primary,
- obj.stripe_info,
TEST_MAX_OBJECT_SIZE,
std::string{TEST_INTERNAL_NAMESPACE},
TEST_OMAP_KEY_LIMIT,
::testing::Values(
test_obj_t::make_head("Small", "foo").set_size(64),
test_obj_t::make_clone("EmptyWithAttr", "foo2").add_attr("extra_attr", 64),
- test_obj_t::make_head("ReplicatedRBD", "foo2").set_size(4<<20),
- test_obj_t::make_ec_head("ECHead", "foo").set_size(4<<20),
- test_obj_t::make_ec_clone("LargeECClone", "foo").set_size(16<<20)
+ test_obj_t::make_head("ReplicatedRBD", "foo2").set_size(4<<20)
),
::testing::Bool(),
::testing::ValuesIn(
::testing::Values(
test_obj_t::make_head("Small", "foo").set_size(64),
test_obj_t::make_clone("EmptyWithAttr", "foo2").add_attr("extra_attr", 64),
- test_obj_t::make_head("ReplicatedRBD", "foo2").set_size(4<<20),
- test_obj_t::make_ec_head("ECHead", "foo").set_size(4<<20),
- test_obj_t::make_ec_clone("LargeECClone", "foo").set_size(16<<20)
+ test_obj_t::make_head("ReplicatedRBD", "foo2").set_size(4<<20)
),
::testing::Values(false), // replica only
::testing::ValuesIn(
}
);
-/* Some tests only make sense on ec objects. */
-INSTANTIATE_TEST_SUITE_P(
- SingleErrorOnly,
- TestSingleError,
- ::testing::Combine(
- ::testing::Values(
- test_obj_t::make_ec_head("ECHead", "foo").set_size(4<<20),
- test_obj_t::make_ec_clone("LargeECClone", "foo").set_size(16<<20)
- ),
- ::testing::Bool(),
- ::testing::ValuesIn(
- test_cases_begin<SingleErrorTestCase::restriction_t::EC_ONLY>(),
- test_cases_end<SingleErrorTestCase::restriction_t::EC_ONLY>())
- ),
- [](const auto &info) {
- return fmt::format("{}", info.param);
- }
-);
-
/* Some tests only make sense on head objects. */
INSTANTIATE_TEST_SUITE_P(
SingleErrorHEAD,
::testing::Combine(
::testing::Values(
test_obj_t::make_head("Small", "foo").set_size(64),
- test_obj_t::make_head("ReplicatedRBD", "foo2").set_size(4<<20),
- test_obj_t::make_ec_head("ECHead", "foo").set_size(4<<20)
+ test_obj_t::make_head("ReplicatedRBD", "foo2").set_size(4<<20)
),
::testing::Bool(),
::testing::ValuesIn(
const pg_shard_t primary(0, shard_id_t::NO_SHARD);
crimson::osd::scrub::chunk_validation_policy_t policy {
primary,
- std::nullopt,
TEST_MAX_OBJECT_SIZE,
std::string{TEST_INTERNAL_NAMESPACE},
TEST_OMAP_KEY_LIMIT,
const pg_shard_t primary(0, shard_id_t::NO_SHARD);
crimson::osd::scrub::chunk_validation_policy_t policy {
primary,
- std::nullopt,
TEST_MAX_OBJECT_SIZE,
std::string{TEST_INTERNAL_NAMESPACE},
TEST_OMAP_KEY_LIMIT,
const pg_shard_t primary(0, shard_id_t::NO_SHARD);
crimson::osd::scrub::chunk_validation_policy_t policy {
primary,
- std::nullopt,
TEST_MAX_OBJECT_SIZE,
std::string{TEST_INTERNAL_NAMESPACE},
TEST_OMAP_KEY_LIMIT,