summaryrefslogtreecommitdiffstats
path: root/src/crimson/osd/object_context_loader.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/crimson/osd/object_context_loader.cc
parentInitial commit. (diff)
downloadceph-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.cc232
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&&);
+}