From: Xuehan Xu Date: Sun, 16 Mar 2025 03:45:26 +0000 (+0800) Subject: crimson/os/seastore/btree: allow BtreeCursor to represent the end of the X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=721350e659bd5f17ae418874669313bfbc569899;p=ceph.git crimson/os/seastore/btree: allow BtreeCursor to represent the end of the tree Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/os/seastore/btree/btree_types.h b/src/crimson/os/seastore/btree/btree_types.h index 87f4e72bb164..fb4e465a05dd 100644 --- a/src/crimson/os/seastore/btree/btree_types.h +++ b/src/crimson/os/seastore/btree/btree_types.h @@ -253,8 +253,7 @@ struct LBACursor : BtreeCursor { using Base = BtreeCursor; 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 { using Base = BtreeCursor; using Base::BtreeCursor; paddr_t get_paddr() const { + assert(key.is_absolute()); return key; } laddr_t get_laddr() const { diff --git a/src/crimson/os/seastore/btree/fixed_kv_btree.h b/src/crimson/os/seastore/btree/fixed_kv_btree.h index f61c93e3ee80..9a847a890270 100644 --- a/src/crimson/os/seastore/btree/fixed_kv_btree.h +++ b/src/crimson/os/seastore/btree/fixed_kv_btree.h @@ -292,8 +292,8 @@ public: ctx, leaf.node, leaf.node->modifications, - get_key(), - std::make_optional(get_val()), + is_end() ? min_max_t::max : get_key(), + is_end() ? std::nullopt : std::make_optional(get_val()), leaf.pos); } diff --git a/src/crimson/os/seastore/lba/btree_lba_manager.cc b/src/crimson/os/seastore/lba/btree_lba_manager.cc index 81da404d633f..33d8dfc3dbb5 100644 --- a/src/crimson/os/seastore/lba/btree_lba_manager.cc +++ b/src/crimson/os/seastore/lba/btree_lba_manager.cc @@ -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( diff --git a/src/crimson/os/seastore/lba_manager.h b/src/crimson/os/seastore/lba_manager.h index 7b75d5790e1d..797a511d3564 100644 --- a/src/crimson/os/seastore/lba_manager.h +++ b/src/crimson/os/seastore/lba_manager.h @@ -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(); } diff --git a/src/crimson/os/seastore/lba_mapping.cc b/src/crimson/os/seastore/lba_mapping.cc index 34d344a8e9d6..458bd1323e35 100644 --- a/src/crimson/os/seastore/lba_mapping.cc +++ b/src/crimson/os/seastore/lba_mapping.cc @@ -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()) { diff --git a/src/crimson/os/seastore/lba_mapping.h b/src/crimson/os/seastore/lba_mapping.h index b57cf9ae1380..162c39c45ab9 100644 --- a/src/crimson/os/seastore/lba_mapping.h +++ b/src/crimson/os/seastore/lba_mapping.h @@ -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