]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/os/seastore/btree: allow BtreeCursor to represent the end of the
authorXuehan Xu <xuxuehan@qianxin.com>
Sun, 16 Mar 2025 03:45:26 +0000 (11:45 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Tue, 5 Aug 2025 06:33:59 +0000 (14:33 +0800)
tree

Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/btree/btree_types.h
src/crimson/os/seastore/btree/fixed_kv_btree.h
src/crimson/os/seastore/lba/btree_lba_manager.cc
src/crimson/os/seastore/lba_manager.h
src/crimson/os/seastore/lba_mapping.cc
src/crimson/os/seastore/lba_mapping.h

index 87f4e72bb1640178a838814793034c4431dd178f..fb4e465a05ddfd1621baa7a700c14431c5d560ab 100644 (file)
@@ -253,8 +253,7 @@ struct LBACursor : BtreeCursor<laddr_t, lba::lba_map_val_t> {
   using Base = BtreeCursor<laddr_t, lba::lba_map_val_t>;
   using Base::BtreeCursor;
   bool is_indirect() const {
-    assert(!is_end());
-    return val->pladdr.is_laddr();
+    return !is_end() && val->pladdr.is_laddr();
   }
   laddr_t get_laddr() const {
     return key;
@@ -298,6 +297,7 @@ struct BackrefCursor : BtreeCursor<paddr_t, backref::backref_map_val_t> {
   using Base = BtreeCursor<paddr_t, backref::backref_map_val_t>;
   using Base::BtreeCursor;
   paddr_t get_paddr() const {
+    assert(key.is_absolute());
     return key;
   }
   laddr_t get_laddr() const {
index f61c93e3ee80055fff89dd4c6b2d617edcbdd014..9a847a890270d414befdcaa2372e014ddc39a007 100644 (file)
@@ -292,8 +292,8 @@ public:
         ctx,
        leaf.node,
         leaf.node->modifications,
-        get_key(),
-        std::make_optional(get_val()),
+        is_end() ? min_max_t<node_key_t>::max : get_key(),
+        is_end() ? std::nullopt : std::make_optional(get_val()),
         leaf.pos);
     }
 
index 81da404d633f7324a498a29ec098d7aea9b6030d..33d8dfc3dbb50c1411ae8b4d0db3aae1a7dda97a 100644 (file)
@@ -146,6 +146,7 @@ BtreeLBAManager::get_mappings(
           cursors,
           [FNAME, this, c, laddr, length, &btree, &ret](auto& cursor)
         {
+         assert(!cursor->is_end());
           if (!cursor->is_indirect()) {
             ret.emplace_back(LBAMapping::create_direct(std::move(cursor)));
             TRACET("{}~0x{:x} got {}",
@@ -251,6 +252,7 @@ BtreeLBAManager::get_mapping(
     }
     return fut.si_then([FNAME, laddr, &btree, c, this,
                        search_containing](LBACursorRef cursor) {
+      assert(!cursor->is_end());
       if (!cursor->is_indirect()) {
         TRACET("{} got direct cursor {}",
                c.trans, laddr, *cursor);
@@ -1070,13 +1072,8 @@ BtreeLBAManager::_update_mapping(
        c,
        iter
       ).si_then([ret, c, laddr=cursor.key](auto iter) {
-       if (iter.is_end()) {
-         return update_mapping_ret_bare_t{
-           L_ADDR_NULL, std::move(ret), nullptr};
-       } else {
-         return update_mapping_ret_bare_t{
-           laddr, std::move(ret), iter.get_cursor(c)};
-       }
+       return update_mapping_ret_bare_t{
+         laddr, std::move(ret), iter.get_cursor(c)};
       });
     } else {
       return btree.update(
index 7b75d5790e1daf33faa5dfa505bc3cd5b7915745..797a511d3564e886c6e48bd5d6d2e37c5e1b694b 100644 (file)
@@ -134,9 +134,8 @@ public:
     pladdr_t addr;
     extent_len_t length = 0;
     LBAMapping mapping; // the mapping pointing to the updated lba entry if
-                       // refcount is non-zero; the next lba entry otherwise;
-                       // null mapping if the mapping is the last one and
-                       // is removed
+                       // refcount is non-zero; the next lba entry or the
+                       // end mapping otherwise.
     bool need_to_remove_extent() const {
       return refcount == 0 && addr.is_paddr() && !addr.get_paddr().is_zero();
     }
index 34d344a8e9d66404c10917a164032afb2db7d8be..458bd1323e35e074736d957827e82ee179fb94e8 100644 (file)
@@ -8,6 +8,9 @@ namespace crimson::os::seastore {
 
 std::ostream &operator<<(std::ostream &out, const LBAMapping &rhs)
 {
+  if (rhs.is_end()) {
+    return out << "LBAMapping(END)";
+  }
   out << "LBAMapping(" << rhs.get_key()
       << "~0x" << std::hex << rhs.get_length();
   if (rhs.is_complete()) {
index b57cf9ae13804642bd3707b8b8099ffbdb32badb..162c39c45ab95695c4a86439851dce673eda4d96 100644 (file)
@@ -21,6 +21,11 @@ class LBAMapping {
   {
     assert(!is_linked_direct() || !direct_cursor->is_indirect());
     assert(!indirect_cursor || indirect_cursor->is_indirect());
+    // if the mapping is indirect, it mustn't be at the end
+    if (is_indirect() && is_linked_direct()) {
+      assert((bool)direct_cursor->val
+           && direct_cursor->key != L_ADDR_NULL);
+    }
   }
 
 public:
@@ -45,6 +50,16 @@ public:
     return (bool)direct_cursor;
   }
 
+  bool is_end() const {
+    bool end = !is_indirect() && !direct_cursor->val;
+    // if the mapping is at the end, it can't be indirect and
+    // the physical cursor must be L_ADDR_NULL
+    assert(end
+      ? (!indirect_cursor && direct_cursor->key == L_ADDR_NULL)
+      : true);
+    return end;
+  }
+
   bool is_indirect() const {
     assert(!is_null());
     return (bool)indirect_cursor;
@@ -63,6 +78,7 @@ public:
   bool is_data_stable() const;
   bool is_clone() const {
     assert(is_linked_direct());
+    assert(!direct_cursor->is_end());
     return direct_cursor->get_refcount() > 1;
   }
   bool is_zero_reserved() const {
@@ -73,32 +89,39 @@ public:
   extent_len_t get_length() const {
     assert(!is_null());
     if (is_indirect()) {
+      assert(!indirect_cursor->is_end());
       return indirect_cursor->get_length();
     }
+    assert(!direct_cursor->is_end());
     return direct_cursor->get_length();
   }
 
   paddr_t get_val() const {
     assert(is_linked_direct());
+    assert(!direct_cursor->is_end());
     return direct_cursor->get_paddr();
   }
 
   checksum_t get_checksum() const {
     assert(is_linked_direct());
+    assert(!direct_cursor->is_end());
     return direct_cursor->get_checksum();
   }
 
   laddr_t get_key() const {
     assert(!is_null());
     if (is_indirect()) {
+      assert(!indirect_cursor->is_end());
       return indirect_cursor->get_laddr();
     }
+    assert(!direct_cursor->is_end());
     return direct_cursor->get_laddr();
   }
 
    // An lba pin may be indirect, see comments in lba/btree_lba_manager.h
   laddr_t get_intermediate_key() const {
     assert(is_indirect());
+    assert(!indirect_cursor->is_end());
     return indirect_cursor->get_intermediate_key();
   }
   laddr_t get_intermediate_base() const {
@@ -107,6 +130,7 @@ public:
   }
   extent_len_t get_intermediate_length() const {
     assert(is_linked_direct());
+    assert(!direct_cursor->is_end());
     return direct_cursor->get_length();
   }
   // The start offset of the indirect cursor related to direct cursor