]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/BtreeLBAManager: cleanup the impl of alloc mapping and remap
authorZhang Song <zhangsong02@qianxin.com>
Thu, 24 Apr 2025 09:25:37 +0000 (17:25 +0800)
committerMatan Breizman <mbreizma@redhat.com>
Sun, 8 Jun 2025 07:02:03 +0000 (10:02 +0300)
Signed-off-by: Zhang Song <zhangsong02@qianxin.com>
(cherry picked from commit d143fa7bb09b004f60efd6c94a6d34e00205249c)

src/crimson/os/seastore/lba_manager.h
src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.cc
src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.h
src/crimson/os/seastore/transaction_manager.h

index bbc05898c63f8c1ef18292ad35aacc00e25de545..120e3b9b962c3a1e5b57fbd37d4f6de6a0ed59ff 100644 (file)
@@ -45,7 +45,7 @@ public:
    * lba value.
    */
   using get_mappings_iertr = base_iertr;
-  using get_mappings_ret = get_mappings_iertr::future<lba_pin_list_t>;
+  using get_mappings_ret = get_mappings_iertr::future<lba_mapping_list_t>;
   virtual get_mappings_ret get_mappings(
     Transaction &t,
     laddr_t offset, extent_len_t length) = 0;
@@ -59,7 +59,7 @@ public:
    */
   using get_mapping_iertr = base_iertr::extend<
     crimson::ct_error::enoent>;
-  using get_mapping_ret = get_mapping_iertr::future<LBAMappingRef>;
+  using get_mapping_ret = get_mapping_iertr::future<LBAMapping>;
   virtual get_mapping_ret get_mapping(
     Transaction &t,
     laddr_t offset) = 0;
@@ -72,7 +72,7 @@ public:
    * is called on the LBAMapping.
    */
   using alloc_extent_iertr = base_iertr;
-  using alloc_extent_ret = alloc_extent_iertr::future<LBAMappingRef>;
+  using alloc_extent_ret = alloc_extent_iertr::future<LBAMapping>;
   virtual alloc_extent_ret alloc_extent(
     Transaction &t,
     laddr_t hint,
@@ -80,7 +80,7 @@ public:
     extent_ref_count_t refcount) = 0;
 
   using alloc_extents_ret = alloc_extent_iertr::future<
-    std::vector<LBAMappingRef>>;
+    std::vector<LBAMapping>>;
   virtual alloc_extents_ret alloc_extents(
     Transaction &t,
     laddr_t hint,
@@ -126,12 +126,8 @@ public:
       len = _len;
     }
   };
-  struct lba_remap_ret_t {
-    ref_update_result_t ruret;
-    std::vector<LBAMappingRef> remapped_mappings;
-  };
   using remap_iertr = ref_iertr;
-  using remap_ret = remap_iertr::future<lba_remap_ret_t>;
+  using remap_ret = remap_iertr::future<std::vector<LBAMapping>>;
 
   /**
    * remap_mappings
@@ -141,7 +137,7 @@ public:
    */
   virtual remap_ret remap_mappings(
     Transaction &t,
-    LBAMappingRef orig_mapping,
+    LBAMapping orig_mapping,
     std::vector<remap_entry_t> remaps,
     std::vector<LogicalChildNodeRef> extents  // Required if and only
                                                 // if pin isn't indirect
index 6cb38c5c1ae8548803bf19cc62ff90ac42a2f3cc..8914e8d5b12bfdce4881b1e015a4d79c9913fc78 100644 (file)
@@ -788,6 +788,106 @@ BtreeLBAManager::_decref_intermediate(
   });
 }
 
