]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / crimson / os / seastore / lba_manager / btree / btree_lba_manager.h
index b48abf9456bbe7b9a092453d47da48044fd1aa45..892600ed0e94c070affe9879abd3ede2f80585a5 100644 (file)
 namespace crimson::os::seastore::lba_manager::btree {
 
 class BtreeLBAMapping : public BtreeNodeMapping<laddr_t, paddr_t> {
+// To support cloning, there are two kinds of lba mappings:
+//     1. physical lba mapping: the pladdr in the value of which is the paddr of
+//        the corresponding extent;
+//     2. indirect lba mapping: the pladdr in the value of which is an laddr pointing
+//        to the physical lba mapping that's pointing to the actual paddr of the
+//        extent being searched;
+//
+// Accordingly, BtreeLBAMapping may also work under two modes: indirect or direct
+//     1. BtreeLBAMappings that come from quering an indirect lba mapping in the lba tree
+//        are indirect;
+//     2. BtreeLBAMappings that come from quering a physical lba mapping in the lba tree
+//        are direct.
+//
+// For direct BtreeLBAMappings, there are two important fields:
+//      1. key: the laddr of the lba mapping being queried;
+//      2. paddr: the paddr recorded in the value of the lba mapping being queried.
+// For indirect BtreeLBAMappings, BtreeLBAMapping has three important fields:
+//     1. key: the laddr key of the lba entry being queried;
+//     2. intermediate_key: the laddr within the scope of the physical lba mapping
+//        that the current indirect lba mapping points to; although an indirect mapping
+//        points to the start of the physical lba mapping, it may change to other
+//        laddr after remap
+//     3. intermediate_base: the laddr key of the physical lba mapping, intermediate_key
+//        and intermediate_base should be the same when doing cloning
+//     4. intermediate_offset: intermediate_key - intermediate_base
+//     5. paddr: the paddr recorded in the physical lba mapping pointed to by the
+//        indirect lba mapping being queried;
+//
+// NOTE THAT, for direct BtreeLBAMappings, their intermediate_keys are the same as
+// their keys.
 public:
   BtreeLBAMapping(op_context_t<laddr_t> ctx)
     : BtreeNodeMapping(ctx) {}
@@ -34,17 +64,112 @@ public:
     CachedExtentRef parent,
     uint16_t pos,
     lba_map_val_t &val,
-    lba_node_meta_t &&meta)
+    lba_node_meta_t meta)
     : BtreeNodeMapping(
        c,
        parent,
        pos,
-       val.paddr,
+       val.pladdr.is_paddr() ? val.pladdr.get_paddr() : P_ADDR_NULL,
        val.len,
-       std::forward<lba_node_meta_t>(meta))
+       meta),
+      key(meta.begin),
+      indirect(val.pladdr.is_laddr() ? true : false),
+      intermediate_key(indirect ? val.pladdr.get_laddr() : L_ADDR_NULL),
+      intermediate_length(indirect ? val.len : 0),
+      raw_val(val.pladdr),
+      map_val(val)
   {}
+
+  lba_map_val_t get_map_val() const {
+    return map_val;
+  }
+
+  bool is_indirect() const final {
+    return indirect;
+  }
+
+  void set_key_for_indirect(
+    laddr_t new_key,
+    extent_len_t length,
+    laddr_t interkey = L_ADDR_NULL)
+  {
+    turn_indirect(interkey);
+    key = new_key;
+    intermediate_length = len;
+    len = length;
+  }
+
+  laddr_t get_key() const final {
+    return key;
+  }
+
+  pladdr_t get_raw_val() const {
+    return raw_val;
+  }
+
+  void set_paddr(paddr_t addr) {
+    value = addr;
+  }
+
+  laddr_t get_intermediate_key() const final {
+    assert(is_indirect());
+    assert(intermediate_key != L_ADDR_NULL);
+    return intermediate_key;
+  }
+
+  laddr_t get_intermediate_base() const final {
+    assert(is_indirect());
+    assert(intermediate_base != L_ADDR_NULL);
+    return intermediate_base;
+  }
+
+  extent_len_t get_intermediate_offset() const final {
+    assert(intermediate_key >= intermediate_base);
+    assert((intermediate_key == L_ADDR_NULL)
+      == (intermediate_base == L_ADDR_NULL));
+    return intermediate_key - intermediate_base;
+  }
+
+  extent_len_t get_intermediate_length() const final {
+    assert(is_indirect());
+    assert(intermediate_length);
+    return intermediate_length;
+  }
+
+  void set_intermediate_base(laddr_t base) {
+    intermediate_base = base;
+  }
+
+protected:
+  std::unique_ptr<BtreeNodeMapping<laddr_t, paddr_t>> _duplicate(
+    op_context_t<laddr_t> ctx) const final {
+    auto pin = std::unique_ptr<BtreeLBAMapping>(new BtreeLBAMapping(ctx));
+    pin->key = key;
+    pin->intermediate_base = intermediate_base;
+    pin->intermediate_key = intermediate_key;
+    pin->indirect = indirect;
+    pin->raw_val = raw_val;
+    pin->map_val = map_val;
+    return pin;
+  }
+private:
+  void turn_indirect(laddr_t interkey) {
+    assert(value.is_paddr());
+    intermediate_base = key;
+    intermediate_key = (interkey == L_ADDR_NULL ? key : interkey);
+    indirect = true;
+  }
+  laddr_t key = L_ADDR_NULL;
+  bool indirect = false;
+  laddr_t intermediate_key = L_ADDR_NULL;
+  laddr_t intermediate_base = L_ADDR_NULL;
+  extent_len_t intermediate_length = 0;
+  pladdr_t raw_val;
+  lba_map_val_t map_val;
 };
 
