From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/crimson/osd/object_context.h | 189 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/crimson/osd/object_context.h (limited to 'src/crimson/osd/object_context.h') diff --git a/src/crimson/osd/object_context.h b/src/crimson/osd/object_context.h new file mode 100644 index 000000000..be238851e --- /dev/null +++ b/src/crimson/osd/object_context.h @@ -0,0 +1,189 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include +#include +#include +#include +#include + +#include "common/intrusive_lru.h" +#include "osd/object_state.h" +#include "crimson/common/exception.h" +#include "crimson/common/tri_mutex.h" +#include "crimson/osd/osd_operation.h" + +namespace ceph { + class Formatter; +} + +namespace crimson::common { + class ConfigProxy; +} + +namespace crimson::osd { + +class Watch; + +template +struct obc_to_hoid { + using type = hobject_t; + const type &operator()(const OBC &obc) { + return obc.obs.oi.soid; + } +}; + +class ObjectContext : public ceph::common::intrusive_lru_base< + ceph::common::intrusive_lru_config< + hobject_t, ObjectContext, obc_to_hoid>> +{ +public: + Ref head; // Ref defined as part of ceph::common::intrusive_lru_base + ObjectState obs; + std::optional ss; + bool loaded : 1; + // the watch / notify machinery rather stays away from the hot and + // frequented paths. std::map is used mostly because of developer's + // convenience. + using watch_key_t = std::pair; + std::map> watchers; + + ObjectContext(const hobject_t &hoid) : obs(hoid), loaded(false) {} + + const hobject_t &get_oid() const { + return obs.oi.soid; + } + + bool is_head() const { + return get_oid().is_head(); + } + + const SnapSet &get_ro_ss() const { + if (is_head()) { + ceph_assert(ss); + return *ss; + } else { + ceph_assert(head); + return head->get_ro_ss(); + } + } + + void set_head_state(ObjectState &&_obs, SnapSet &&_ss) { + ceph_assert(is_head()); + obs = std::move(_obs); + ss = std::move(_ss); + loaded = true; + } + + void set_clone_state(ObjectState &&_obs, Ref &&_head) { + ceph_assert(!is_head()); + obs = std::move(_obs); + head = _head; + loaded = true; + } + + /// pass the provided exception to any waiting consumers of this ObjectContext + template + void interrupt(Exception ex) { + lock.abort(std::move(ex)); + if (recovery_read_marker) { + drop_recovery_read(); + } + } + +private: + tri_mutex lock; + bool recovery_read_marker = false; + + template + auto _with_lock(Lock&& lock, Func&& func) { + Ref obc = this; + return lock.lock().then([&lock, func = std::forward(func), obc]() mutable { + return seastar::futurize_invoke(func).finally([&lock, obc] { + lock.unlock(); + }); + }); + } + +public: + template + auto with_lock(Func&& func) { + switch (Type) { + case RWState::RWWRITE: + return _with_lock(lock.for_write(), std::forward(func)); + case RWState::RWREAD: + return _with_lock(lock.for_read(), std::forward(func)); + case RWState::RWEXCL: + return _with_lock(lock.for_excl(), std::forward(func)); + case RWState::RWNONE: + return seastar::futurize_invoke(std::forward(func)); + default: + assert(0 == "noop"); + } + } + template + auto with_promoted_lock(Func&& func) { + switch (Type) { + case RWState::RWWRITE: + return _with_lock(lock.excl_from_write(), std::forward(func)); + case RWState::RWREAD: + return _with_lock(lock.excl_from_read(), std::forward(func)); + case RWState::RWEXCL: + return _with_lock(lock.excl_from_excl(), std::forward(func)); + case RWState::RWNONE: + return _with_lock(lock.for_excl(), std::forward(func)); + default: + assert(0 == "noop"); + } + } + + bool empty() const { + return !lock.is_acquired(); + } + bool is_request_pending() const { + return lock.is_acquired(); + } + + bool get_recovery_read() { + if (lock.try_lock_for_read()) { + recovery_read_marker = true; + return true; + } else { + return false; + } + } + void wait_recovery_read() { + assert(lock.get_readers() > 0); + recovery_read_marker = true; + } + void drop_recovery_read() { + assert(recovery_read_marker); + recovery_read_marker = false; + } + bool maybe_get_excl() { + return lock.try_lock_for_excl(); + } +}; +using ObjectContextRef = ObjectContext::Ref; + +class ObjectContextRegistry : public md_config_obs_t { + ObjectContext::lru_t obc_lru; + +public: + ObjectContextRegistry(crimson::common::ConfigProxy &conf); + + std::pair get_cached_obc(const hobject_t &hoid) { + return obc_lru.get_or_create(hoid); + } + ObjectContextRef maybe_get_cached_obc(const hobject_t &hoid) { + return obc_lru.get(hoid); + } + + const char** get_tracked_conf_keys() const final; + void handle_conf_change(const crimson::common::ConfigProxy& conf, + const std::set &changed) final; +}; + +} // namespace crimson::osd -- cgit v1.2.3