]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/.../lba_btree: fix handle_split internal nodes 43083/head
authorSamuel Just <sjust@redhat.com>
Tue, 7 Sep 2021 22:59:08 +0000 (22:59 +0000)
committerSamuel Just <sjust@redhat.com>
Tue, 7 Sep 2021 23:55:27 +0000 (16:55 -0700)
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 <sjust@redhat.com>
src/crimson/os/seastore/lba_manager/btree/lba_btree.cc

index 828c787667d93ab7a6d0a4370d157a705784a931..b12b346eab551930a33679a0a763936ef9e2ebe3 100644 (file)
@@ -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;
+      }
     }
   }