]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/cached_extent: record transaction id in pending CachedExtents
authorXuehan Xu <xxhdx1985126@gmail.com>
Tue, 13 Sep 2022 07:50:35 +0000 (15:50 +0800)
committerMatan Breizman <mbreizma@redhat.com>
Tue, 23 May 2023 13:24:44 +0000 (13:24 +0000)
Signed-off-by: Xuehan Xu <xxhdx1985126@gmail.com>
(cherry picked from commit 8240be8f324b244061b17bb2c1676b192a12dca2)

src/crimson/os/seastore/cache.cc
src/crimson/os/seastore/cache.h
src/crimson/os/seastore/cached_extent.h
src/crimson/os/seastore/logging.h
src/crimson/os/seastore/seastore_types.h
src/crimson/os/seastore/transaction.h
src/crimson/os/seastore/transaction_manager.h

index 86c3730fd8b4d575cfd56dbb0bced46fe868048e..65c0f8ef5fe40f3d9d96106db44c59583e9d78f7 100644 (file)
@@ -98,7 +98,8 @@ Cache::retire_extent_ret Cache::retire_extent_addr(
     ext->init(CachedExtent::extent_state_t::CLEAN,
               addr,
               PLACEMENT_HINT_NULL,
-              NULL_GENERATION);
+              NULL_GENERATION,
+             TRANS_ID_NULL);
     DEBUGT("retire {}~{} as placeholder, add extent -- {}",
            t, addr, length, *ext);
     const auto t_src = t.get_src();
@@ -1012,6 +1013,7 @@ CachedExtentRef Cache::duplicate_for_write(
   }
 
   auto ret = i->duplicate_for_write();
+  ret->pending_for_transaction = t.get_trans_id();
   ret->prior_instance = i;
   // duplicate_for_write won't occur after ool write finished
   assert(!i->prior_poffset);
@@ -1448,6 +1450,7 @@ void Cache::complete_commit(
       i->set_paddr(final_block_start.add_relative(i->get_paddr()));
     }
     i->last_committed_crc = i->get_crc32c();
+    i->pending_for_transaction = TRANS_ID_NULL;
     i->on_initial_write();
 
     i->state = CachedExtent::extent_state_t::CLEAN;
@@ -1489,6 +1492,7 @@ void Cache::complete_commit(
     assert(i->is_exist_mutation_pending() ||
           i->prior_instance);
     i->on_delta_write(final_block_start);
+    i->pending_for_transaction = TRANS_ID_NULL;
     i->prior_instance = CachedExtentRef();
     i->state = CachedExtent::extent_state_t::DIRTY;
     assert(i->version > 0);
@@ -1593,7 +1597,8 @@ void Cache::init()
   root->init(CachedExtent::extent_state_t::CLEAN,
              P_ADDR_ROOT,
              PLACEMENT_HINT_NULL,
-             NULL_GENERATION);
+             NULL_GENERATION,
+            TRANS_ID_NULL);
   INFO("init root -- {}", *root);
   extents.insert(*root);
 }
index 253836276675d406ac0ad866e48ebc66dc15b75a..3b73594157f8b88f48dd31c5587b3f35d40b1690 100644 (file)
@@ -205,7 +205,8 @@ public:
       last_commit,
       [this](Transaction& t) {
         return on_transaction_destruct(t);
-      }
+      },
+      ++next_id
     );
     SUBDEBUGT(seastore_t, "created name={}, source={}, is_weak={}",
              *ret, name, src, is_weak);
@@ -284,7 +285,8 @@ public:
       ret->init(CachedExtent::extent_state_t::CLEAN_PENDING,
                 offset,
                 PLACEMENT_HINT_NULL,
-                NULL_GENERATION);
+                NULL_GENERATION,
+               TRANS_ID_NULL);
       SUBDEBUG(seastore_cache,
           "{} {}~{} is absent, add extent and reading ... -- {}",
           T::TYPE, offset, length, *ret);