+using BtreeLBAMappingRef = std::unique_ptr<BtreeLBAMapping>;
+
 using LBABtree = FixedKVBtree<
   laddr_t, lba_map_val_t, LBAInternalNode,
   LBALeafNode, BtreeLBAMapping, LBA_BLOCK_SIZE, true>;
@@ -89,23 +214,75 @@ public:
     Transaction &t,
     laddr_t offset) final;
 
+  alloc_extent_ret reserve_region(
+    Transaction &t,
+    laddr_t hint,
+    extent_len_t len)
+  {
+    return _alloc_extent(
+      t,
+      hint,
+      len,
+      P_ADDR_ZERO,
+      P_ADDR_NULL,
+      L_ADDR_NULL,
+      nullptr);
+  }
+
+  alloc_extent_ret clone_extent(
+    Transaction &t,
+    laddr_t hint,
+    extent_len_t len,
+    laddr_t intermediate_key,
+    paddr_t actual_addr,
+    laddr_t intermediate_base)
+  {
+    return _alloc_extent(
+      t,
+      hint,
+      len,
+      intermediate_key,
+      actual_addr,
+      intermediate_base,
+      nullptr);
+  }
+
   alloc_extent_ret alloc_extent(
     Transaction &t,
     laddr_t hint,
     extent_len_t len,
     paddr_t addr,
-    LogicalCachedExtent*) final;
+    LogicalCachedExtent &ext) final
+  {
+    return _alloc_extent(
+      t,
+      hint,
+      len,
+      addr,
+      P_ADDR_NULL,
+      L_ADDR_NULL,
+      &ext);
+  }
 
   ref_ret decref_extent(
     Transaction &t,
-    laddr_t addr) final {
-    return update_refcount(t, addr, -1);
+    laddr_t addr,
+    bool cascade_remove) final {
+    return update_refcount(t, addr, -1, cascade_remove);
   }
 
   ref_ret incref_extent(
     Transaction &t,
     laddr_t addr) final {
-    return update_refcount(t, addr, 1);
+    return update_refcount(t, addr, 1, false);
+  }
+
+  ref_ret incref_extent(
+    Transaction &t,
+    laddr_t addr,
+    int delta) final {
+    ceph_assert(delta > 0);
+    return update_refcount(t, addr, delta, false);
   }
 
   /**
@@ -170,7 +347,8 @@ private:
   update_refcount_ret update_refcount(
     Transaction &t,
     laddr_t addr,
-    int delta);
+    int delta,
+    bool cascade_remove);
 
   /**
    * _update_mapping
@@ -187,6 +365,31 @@ private:
     laddr_t addr,
     update_func_t &&f,
     LogicalCachedExtent*);
+
+  alloc_extent_ret _alloc_extent(
+    Transaction &t,
+    laddr_t hint,
+    extent_len_t len,
+    pladdr_t addr,
+    paddr_t actual_addr,
+    laddr_t intermediate_base,
+    LogicalCachedExtent*);
+
+  using _get_mapping_ret = get_mapping_iertr::future<BtreeLBAMappingRef>;
+  _get_mapping_ret _get_mapping(
+    Transaction &t,
+    laddr_t offset);
+
+  using _get_original_mappings_ret = get_mappings_ret;
+  _get_original_mappings_ret _get_original_mappings(
+    op_context_t<laddr_t> c,
+    std::list<BtreeLBAMappingRef> &pin_list);
+
+  ref_iertr::future<std::optional<std::pair<paddr_t, extent_len_t>>>
+  _decref_intermediate(
+    Transaction &t,
+    laddr_t addr,
+    extent_len_t len);
 };
 using BtreeLBAManagerRef = std::unique_ptr<BtreeLBAManager>;