]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/cached_extent: add the "refresh" ability to lba
authorXuehan Xu <xuxuehan@qianxin.com>
Mon, 1 Jul 2024 05:58:18 +0000 (13:58 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Mon, 22 Jul 2024 02:38:00 +0000 (10:38 +0800)
mappings

So that we don't have to re-iterate through the whole lba tree to get
a "parent-viewable" mapping in most cases.

Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/btree/btree_range_pin.h
src/crimson/os/seastore/btree/fixed_kv_node.h
src/crimson/os/seastore/cached_extent.h
src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h
src/crimson/os/seastore/lba_manager/btree/lba_btree_node.cc
src/crimson/os/seastore/lba_manager/btree/lba_btree_node.h
src/crimson/os/seastore/transaction_manager.h

index 56bdf5729be337fb1246b7488bd7a4e8b89c5331..e0deb6b3da15a1677d19de3c5185ff109b1e3148 100644 (file)
@@ -225,6 +225,10 @@ public:
     }
     return !is_unviewable_by_trans(*parent, ctx.trans);
   }
+  bool is_parent_valid() const final {
+    ceph_assert(parent);
+    return parent->is_valid();
+  }
 };
 
 }
index 536c11c479e60861c9b11619817d7f0be3daf54c..0bde60ef18ede02ef7fc2677b22044dbd1921b7d 100644 (file)
@@ -134,6 +134,28 @@ struct FixedKVNode : ChildableCachedExtent {
     copy_dests.dests_by_key.erase(dest);
   }
 
+  FixedKVNodeRef find_pending_version(Transaction &t, node_key_t key) {
+    assert(is_stable());
+    auto mut_iter = mutation_pendings.find(
+      t.get_trans_id(), trans_spec_view_t::cmp_t());
+    if (mut_iter != mutation_pendings.end()) {
+      assert(copy_dests_by_trans.find(t.get_trans_id()) ==
+       copy_dests_by_trans.end());
+      return (FixedKVNode*)(&(*mut_iter));
+    }
+    auto iter = copy_dests_by_trans.find(
+      t.get_trans_id(), trans_spec_view_t::cmp_t());
+    ceph_assert(iter != copy_dests_by_trans.end());
+    auto &copy_dests = static_cast<copy_dests_t&>(*iter);
+    auto it = copy_dests.dests_by_key.lower_bound(key);
+    if ((*it)->range.begin > key) {
+      ceph_assert(it != copy_dests.dests_by_key.begin());
+      --it;
+    }
+    ceph_assert((*it)->range.begin <= key && key < (*it)->range.end);
+    return *it;
+  }
+
   bool is_linked() {
     assert(!has_parent_tracker() || !(bool)root_block);
     return (bool)has_parent_tracker() || (bool)root_block;
index 2f8308d5eef8d6a807a5b27fdfae981b3ce72297..1d6ffc740cb818d41c806fb531100b5f9468b24c 100644 (file)
@@ -1121,6 +1121,10 @@ public:
   virtual val_t get_val() const = 0;
   virtual key_t get_key() const = 0;
   virtual PhysicalNodeMappingRef<key_t, val_t> duplicate() const = 0;
+  virtual PhysicalNodeMappingRef<key_t, val_t> refresh_with_pending_parent() {
+    ceph_abort("impossible");
+    return {};
+  }
   virtual bool has_been_invalidated() const = 0;
   virtual CachedExtentRef get_parent() const = 0;
   virtual uint16_t get_pos() const = 0;
@@ -1155,6 +1159,7 @@ public:
     return !get_val().is_real();
   }
   virtual bool is_parent_viewable() const = 0;
+  virtual bool is_parent_valid() const = 0;
   virtual bool parent_modified() const {
     ceph_abort("impossible");
     return false;
index a5b9bb70c18dfd2017255d90f2bf9623fc44518f..aa6f0fecb313e92c2c7870c7de68e689149d7931 100644 (file)
@@ -176,6 +176,14 @@ public:
     auto &p = static_cast<LBALeafNode&>(*parent);
     p.maybe_fix_mapping_pos(*this);
   }
