diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /src/crimson/osd/object_context_loader.cc | |
parent | Initial commit. (diff) | |
download | ceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/crimson/osd/object_context_loader.cc')
-rw-r--r-- | src/crimson/osd/object_context_loader.cc | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/src/crimson/osd/object_context_loader.cc b/src/crimson/osd/object_context_loader.cc new file mode 100644 index 000000000..0a4d74c0d --- /dev/null +++ b/src/crimson/osd/object_context_loader.cc @@ -0,0 +1,232 @@ +#include "crimson/osd/object_context_loader.h" +#include "osd/osd_types_fmt.h" + +SET_SUBSYS(osd); + +namespace crimson::osd { + +using crimson::common::local_conf; + + template<RWState::State State> + ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_head_obc(ObjectContextRef obc, + bool existed, + with_obc_func_t&& func) + { + LOG_PREFIX(ObjectContextLoader::with_head_obc); + DEBUGDPP("object {}", dpp, obc->get_oid()); + assert(obc->is_head()); + obc->append_to(obc_set_accessing); + return obc->with_lock<State, IOInterruptCondition>( + [existed=existed, obc=obc, func=std::move(func), this] { + return get_or_load_obc<State>(obc, existed) + .safe_then_interruptible( + [func = std::move(func)](auto obc) { + return std::move(func)(std::move(obc)); + }); + }).finally([FNAME, this, obc=std::move(obc)] { + DEBUGDPP("released object {}", dpp, obc->get_oid()); + obc->remove_from(obc_set_accessing); + }); + } + + template<RWState::State State> + ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_clone_obc(hobject_t oid, + with_obc_func_t&& func) + { + LOG_PREFIX(ObjectContextLoader::with_clone_obc); + assert(!oid.is_head()); + return with_obc<RWState::RWREAD>( + oid.get_head(), + [FNAME, oid, func=std::move(func), this](auto head) mutable + -> load_obc_iertr::future<> { + if (!head->obs.exists) { + ERRORDPP("head doesn't exist for object {}", dpp, head->obs.oi.soid); + return load_obc_iertr::future<>{ + crimson::ct_error::enoent::make() + }; + } + return this->with_clone_obc_only<State>(std::move(head), + oid, + std::move(func)); + }); + } + + template<RWState::State State> + ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_clone_obc_only(ObjectContextRef head, + hobject_t oid, + with_obc_func_t&& func) + { + LOG_PREFIX(ObjectContextLoader::with_clone_obc_only); + auto coid = resolve_oid(head->get_head_ss(), oid); + if (!coid) { + ERRORDPP("clone {} not found", dpp, oid); + return load_obc_iertr::future<>{ + crimson::ct_error::enoent::make() + }; + } + auto [clone, existed] = obc_registry.get_cached_obc(*coid); + return clone->template with_lock<State, IOInterruptCondition>( + [existed=existed, clone=std::move(clone), + func=std::move(func), head=std::move(head), this]() + -> load_obc_iertr::future<> { + auto loaded = get_or_load_obc<State>(clone, existed); + return loaded.safe_then_interruptible( + [func = std::move(func)](auto clone) { + return std::move(func)(std::move(clone)); + }); + }); + } + + template<RWState::State State> + ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_clone_obc_direct( + hobject_t oid, + with_both_obc_func_t&& func) + { + LOG_PREFIX(ObjectContextLoader::with_clone_obc_direct); + assert(!oid.is_head()); + return with_obc<RWState::RWREAD>( + oid.get_head(), + [FNAME, oid, func=std::move(func), this](auto head) mutable + -> load_obc_iertr::future<> { + if (!head->obs.exists) { + ERRORDPP("head doesn't exist for object {}", dpp, head->obs.oi.soid); + return load_obc_iertr::future<>{ + crimson::ct_error::enoent::make() + }; + } +#ifndef NDEBUG + auto &ss = head->get_head_ss(); + auto cit = std::find( + std::begin(ss.clones), std::end(ss.clones), oid.snap); + assert(cit != std::end(ss.clones)); +#endif + auto [clone, existed] = obc_registry.get_cached_obc(oid); + return clone->template with_lock<State, IOInterruptCondition>( + [existed=existed, clone=std::move(clone), + func=std::move(func), head=std::move(head), this]() + -> load_obc_iertr::future<> { + auto loaded = get_or_load_obc<State>(clone, existed); + return loaded.safe_then_interruptible( + [func = std::move(func), head=std::move(head)](auto clone) { + return std::move(func)(std::move(head), std::move(clone)); + }); + }); + }); + } + + template<RWState::State State> + ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_obc(hobject_t oid, + with_obc_func_t&& func) + { + if (oid.is_head()) { + auto [obc, existed] = + obc_registry.get_cached_obc(std::move(oid)); + return with_head_obc<State>(std::move(obc), + existed, + std::move(func)); + } else { + return with_clone_obc<State>(oid, std::move(func)); + } + } + + ObjectContextLoader::load_obc_iertr::future<ObjectContextRef> + ObjectContextLoader::load_obc(ObjectContextRef obc) + { + LOG_PREFIX(ObjectContextLoader::load_obc); + return backend.load_metadata(obc->get_oid()) + .safe_then_interruptible( + [FNAME, this, obc=std::move(obc)](auto md) + -> load_obc_ertr::future<ObjectContextRef> { + const hobject_t& oid = md->os.oi.soid; + DEBUGDPP("loaded obs {} for {}", dpp, md->os.oi, oid); + if (oid.is_head()) { + if (!md->ssc) { + ERRORDPP("oid {} missing snapsetcontext", dpp, oid); + return crimson::ct_error::object_corrupted::make(); + } + obc->set_head_state(std::move(md->os), + std::move(md->ssc)); + } else { + obc->set_clone_state(std::move(md->os)); + } + DEBUGDPP("returning obc {} for {}", dpp, obc->obs.oi, obc->obs.oi.soid); + return load_obc_ertr::make_ready_future<ObjectContextRef>(obc); + }); + } + + template<RWState::State State> + ObjectContextLoader::load_obc_iertr::future<ObjectContextRef> + ObjectContextLoader::get_or_load_obc(ObjectContextRef obc, + bool existed) + { + LOG_PREFIX(ObjectContextLoader::get_or_load_obc); + auto loaded = + load_obc_iertr::make_ready_future<ObjectContextRef>(obc); + if (existed) { + DEBUGDPP("cache hit on {}", dpp, obc->get_oid()); + } else { + DEBUGDPP("cache miss on {}", dpp, obc->get_oid()); + loaded = + obc->template with_promoted_lock<State, IOInterruptCondition>( + [obc, this] { + return load_obc(obc); + }); + } + return loaded; + } + + ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::reload_obc(ObjectContext& obc) const + { + LOG_PREFIX(ObjectContextLoader::reload_obc); + assert(obc.is_head()); + return backend.load_metadata(obc.get_oid()) + .safe_then_interruptible<false>( + [FNAME, this, &obc](auto md)-> load_obc_ertr::future<> { + DEBUGDPP("reloaded obs {} for {}", dpp, md->os.oi, obc.get_oid()); + if (!md->ssc) { + ERRORDPP("oid {} missing snapsetcontext", dpp, obc.get_oid()); + return crimson::ct_error::object_corrupted::make(); + } + obc.set_head_state(std::move(md->os), std::move(md->ssc)); + return load_obc_ertr::now(); + }); + } + + void ObjectContextLoader::notify_on_change(bool is_primary) + { + LOG_PREFIX(ObjectContextLoader::notify_on_change); + DEBUGDPP("is_primary: {}", dpp, is_primary); + for (auto& obc : obc_set_accessing) { + DEBUGDPP("interrupting obc: {}", dpp, obc.get_oid()); + obc.interrupt(::crimson::common::actingset_changed(is_primary)); + } + } + + // explicitly instantiate the used instantiations + template ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_obc<RWState::RWNONE>(hobject_t, + with_obc_func_t&&); + + template ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_obc<RWState::RWREAD>(hobject_t, + with_obc_func_t&&); + + template ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_obc<RWState::RWWRITE>(hobject_t, + with_obc_func_t&&); + + template ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_obc<RWState::RWEXCL>(hobject_t, + with_obc_func_t&&); + + template ObjectContextLoader::load_obc_iertr::future<> + ObjectContextLoader::with_clone_obc_direct<RWState::RWWRITE>( + hobject_t, + with_both_obc_func_t&&); +} |