+BtreeLBAManager::remap_ret
+BtreeLBAManager::remap_mappings(
+  Transaction &t,
+  LBAMapping orig_mapping,
+  std::vector<remap_entry_t> remaps,
+  std::vector<LogicalChildNodeRef> extents)
+{
+  LOG_PREFIX(BtreeLBAManager::remap_mappings);
+  struct state_t {
+    LBAMapping orig_mapping;
+    std::vector<remap_entry_t> remaps;
+    std::vector<LogicalChildNodeRef> extents;
+    std::vector<alloc_mapping_info_t> alloc_infos;
+    std::vector<LBAMapping> ret;
+  };
+  return seastar::do_with(
+    state_t(std::move(orig_mapping), std::move(remaps), std::move(extents), {}, {}),
+    [this, &t, FNAME](state_t &state)
+  {
+    return update_refcount(
+      t, state.orig_mapping.get_key(), -1, false
+    ).si_then([this, &t, &state, FNAME](auto ret) {
+      // Remapping the shared direct mapping is prohibited,
+      // the refcount of indirect mapping should always be 1.
+      ceph_assert(ret.is_removed_mapping());
+
+      auto orig_laddr = state.orig_mapping.get_key();
+      if (!state.orig_mapping.is_indirect()) {
+       auto &addr = ret.get_removed_mapping().map_value.pladdr;
+       ceph_assert(addr.is_paddr() && !addr.get_paddr().is_zero());
+       return alloc_extents(
+         t,
+         (state.remaps.front().offset + orig_laddr).checked_to_laddr(),
+         std::move(state.extents),
+         EXTENT_DEFAULT_REF_COUNT
+       ).si_then([&state](auto ret) {
+         state.ret = std::move(ret);
+         return remap_iertr::make_ready_future();
+       });
+      }
+
+      extent_len_t orig_len = state.orig_mapping.get_length();
+      auto intermediate_key = state.orig_mapping.get_intermediate_key();
+      ceph_assert(intermediate_key != L_ADDR_NULL);
+      DEBUGT("remap indirect mapping {}", t, state.orig_mapping);
+      for (auto &remap : state.remaps) {
+       DEBUGT("remap 0x{:x}~0x{:x}", t, remap.offset, remap.len);
+       ceph_assert(remap.len != 0);
+       ceph_assert(remap.offset + remap.len <= orig_len);
+       auto remapped_laddr = (orig_laddr + remap.offset)
+           .checked_to_laddr();
+       auto remapped_intermediate_key = (intermediate_key + remap.offset)
+           .checked_to_laddr();
+       state.alloc_infos.emplace_back(
+         alloc_mapping_info_t::create_indirect(
+           remapped_laddr, remap.len, remapped_intermediate_key));
+      }
+
+      return alloc_sparse_mappings(
+       t, state.alloc_infos.front().key, state.alloc_infos,
+       alloc_policy_t::deterministic
+      ).si_then([&t, &state, this](std::list<LBACursorRef> cursors) {
+       return seastar::futurize_invoke([&t, &state, this] {
+         if (state.remaps.size() > 1) {
+           auto base = state.orig_mapping.get_intermediate_base();
+           return update_refcount(
+             t, base, state.remaps.size() - 1, false
+           ).si_then([](update_mapping_ret_bare_t ret) {
+             return ret.take_cursor();
+           });
+         } else {
+           return remap_iertr::make_ready_future<
+             LBACursorRef>(state.orig_mapping.direct_cursor->duplicate());
+         }
+       }).si_then([&state, cursors=std::move(cursors)](auto direct) mutable {
+         for (auto &cursor : cursors) {
+           state.ret.emplace_back(LBAMapping::create_indirect(
+             direct->duplicate(), std::move(cursor)));
+         }
+         return remap_iertr::make_ready_future();
+       });
+      });
+    }).si_then([&state] {
+      assert(state.ret.size() == state.remaps.size());
+#ifndef NDEBUG
+      auto mapping_it = state.ret.begin();
+      auto remap_it = state.remaps.begin();
+      for (;mapping_it != state.ret.end(); mapping_it++, remap_it++) {
+       auto &mapping = *mapping_it;
+       auto &remap = *remap_it;
+       assert(mapping.get_key() == state.orig_mapping.get_key() + remap.offset);
+       assert(mapping.get_length() == remap.len);
+      }
+#endif
+      return remap_iertr::make_ready_future<
+       std::vector<LBAMapping>>(std::move(state.ret));
+    });
+  });
+}
+
 BtreeLBAManager::update_refcount_ret
 BtreeLBAManager::update_refcount(
   Transaction &t,
index c31923641e8499ce3b08bff7355f5b1c5dbc1b5b..33cdcee8e5a24f0f6dceb5b337e49fe58243a289 100644 (file)
@@ -79,14 +79,11 @@ public:
     return seastar::do_with(
       std::move(alloc_infos),
       [&t, hint, this](auto &alloc_infos) {
-      return _alloc_extents(
-       t,
-       hint,
-       alloc_infos
-      ).si_then([](auto mappings) {
-       assert(mappings.size() == 1);
-       auto mapping = std::move(mappings.front());
-       return mapping;
+      return alloc_contiguous_mappings(
+       t, hint, alloc_infos, alloc_policy_t::linear_search
+      ).si_then([](auto cursors) {
+       assert(cursors.size() == 1);
+       return LBAMapping::create_direct(std::move(cursors.front()));
       });
     });
   }
@@ -101,29 +98,27 @@ public:
     std::vector<alloc_mapping_info_t> alloc_infos = {
       alloc_mapping_info_t::create_indirect(
        laddr, len, intermediate_key)};
-    return alloc_cloned_mappings(
-      t,
-      laddr,
-      std::move(alloc_infos)
-    ).si_then([&t, this, intermediate_base](auto imappings) {
-      assert(imappings.size() == 1);
-      auto &imapping = imappings.front();
-      return update_refcount(t, intermediate_base, 1, false
-      ).si_then([imapping=std::move(imapping)](auto p) mutable {
-       auto mapping = std::move(p.mapping);
-       ceph_assert(mapping->is_stable());
-       ceph_assert(imapping->is_indirect());
-       mapping->make_indirect(
-         imapping->get_key(),
-         imapping->get_length(),
-         imapping->get_intermediate_key());
-       return seastar::make_ready_future<
-         LBAMappingRef>(std::move(mapping));
-      });
-    }).handle_error_interruptible(
-      crimson::ct_error::input_output_error::pass_further{},
-      crimson::ct_error::assert_all{"unexpect enoent"}
-    );
+    return seastar::do_with(
+      std::move(alloc_infos),
+      [this, &t, laddr, intermediate_base](auto &infos) {
+       return alloc_sparse_mappings(
+         t, laddr, infos, alloc_policy_t::deterministic
+       ).si_then([this, &t, intermediate_base](auto cursors) {
+         ceph_assert(cursors.size() == 1);
+         ceph_assert(cursors.front()->is_indirect());
+         return update_refcount(t, intermediate_base, 1, false
+         ).si_then([cursors=std::move(cursors)](auto p) mutable {
+           assert(p.is_alive_mapping());
+           auto mapping = LBAMapping::create_indirect(
+             p.take_cursor(), std::move(cursors.front()));
+           ceph_assert(mapping.is_stable());
+           return alloc_extent_iertr::make_ready_future<
+             LBAMapping>(std::move(mapping));
+         });
+       });
+      }).handle_error_interruptible(
+       crimson::ct_error::input_output_error::pass_further{},
+       crimson::ct_error::assert_all{"unexpect enoent"});
   }
 
   alloc_extent_ret alloc_extent(
@@ -145,15 +140,12 @@ public:
        ext)};
     return seastar::do_with(
       std::move(alloc_infos),
-      [this, &t, hint, refcount](auto &alloc_infos) {
-      return _alloc_extents(
-       t,
-       hint,
-       alloc_infos
-      ).si_then([](auto mappings) {
-       assert(mappings.size() == 1);
-       auto mapping = std::move(mappings.front());
-       return mapping;
+      [this, &t, hint](auto &alloc_infos) {
+      return alloc_contiguous_mappings(
+       t, hint, alloc_infos, alloc_policy_t::linear_search
+      ).si_then([](auto cursors) {
+       assert(cursors.size() == 1);
+       return LBAMapping::create_direct(std::move(cursors.front()));
       });
     });
   }
@@ -165,8 +157,11 @@ public:
     extent_ref_count_t refcount) final
   {
     std::vector<alloc_mapping_info_t> alloc_infos;
+    assert(!extents.empty());
+    auto has_laddr = extents.front()->has_laddr();
     for (auto &extent : extents) {
       assert(extent);
+      assert(extent->has_laddr() == has_laddr);
       alloc_infos.emplace_back(
        alloc_mapping_info_t::create_direct(
          extent->has_laddr() ? extent->get_laddr() : L_ADDR_NULL,
@@ -178,8 +173,35 @@ public:
     }
     return seastar::do_with(
       std::move(alloc_infos),
-      [this, &t, hint](auto &alloc_infos) {
-      return _alloc_extents(t, hint, alloc_infos);
+      [this, &t, hint, has_laddr](auto &alloc_infos)
+    {
+      if (has_laddr) {
+       return alloc_sparse_mappings(
+         t, hint, alloc_infos, alloc_policy_t::deterministic)
+#ifndef NDEBUG
+       .si_then([&alloc_infos](std::list<LBACursorRef> cursors) {
+         assert(alloc_infos.size() == cursors.size());
+         auto info_p = alloc_infos.begin();
+         auto cursor_p = cursors.begin();
+         for (; info_p != alloc_infos.end(); info_p++, cursor_p++) {
+           auto &cursor = *cursor_p;
+           assert(cursor->get_laddr() == info_p->key);
+         }
+         return alloc_extent_iertr::make_ready_future<
+           std::list<LBACursorRef>>(std::move(cursors));
+       })
+#endif
+         ;
+      } else {
+       return alloc_contiguous_mappings(
+         t, hint, alloc_infos, alloc_policy_t::linear_search);
+      }
+    }).si_then([](std::list<LBACursorRef> cursors) {
+      std::vector<LBAMapping> ret;
+      for (auto &cursor : cursors) {
+       ret.emplace_back(LBAMapping::create_direct(std::move(cursor)));
+      }
+      return ret;
     });
   }
 
@@ -194,118 +216,9 @@ public:
 
   remap_ret remap_mappings(
     Transaction &t,
-    LBAMappingRef orig_mapping,
+    LBAMapping orig_mapping,
     std::vector<remap_entry_t> remaps,
-    std::vector<LogicalChildNodeRef> extents) final {
-    LOG_PREFIX(BtreeLBAManager::remap_mappings);
-    assert((orig_mapping->is_indirect())
-      == (remaps.size() != extents.size()));
-    return seastar::do_with(
-      lba_remap_ret_t{},
-      std::move(remaps),
-      std::move(extents),
-      std::move(orig_mapping),
-      [&t, FNAME, this](auto &ret, const auto &remaps,
-                       auto &extents, auto &orig_mapping) {
-      return update_refcount(t, orig_mapping->get_key(), -1, false
-      ).si_then([&ret, this, &extents, &remaps,
-               &t, &orig_mapping, FNAME](auto r) {
-       ret.ruret = std::move(r.ref_update_res);
-       if (!orig_mapping->is_indirect()) {
-         ceph_assert(ret.ruret.refcount == 0 &&
-           ret.ruret.addr.is_paddr() &&
-           !ret.ruret.addr.get_paddr().is_zero());
-       }
-       auto fut = alloc_extent_iertr::make_ready_future<
-         std::vector<LBAMappingRef>>();
-       laddr_t orig_laddr = orig_mapping->get_key();
-       if (orig_mapping->is_indirect()) {
-         std::vector<alloc_mapping_info_t> alloc_infos;
-         for (auto &remap : remaps) {
-           extent_len_t orig_len = orig_mapping->get_length();
-           paddr_t orig_paddr = orig_mapping->get_val();
-           laddr_t intermediate_base = orig_mapping->is_indirect()
-             ? orig_mapping->get_intermediate_base()
-             : L_ADDR_NULL;
-           laddr_t intermediate_key = orig_mapping->is_indirect()
-             ? orig_mapping->get_intermediate_key()
-             : L_ADDR_NULL;
-           auto remap_offset = remap.offset;
-           auto remap_len = remap.len;
-           auto remap_laddr = (orig_laddr + remap_offset).checked_to_laddr();
-           ceph_assert(intermediate_base != L_ADDR_NULL);
-           ceph_assert(intermediate_key != L_ADDR_NULL);
-           ceph_assert(remap_len < orig_len);
-           ceph_assert(remap_offset + remap_len <= orig_len);
-           ceph_assert(remap_len != 0);
-           SUBDEBUGT(seastore_lba,
-             "remap laddr: {}, remap paddr: {}, remap length: {},"
-             " intermediate_base: {}, intermediate_key: {}", t,
-             remap_laddr, orig_paddr, remap_len,
-             intermediate_base, intermediate_key);
-           auto remapped_intermediate_key = (intermediate_key + remap_offset).checked_to_laddr();
-           alloc_infos.emplace_back(
-             alloc_mapping_info_t::create_indirect(
-               remap_laddr,
-               remap_len,
-               remapped_intermediate_key));
-         }
-         fut = alloc_cloned_mappings(
-           t,
-           (remaps.front().offset + orig_laddr).checked_to_laddr(),
-           std::move(alloc_infos)
-         ).si_then([&orig_mapping](auto imappings) mutable {
-           std::vector<LBAMappingRef> mappings;
-           for (auto &imapping : imappings) {
-             auto mapping = orig_mapping->duplicate();
-             auto bmapping = static_cast<BtreeLBAMapping*>(mapping.get());
-             bmapping->adjust_mutable_indirect_attrs(
-               imapping->get_key(),
-               imapping->get_length(),
-               imapping->get_intermediate_key());
-             mappings.emplace_back(std::move(mapping));
-           }
-           return seastar::make_ready_future<std::vector<LBAMappingRef>>(
-             std::move(mappings));
-         });
-       } else { // !orig_mapping->is_indirect()
-         fut = alloc_extents(
-           t,
-           (remaps.front().offset + orig_laddr).checked_to_laddr(),
-           std::move(extents),
-           EXTENT_DEFAULT_REF_COUNT);
-       }
-
-       return fut.si_then([&ret, &remaps, &orig_mapping](auto &&refs) {
-         assert(refs.size() == remaps.size());
-#ifndef NDEBUG
-         auto ref_it = refs.begin();
-         auto remap_it = remaps.begin();
-         for (;ref_it != refs.end(); ref_it++, remap_it++) {
-           auto &ref = *ref_it;
-           auto &remap = *remap_it;
-           assert(ref->get_key() == orig_mapping->get_key() + remap.offset);
-           assert(ref->get_length() == remap.len);
-         }
-#endif
-         ret.remapped_mappings = std::move(refs);
-         return seastar::now();
-       });
-      }).si_then([&remaps, &t, &orig_mapping, this] {
-       if (remaps.size() > 1 && orig_mapping->is_indirect()) {
-         auto intermediate_base = orig_mapping->get_intermediate_base();
-         return _incref_extent(t, intermediate_base, remaps.size() - 1
-         ).si_then([](auto) {
-           return seastar::now();
-         });
-       }
-       return ref_iertr::now();
-      }).si_then([&ret, &remaps] {
-       assert(ret.remapped_mappings.size() == remaps.size());
-       return seastar::make_ready_future<lba_remap_ret_t>(std::move(ret));
-      });
-    });
-  }
+    std::vector<LogicalChildNodeRef> extents) final;
 
   /**
    * init_cached_extent
@@ -572,43 +485,6 @@ private:
     });
   }
 
-  alloc_extent_iertr::future<std::vector<BtreeLBAMappingRef>> alloc_cloned_mappings(
-    Transaction &t,
-    laddr_t laddr,
-    std::vector<alloc_mapping_info_t> alloc_infos)
-  {
-#ifndef NDEBUG
-    for (auto &alloc_info : alloc_infos) {
-      assert(alloc_info.value.pladdr.get_laddr() != L_ADDR_NULL);
-      assert(alloc_info.value.refcount == EXTENT_DEFAULT_REF_COUNT);
-    }
-#endif
-    return seastar::do_with(
-      std::move(alloc_infos),
-      [this, &t, laddr](auto &alloc_infos) {
-      return _alloc_extents(
-       t,
-       laddr,
-       alloc_infos
-      ).si_then([&alloc_infos](auto mappings) {
-       assert(alloc_infos.size() == mappings.size());
-       std::vector<BtreeLBAMappingRef> rets;
-       auto mit = mappings.begin();
-       auto ait = alloc_infos.begin();
-       for (; mit != mappings.end(); mit++, ait++) {
-         auto mapping = static_cast<BtreeLBAMapping*>(mit->release());
-         [[maybe_unused]] auto &alloc_info = *ait;
-         assert(mapping->get_key() == alloc_info.key);
-         assert(mapping->get_raw_val().get_laddr() ==
-           alloc_info.value.pladdr.get_laddr());
-         assert(mapping->get_length() == alloc_info.value.len);
-         rets.emplace_back(mapping);
-       }
-       return rets;
-      });
-    });
-  }
-
   using _get_cursor_ret = get_mapping_iertr::future<LBACursorRef>;
   _get_cursor_ret get_cursor(
     op_context_t c,
index 6d6e4562712c97a2fd6c0a58ebd9885e8a2bf7d1..f2169e0ffdcc749c559ed547df2343fbb0f4e32b 100644 (file)
@@ -636,10 +636,9 @@ public:
          std::vector<remap_entry_t>(remaps.begin(), remaps.end()),
          std::move(extents)
        ).si_then([FNAME, &t](auto ret) {
-         SUBDEBUGT(seastore_tm, "remapped {} pins",
-                   t, ret.remapped_mappings.size());
+         SUBDEBUGT(seastore_tm, "remapped {} pins", t, ret.size());
          return Cache::retire_extent_iertr::make_ready_future<
-           std::vector<LBAMappingRef>>(std::move(ret.remapped_mappings));
+           std::vector<LBAMapping>>(std::move(ret));
        });
       }).handle_error_interruptible(
        remap_pin_iertr::pass_further{},