+
+  LBAMappingRef refresh_with_pending_parent() final {
+    assert(is_parent_valid() && !is_parent_viewable());
+    auto &p = static_cast<LBALeafNode&>(*parent);
+    auto &viewable_p = static_cast<LBALeafNode&>(
+      *p.find_pending_version(ctx.trans, get_key()));
+    return viewable_p.get_mapping(ctx, get_key());
+  }
 protected:
   std::unique_ptr<BtreeNodeMapping<laddr_t, paddr_t>> _duplicate(
     op_context_t<laddr_t> ctx) const final {
index 504c346ea946d394971cb1e33c6cc3a90386c428..f3e37ff9bef37d806358c80e927208b368a9aa6d 100644 (file)
@@ -72,4 +72,18 @@ void LBALeafNode::maybe_fix_mapping_pos(BtreeLBAMapping &mapping)
   }
 }
 
+BtreeLBAMappingRef LBALeafNode::get_mapping(
+  op_context_t<laddr_t> c, laddr_t laddr)
+{
+  auto iter = lower_bound(laddr);
+  ceph_assert(iter != end() && iter->get_key() == laddr);
+  auto val = iter.get_val();
+  return std::make_unique<BtreeLBAMapping>(
+    c,
+    this,
+    iter.get_offset(),
+    val,
+    lba_node_meta_t{laddr, val.len, 0});
+}
+
 }
index add464e45e6f938b3ea53e5ed41d1deab1617751..2cd6e7bec4aa65f914d97c9e0724812f643e439e 100644 (file)
@@ -294,6 +294,7 @@ struct LBALeafNode
   std::ostream &_print_detail(std::ostream &out) const final;
 
   void maybe_fix_mapping_pos(BtreeLBAMapping &mapping);
+  std::unique_ptr<BtreeLBAMapping> get_mapping(op_context_t<laddr_t> c, laddr_t laddr);
 };
 using LBALeafNodeRef = TCachedExtentRef<LBALeafNode>;
 
index 1417fd1de004888135c9596093f66dc885431a71..2f4394720aaf9035cfb7ba881eb17329d7e7043e 100644 (file)
@@ -184,11 +184,16 @@ public:
   {
     auto fut = base_iertr::make_ready_future<LBAMappingRef>();
     if (!pin->is_parent_viewable()) {
-      fut = get_pin(t, pin->get_key()
-      ).handle_error_interruptible(
-       crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
-       crimson::ct_error::input_output_error::pass_further{}
-      );
+      if (pin->is_parent_valid()) {
+       pin = pin->refresh_with_pending_parent();
+       fut = base_iertr::make_ready_future<LBAMappingRef>(std::move(pin));
+      } else {
+       fut = get_pin(t, pin->get_key()
+       ).handle_error_interruptible(
+         crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
+         crimson::ct_error::input_output_error::pass_further{}
+       );
+      }
     } else {
       pin->maybe_fix_pos();
       fut = base_iertr::make_ready_future<LBAMappingRef>(std::move(pin));
@@ -476,15 +481,19 @@ public:
       auto fut = base_iertr::now();
       if (!pin->is_indirect()) {
        if (!pin->is_parent_viewable()) {
-         fut = get_pin(t, pin->get_key()
-         ).si_then([&pin](auto npin) {
-           assert(npin);
-           pin = std::move(npin);
-           return seastar::now();
-         }).handle_error_interruptible(
-           crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
-           crimson::ct_error::input_output_error::pass_further{}
-         );
+         if (pin->is_parent_valid()) {
+           pin = pin->refresh_with_pending_parent();
+         } else {
+           fut = get_pin(t, pin->get_key()
+           ).si_then([&pin](auto npin) {
+             assert(npin);
+             pin = std::move(npin);
+             return seastar::now();
+           }).handle_error_interruptible(
+             crimson::ct_error::enoent::assert_failure{"unexpected enoent"},
+             crimson::ct_error::input_output_error::pass_further{}
+           );
+         }
        } else {
          pin->maybe_fix_pos();
        }