]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/btree: always check the stability of extents within 57482/head
authorXuehan Xu <xuxuehan@qianxin.com>
Thu, 21 Mar 2024 01:54:42 +0000 (09:54 +0800)
committerMatan Breizman <mbreizma@redhat.com>
Wed, 15 May 2024 14:58:27 +0000 (17:58 +0300)
the current transaction's view

Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
(cherry picked from commit 7dcd74ac098201d2ea6f9d1c723f9944ade6bf33)

src/crimson/os/seastore/btree/btree_range_pin.cc
src/crimson/os/seastore/btree/fixed_kv_node.h
src/crimson/os/seastore/cache.h
src/crimson/os/seastore/cached_extent.h

index 1fe79eafa8177067264cb2e6d2ddc4184463d7fe..3da1cac970ae74bb603effa21b79293927ce9dca 100644 (file)
@@ -29,7 +29,7 @@ bool BtreeNodeMapping<key_t, val_t>::is_stable() const
   assert(parent->is_valid());
   assert(pos != std::numeric_limits<uint16_t>::max());
   auto &p = (FixedKVNode<key_t>&)*parent;
-  return p.is_child_stable(pos);
+  return p.is_child_stable(ctx, pos);
 }
 
 template class BtreeNodeMapping<laddr_t, paddr_t>;
index de3569c0c5bcf9e8b1eee3d1bec0621a59e8086a..ab8775ad8aa8308cb934fe4da94851817015cc09 100644 (file)
@@ -229,13 +229,14 @@ struct FixedKVNode : ChildableCachedExtent {
   virtual get_child_ret_t<LogicalCachedExtent>
   get_logical_child(op_context_t<node_key_t> c, uint16_t pos) = 0;
 
-  virtual bool is_child_stable(uint16_t pos) const = 0;
+  virtual bool is_child_stable(op_context_t<node_key_t>, uint16_t pos) const = 0;
 
   template <typename T, typename iter_t>
   get_child_ret_t<T> get_child(op_context_t<node_key_t> c, iter_t iter) {
     auto pos = iter.get_offset();
     assert(children.capacity());
     auto child = children[pos];
+    ceph_assert(!is_reserved_ptr(child));
     if (is_valid_child_ptr(child)) {
       ceph_assert(child->get_type() == T::TYPE);
       return c.cache.template get_extent_viewable_by_trans<T>(c.trans, (T*)child);
@@ -596,7 +597,7 @@ struct FixedKVInternalNode
     return get_child_ret_t<LogicalCachedExtent>(child_pos_t(nullptr, 0));
   }
 
-  bool is_child_stable(uint16_t pos) const final {
+  bool is_child_stable(op_context_t<NODE_KEY>, uint16_t pos) const final {
     ceph_abort("impossible");
     return false;
   }
@@ -999,13 +1000,16 @@ struct FixedKVLeafNode
   // 2. The child extent is stable
   //
   // For reserved mappings, the return values are undefined.
-  bool is_child_stable(uint16_t pos) const final {
+  bool is_child_stable(op_context_t<NODE_KEY> c, uint16_t pos) const final {
     auto child = this->children[pos];
     if (is_reserved_ptr(child)) {
       return true;
     } else if (is_valid_child_ptr(child)) {
       ceph_assert(child->is_logical());
-      return child->is_stable();
+      ceph_assert(
+       child->is_pending_in_trans(c.trans.get_trans_id())
+       || this->is_stable_written());
+      return c.cache.is_viewable_extent_stable(c.trans, child);
     } else if (this->is_pending()) {
       auto key = this->iter_idx(pos).get_key();
       auto &sparent = this->get_stable_for_key(key);
@@ -1013,7 +1017,7 @@ struct FixedKVLeafNode
       auto child = sparent.children[spos];
       if (is_valid_child_ptr(child)) {
        ceph_assert(child->is_logical());
-       return child->is_stable();
+       return c.cache.is_viewable_extent_stable(c.trans, child);
       } else {
        return true;
       }
index 262703573d9379c00e6aecf3962c01016d43d76b..c06193cbbf57584195c20a2ce9027056985f8947 100644 (file)
@@ -443,6 +443,15 @@ public:
     return get_absent_extent<T>(t, offset, length, [](T &){});
   }
 
+  bool is_viewable_extent_stable(
+    Transaction &t,
+    CachedExtentRef extent)
+  {
+    assert(extent);
+    auto view = extent->get_transactional_view(t);
+    return view->is_stable();
+  }
+
   using get_extent_ertr = base_ertr;
   get_extent_ertr::future<CachedExtentRef>
   get_extent_viewable_by_trans(
index 730a0ace9a0b750bfe8743d52e19b73656e40579..fee7ca74514cdbc5f81b6689522f117ee2840ee5 100644 (file)
@@ -618,6 +618,11 @@ public:
     return last_committed_crc;
   }
 
+  /// Returns true if the extent part of the open transaction
+  bool is_pending_in_trans(transaction_id_t id) const {
+    return is_pending() && pending_for_transaction == id;
+  }
+
 private:
   template <typename T>
   friend class read_set_item_t;
@@ -648,11 +653,6 @@ private:
     ptr = nptr;
   }
 
-  /// Returns true if the extent part of the open transaction
-  bool is_pending_in_trans(transaction_id_t id) const {
-    return is_pending() && pending_for_transaction == id;
-  }
-
   /// hook for intrusive ref list (mainly dirty or lru list)
   boost::intrusive::list_member_hook<> primary_ref_list_hook;
   using primary_ref_list_member_options = boost::intrusive::member_hook<