]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/crimson/osd/object_context.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / crimson / osd / object_context.h
index be238851e6a92a4dc53b4145bafd94bfc5055701..d5165dc23e814b93a94d11875a8b418d6d5865f0 100644 (file)
@@ -43,14 +43,13 @@ public:
   Ref head; // Ref defined as part of ceph::common::intrusive_lru_base
   ObjectState obs;
   std::optional<SnapSet> 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<uint64_t, entity_name_t>;
   std::map<watch_key_t, seastar::shared_ptr<crimson::osd::Watch>> watchers;
 
-  ObjectContext(const hobject_t &hoid) : obs(hoid), loaded(false) {}
+  ObjectContext(hobject_t hoid) : obs(std::move(hoid)) {}
 
   const hobject_t &get_oid() const {
     return obs.oi.soid;
@@ -60,6 +59,14 @@ public:
     return get_oid().is_head();
   }
 
+  Ref get_head_obc() const {
+    return head;
+  }
+
+  hobject_t get_head_oid() const {
+    return get_oid().get_head();
+  }
+
   const SnapSet &get_ro_ss() const {
     if (is_head()) {
       ceph_assert(ss);
@@ -74,14 +81,12 @@ public:
     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
@@ -107,35 +112,91 @@ private:
     });
   }
 
+  boost::intrusive::list_member_hook<> list_hook;
+  uint64_t list_link_cnt = 0;
+
 public:
-  template<RWState::State Type, typename Func>
+
+  template <typename ListType>
+  void append_to(ListType& list) {
+    if (list_link_cnt++ == 0) {
+      list.push_back(*this);
+    }
+  }
+
+  template <typename ListType>
+  void remove_from(ListType&& list) {
+    assert(list_link_cnt > 0);
+    if (--list_link_cnt == 0) {
+      list.erase(std::decay_t<ListType>::s_iterator_to(*this));
+    }
+  }
+
+  using obc_accessing_option_t = boost::intrusive::member_hook<
+    ObjectContext,
+    boost::intrusive::list_member_hook<>,
+    &ObjectContext::list_hook>;
+
+  template<RWState::State Type, typename InterruptCond = void, typename Func>
   auto with_lock(Func&& func) {
-    switch (Type) {
-    case RWState::RWWRITE:
-      return _with_lock(lock.for_write(), std::forward<Func>(func));
-    case RWState::RWREAD:
-      return _with_lock(lock.for_read(), std::forward<Func>(func));
-    case RWState::RWEXCL:
-      return _with_lock(lock.for_excl(), std::forward<Func>(func));
-    case RWState::RWNONE:
-      return seastar::futurize_invoke(std::forward<Func>(func));
-    default:
-      assert(0 == "noop");
+    if constexpr (!std::is_void_v<InterruptCond>) {
+      auto wrapper = ::crimson::interruptible::interruptor<InterruptCond>::wrap_function(std::forward<Func>(func));
+      switch (Type) {
+      case RWState::RWWRITE:
+       return _with_lock(lock.for_write(), std::move(wrapper));
+      case RWState::RWREAD:
+       return _with_lock(lock.for_read(), std::move(wrapper));
+      case RWState::RWEXCL:
+       return _with_lock(lock.for_excl(), std::move(wrapper));
+      case RWState::RWNONE:
+       return seastar::futurize_invoke(std::move(wrapper));
+      default:
+       assert(0 == "noop");
+      }
+    } else {
+      switch (Type) {
+      case RWState::RWWRITE:
+       return _with_lock(lock.for_write(), std::forward<Func>(func));
+      case RWState::RWREAD:
+       return _with_lock(lock.for_read(), std::forward<Func>(func));
+      case RWState::RWEXCL:
+       return _with_lock(lock.for_excl(), std::forward<Func>(func));
+      case RWState::RWNONE:
+       return seastar::futurize_invoke(std::forward<Func>(func));
+      default:
+       assert(0 == "noop");
+      }
     }
   }
-  template<RWState::State Type, typename Func>
+  template<RWState::State Type, typename InterruptCond = void, typename Func>
   auto with_promoted_lock(Func&& func) {
-    switch (Type) {
-    case RWState::RWWRITE:
-      return _with_lock(lock.excl_from_write(), std::forward<Func>(func));
-    case RWState::RWREAD:
-      return _with_lock(lock.excl_from_read(), std::forward<Func>(func));
-    case RWState::RWEXCL:
-      return _with_lock(lock.excl_from_excl(), std::forward<Func>(func));
-    case RWState::RWNONE:
-      return _with_lock(lock.for_excl(), std::forward<Func>(func));
-     default:
-      assert(0 == "noop");
+    if constexpr (!std::is_void_v<InterruptCond>) {
+      auto wrapper = ::crimson::interruptible::interruptor<InterruptCond>::wrap_function(std::forward<Func>(func));
+      switch (Type) {
+      case RWState::RWWRITE:
+       return _with_lock(lock.excl_from_write(), std::move(wrapper));
+      case RWState::RWREAD:
+       return _with_lock(lock.excl_from_read(), std::move(wrapper));
+      case RWState::RWEXCL:
+       return _with_lock(lock.excl_from_excl(), std::move(wrapper));
+      case RWState::RWNONE:
+       return _with_lock(lock.for_excl(), std::move(wrapper));
+       default:
+       assert(0 == "noop");
+      }
+    } else {
+      switch (Type) {
+      case RWState::RWWRITE:
+       return _with_lock(lock.excl_from_write(), std::forward<Func>(func));
+      case RWState::RWREAD:
+       return _with_lock(lock.excl_from_read(), std::forward<Func>(func));
+      case RWState::RWEXCL:
+       return _with_lock(lock.excl_from_excl(), std::forward<Func>(func));
+      case RWState::RWNONE:
+       return _with_lock(lock.for_excl(), std::forward<Func>(func));
+       default:
+       assert(0 == "noop");
+      }
     }
   }
 
@@ -173,6 +234,7 @@ class ObjectContextRegistry : public md_config_obs_t  {
 
 public:
   ObjectContextRegistry(crimson::common::ConfigProxy &conf);
+  ~ObjectContextRegistry();
 
   std::pair<ObjectContextRef, bool> get_cached_obc(const hobject_t &hoid) {
     return obc_lru.get_or_create(hoid);