]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/btree_lba_manager: allow _alloc_extents to alloc
authorXuehan Xu <xuxuehan@qianxin.com>
Thu, 30 May 2024 11:26:49 +0000 (19:26 +0800)
committerMatan Breizman <mbreizma@redhat.com>
Thu, 25 Jul 2024 07:26:00 +0000 (10:26 +0300)
non-continuous extents as long as it doesn't violate the order of lba
keys

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

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

index 74364d6245cb1e02d738f47b3aaf6ea64443d4f6..bf0a8e3ec791e3544e716403cd56a656f77f0461 100644 (file)
@@ -307,10 +307,27 @@ BtreeLBAManager::_alloc_extents(
   std::vector<alloc_mapping_info_t> &alloc_infos,
   extent_ref_count_t refcount)
 {
+  ceph_assert(hint != L_ADDR_NULL);
   extent_len_t total_len = 0;
+#ifndef NDEBUG
+  bool laddr_null = (alloc_infos.front().key == L_ADDR_NULL);
+  laddr_t last_end = hint;
   for (auto &info : alloc_infos) {
-    total_len += info.len;
+    assert((info.key == L_ADDR_NULL) == (laddr_null));
+    if (!laddr_null) {
+      assert(info.key >= last_end);
+      last_end = info.key + info.len;
+    }
+  }
+#endif
+  if (alloc_infos.front().key == L_ADDR_NULL) {
+    for (auto &info : alloc_infos) {
+      total_len += info.len;
+    }
+  } else {
+    total_len = alloc_infos.back().key + alloc_infos.back().len - hint;
   }
+
   struct state_t {
     laddr_t last_end;
 
@@ -379,6 +396,9 @@ BtreeLBAManager::_alloc_extents(
          alloc_infos,
          [c, addr, hint, &btree, &state, FNAME,
          total_len, &rets, refcount](auto &alloc_info) {
+         if (alloc_info.key != L_ADDR_NULL) {
+           state.last_end = alloc_info.key;
+         }
          return btree.insert(
            c,
            *state.insert_iter,
@@ -396,13 +416,23 @@ BtreeLBAManager::_alloc_extents(
                   c.trans, addr, total_len, hint, state.last_end);
            if (alloc_info.extent) {
              ceph_assert(alloc_info.val.is_paddr());
+             assert(alloc_info.val == iter.get_val().pladdr);
+             assert(alloc_info.len == iter.get_val().len);
+             if (alloc_info.extent->has_laddr()) {
+               assert(alloc_info.key == alloc_info.extent->get_laddr());
+               assert(alloc_info.key == iter.get_key());
+             } else {
+               alloc_info.extent->set_laddr(iter.get_key());
+             }
              alloc_info.extent->set_laddr(iter.get_key());
            }
            ceph_assert(inserted);
            rets.emplace_back(iter.get_pin(c));
            return iter.next(c).si_then([&state, &alloc_info](auto it) {
              state.insert_iter = it;
-             state.last_end += alloc_info.len;
+             if (alloc_info.key == L_ADDR_NULL) {
+               state.last_end += alloc_info.len;
+             }
            });
          });
        });
index 43807efb5fcf94dc00356f692c41224111c8beb0..7a4dbbd5c26ed243b14dfb3338c0e5837dc8d14e 100644 (file)
@@ -225,10 +225,36 @@ public:
 
 
   struct alloc_mapping_info_t {
+    laddr_t key = L_ADDR_NULL; // once assigned, the allocation to
+                              // key must be exact and successful
     extent_len_t len = 0;
     pladdr_t val;
     uint32_t checksum = 0;
     LogicalCachedExtent* extent = nullptr;
+
+    static alloc_mapping_info_t create_zero(extent_len_t len) {
+      return {L_ADDR_NULL, len, P_ADDR_ZERO, 0, nullptr};
+    }
+    static alloc_mapping_info_t create_indirect(
+      laddr_t laddr,
+      extent_len_t len,
+      laddr_t intermediate_key) {
+      return {
+       laddr,
+       len,
+       intermediate_key,
+       0,      // crc will only be used and checked with LBA direct mappings
+               // also see pin_to_extent(_by_type)
+       nullptr};
+    }
+    static alloc_mapping_info_t create_direct(
+      laddr_t laddr,
+      extent_len_t len,
+      paddr_t paddr,
+      uint32_t checksum,
+      LogicalCachedExtent *extent) {
+      return {laddr, len, paddr, checksum, extent};
+    }
   };
 
   alloc_extent_ret reserve_region(
@@ -237,7 +263,7 @@ public:
     extent_len_t len) final
   {
     std::vector<alloc_mapping_info_t> alloc_infos = {
-      alloc_mapping_info_t{len, P_ADDR_ZERO, 0, nullptr}};
+      alloc_mapping_info_t::create_zero(len)};
     return seastar::do_with(
       std::move(alloc_infos),
       [&t, hint, this](auto &alloc_infos) {
@@ -293,8 +319,14 @@ public:
   {
     // The real checksum will be updated upon transaction commit
     assert(ext.get_last_committed_crc() == 0);
-    std::vector<alloc_mapping_info_t> alloc_infos = {{
-      ext.get_length(), ext.get_paddr(), ext.get_last_committed_crc(), &ext}};
+    assert(!ext.has_laddr());
+    std::vector<alloc_mapping_info_t> alloc_infos = {
+      alloc_mapping_info_t::create_direct(
+       L_ADDR_NULL,
+       ext.get_length(),
+       ext.get_paddr(),
+       ext.get_last_committed_crc(),
+       &ext)};
     return seastar::do_with(
       std::move(alloc_infos),
       [this, &t, hint, refcount](auto &alloc_infos) {
@@ -319,11 +351,13 @@ public:
   {
     std::vector<alloc_mapping_info_t> alloc_infos;
     for (auto &extent : extents) {
-      alloc_infos.emplace_back(alloc_mapping_info_t{
-       extent->get_length(),
-       pladdr_t(extent->get_paddr()),
-       extent->get_last_committed_crc(),
-       extent.get()});
+      alloc_infos.emplace_back(
+       alloc_mapping_info_t::create_direct(
+         extent->has_laddr() ? extent->get_laddr() : L_ADDR_NULL,
+         extent->get_length(),
+         extent->get_paddr(),
+         extent->get_last_committed_crc(),
+         extent.get()));
     }
     return seastar::do_with(
       std::move(alloc_infos),
@@ -573,12 +607,7 @@ private:
   {
     assert(intermediate_key != L_ADDR_NULL);
     std::vector<alloc_mapping_info_t> alloc_infos = {
-      alloc_mapping_info_t{
-       len,
-       intermediate_key,
-       0,      // crc will only be used and checked with LBA direct mappings
-               // also see pin_to_extent(_by_type)
-       nullptr}};
+      alloc_mapping_info_t::create_indirect(L_ADDR_NULL, len, intermediate_key)};
     return seastar::do_with(
       std::move(alloc_infos),
       [this, &t, laddr](auto &alloc_infos) {