@@ -303,7 +305,8 @@ public:
       ret->init(CachedExtent::extent_state_t::CLEAN_PENDING,
                 offset,
                 PLACEMENT_HINT_NULL,
-                NULL_GENERATION);
+                NULL_GENERATION,
+               TRANS_ID_NULL);
       SUBDEBUG(seastore_cache,
           "{} {}~{} is absent(placeholder), reading ... -- {}",
           T::TYPE, offset, length, *ret);
@@ -648,7 +651,8 @@ public:
     ret->init(CachedExtent::extent_state_t::INITIAL_WRITE_PENDING,
               result.paddr,
               hint,
-              result.gen);
+              result.gen,
+             t.get_trans_id());
     t.add_fresh_extent(ret);
     SUBDEBUGT(seastore_cache,
               "allocated {} {}B extent at {}, hint={}, gen={} -- {}",
@@ -990,6 +994,8 @@ private:
   // FIXME: This is specific to the segmented implementation
   std::vector<SegmentProvider*> segment_providers_by_device_id;
 
+  transaction_id_t next_id = 0;
+
   /**
    * dirty
    *
index 5ccafc5fa1961d17e4ad44ca2e44963ddd8c880b..7f76c26145302dfd0bdf3508d3dfe6b1db194862 100644 (file)
@@ -76,9 +76,55 @@ using read_set_t = std::set<
   read_set_item_t<T>,
   typename read_set_item_t<T>::cmp_t>;
 
+struct trans_spec_view_t {
+  // if the extent is pending, contains the id of the owning transaction;
+  // TRANS_ID_NULL otherwise
+  transaction_id_t pending_for_transaction = TRANS_ID_NULL;
+
+  struct cmp_t {
+    bool operator()(
+      const trans_spec_view_t &lhs,
+      const trans_spec_view_t &rhs) const
+    {
+      return lhs.pending_for_transaction < rhs.pending_for_transaction;
+    }
+    bool operator()(
+      const transaction_id_t &lhs,
+      const trans_spec_view_t &rhs) const
+    {
+      return lhs < rhs.pending_for_transaction;
+    }
+    bool operator()(
+      const trans_spec_view_t &lhs,
+      const transaction_id_t &rhs) const
+    {
+      return lhs.pending_for_transaction < rhs;
+    }
+  };
+
+  using trans_view_hook_t =
+    boost::intrusive::set_member_hook<
+      boost::intrusive::link_mode<
+        boost::intrusive::auto_unlink>>;
+  trans_view_hook_t trans_view_hook;
+
+  using trans_view_member_options =
+    boost::intrusive::member_hook<
+      trans_spec_view_t,
+      trans_view_hook_t,
+      &trans_spec_view_t::trans_view_hook>;
+  using trans_view_set_t = boost::intrusive::set<
+    trans_spec_view_t,
+    trans_view_member_options,
+    boost::intrusive::constant_time_size<false>,
+    boost::intrusive::compare<cmp_t>>;
+};
+
 class ExtentIndex;
-class CachedExtent : public boost::intrusive_ref_counter<
-  CachedExtent, boost::thread_unsafe_counter> {
+class CachedExtent
+  : public boost::intrusive_ref_counter<
+      CachedExtent, boost::thread_unsafe_counter>,
+    public trans_spec_view_t {
   enum class extent_state_t : uint8_t {
     INITIAL_WRITE_PENDING, // In Transaction::write_set and fresh_block_list
     MUTATION_PENDING,      // In Transaction::write_set and mutated_block_list
@@ -117,12 +163,14 @@ public:
   void init(extent_state_t _state,
             paddr_t paddr,
             placement_hint_t hint,
-            rewrite_gen_t gen) {
+            rewrite_gen_t gen,
+           transaction_id_t trans_id) {
     assert(gen == NULL_GENERATION || is_rewrite_generation(gen));
     state = _state;
     set_paddr(paddr);
     user_hint = hint;
     rewrite_generation = gen;
+    pending_for_transaction = trans_id;
   }
 
   void set_modify_time(sea_time_point t) {
index ec9b7df5ed181119b8ef4d92e55e30094027c8f3..3f12ee72cfed7f100857039cde0923f9ef43833b 100644 (file)
@@ -8,9 +8,11 @@
 #include "crimson/common/log.h"
 
 #define LOGT(level_, MSG, t, ...) \
-  LOCAL_LOGGER.log(level_, "{} {}: " MSG, (void*)&t, FNAME , ##__VA_ARGS__)
+  LOCAL_LOGGER.log(level_, "{} trans.{} {}: " MSG, (void*)&t, \
+    (t).get_trans_id(), FNAME , ##__VA_ARGS__)
 #define SUBLOGT(subname_, level_, MSG, t, ...) \
-  LOGGER(subname_).log(level_, "{} {}: " MSG, (void*)&t, FNAME , ##__VA_ARGS__)
+  LOGGER(subname_).log(level_, "{} trans.{} {}: " MSG, (void*)&t, \
+    (t).get_trans_id(), FNAME , ##__VA_ARGS__)
 
 #define TRACET(...) LOGT(seastar::log_level::trace, __VA_ARGS__)
 #define SUBTRACET(subname_, ...) SUBLOGT(subname_, seastar::log_level::trace, __VA_ARGS__)
index 7ec1215a06f5aa5dcb2b2bab5034ba439bc8a272..2894eb1704db3d6f71d01e51705730cdcce3a746 100644 (file)
@@ -24,6 +24,9 @@ namespace crimson::os::seastore {
 /* using a special xattr key "omap_header" to store omap header */
   const std::string OMAP_HEADER_XATTR_KEY = "omap_header";
 
+using transaction_id_t = uint64_t;
+constexpr transaction_id_t TRANS_ID_NULL = 0;
+
 /*
  * Note: NULL value is usually the default and max value.
  */
index 8899e105cefc529c61ad20fceab712a0d26ff809..e7eef11427a81c9c62cba5e3285c3628458e816f 100644 (file)
@@ -337,11 +337,13 @@ public:
     bool weak,
     src_t src,
     journal_seq_t initiated_after,
-    on_destruct_func_t&& f
+    on_destruct_func_t&& f,
+    transaction_id_t trans_id
   ) : weak(weak),
       handle(std::move(handle)),
       on_destruct(std::move(f)),
