From d9192d7d18dd313b20e8b2c5a8e0186431be5891 Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Tue, 7 Sep 2021 22:59:08 +0000 Subject: [PATCH] crimson/os/seastore/.../lba_btree: fix handle_split internal nodes Internal node pointers aren't actually allowed to point to end() -- that's specific to the leaf pointer. Fixes: https://tracker.ceph.com/issues/52532 Signed-off-by: Samuel Just --- .../seastore/lba_manager/btree/lba_btree.cc | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/crimson/os/seastore/lba_manager/btree/lba_btree.cc b/src/crimson/os/seastore/lba_manager/btree/lba_btree.cc index 828c787667d93..b12b346eab551 100644 --- a/src/crimson/os/seastore/lba_manager/btree/lba_btree.cc +++ b/src/crimson/os/seastore/lba_manager/btree/lba_btree.cc @@ -536,20 +536,7 @@ LBABtree::handle_split_ret LBABtree::handle_split( c.cache.retire_extent(c.trans, pos.node); - /* right->get_node_meta().begin == pivot == right->begin()->get_key() - * Thus, if pos.pos == left->get_size(), we want iter to point to - * left with pos.pos at the end rather than right with pos.pos = 0 - * since the insertion would be to the left of the first element - * of right and thus necessarily less than right->get_node_meta().begin. - */ - if (pos.pos <= left->get_size()) { - pos.node = left; - } else { - pos.node = right; - pos.pos -= left->get_size(); - - parent_pos.pos += 1; - } + return std::make_pair(left, right); }; for (; split_from > 0; --split_from) { @@ -563,11 +550,35 @@ LBABtree::handle_split_ret LBABtree::handle_split( if (split_from > 1) { auto &pos = iter.get_internal(split_from); DEBUGT("splitting internal {} at depth {}", c.trans, *pos.node, split_from); - split_level(parent_pos, pos); + auto [left, right] = split_level(parent_pos, pos); + + if (pos.pos < left->get_size()) { + pos.node = left; + } else { + pos.node = right; + pos.pos -= left->get_size(); + + parent_pos.pos += 1; + } } else { auto &pos = iter.leaf; DEBUGT("splitting leaf {}", c.trans, *pos.node); - split_level(parent_pos, pos); + auto [left, right] = split_level(parent_pos, pos); + + /* right->get_node_meta().begin == pivot == right->begin()->get_key() + * Thus, if pos.pos == left->get_size(), we want iter to point to + * left with pos.pos at the end rather than right with pos.pos = 0 + * since the insertion would be to the left of the first element + * of right and thus necessarily less than right->get_node_meta().begin. + */ + if (pos.pos <= left->get_size()) { + pos.node = left; + } else { + pos.node = right; + pos.pos -= left->get_size(); + + parent_pos.pos += 1; + } } } -- 2.39.5