-      src(src)
+      src(src),
+      trans_id(trans_id)
   {}
 
   void invalidate_clear_write_set() {
@@ -468,6 +470,10 @@ public:
     return existing_block_stats;
   }
 
+  transaction_id_t get_trans_id() const {
+    return trans_id;
+  }
+
 private:
   friend class Cache;
   friend Ref make_test_transaction();
@@ -553,17 +559,21 @@ private:
   on_destruct_func_t on_destruct;
 
   const src_t src;
+
+  transaction_id_t trans_id = TRANS_ID_NULL;
 };
 using TransactionRef = Transaction::Ref;
 
 /// Should only be used with dummy staged-fltree node extent manager
 inline TransactionRef make_test_transaction() {
+  static transaction_id_t next_id = 0;
   return std::make_unique<Transaction>(
     get_dummy_ordering_handle(),
     false,
     Transaction::src_t::MUTATE,
     JOURNAL_SEQ_NULL,
-    [](Transaction&) {}
+    [](Transaction&) {},
+    ++next_id
   );
 }
 
index 47dcfc7129446119465ef75031f7b0b47ece0182..6cb18c560fab4d967b41006f6d59f8c2d7d9b7e8 100644 (file)
@@ -371,7 +371,8 @@ public:
     ext->init(CachedExtent::extent_state_t::EXIST_CLEAN,
              existing_paddr,
              PLACEMENT_HINT_NULL,
-             NULL_GENERATION);
+             NULL_GENERATION,
+             t.get_trans_id());
 
     t.add_fresh_extent(ext);