Skip to content

Commit cec136d

Browse files
author
Kent Overstreet
committed
bcachefs: Fix topology errors on split after merge
If a btree split picks a pivot that's being deleted by a btree node merge, we're going to have problems. Fix this by checking if the pivot is being deleted, the same as we check for deletions in journal replay keys. Found by single_devic.ktest small_nodes. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent d335bb3 commit cec136d

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

fs/bcachefs/btree_update_interior.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,14 +1434,24 @@ bch2_btree_insert_keys_interior(struct btree_update *as,
14341434
}
14351435
}
14361436

1437+
static bool key_deleted_in_insert(struct keylist *insert_keys, struct bpos pos)
1438+
{
1439+
if (insert_keys)
1440+
for_each_keylist_key(insert_keys, k)
1441+
if (bkey_deleted(&k->k) && bpos_eq(k->k.p, pos))
1442+
return true;
1443+
return false;
1444+
}
1445+
14371446
/*
14381447
* Move keys from n1 (original replacement node, now lower node) to n2 (higher
14391448
* node)
14401449
*/
14411450
static void __btree_split_node(struct btree_update *as,
14421451
struct btree_trans *trans,
14431452
struct btree *b,
1444-
struct btree *n[2])
1453+
struct btree *n[2],
1454+
struct keylist *insert_keys)
14451455
{
14461456
struct bkey_packed *k;
14471457
struct bpos n1_pos = POS_MIN;
@@ -1476,7 +1486,8 @@ static void __btree_split_node(struct btree_update *as,
14761486
if (b->c.level &&
14771487
u64s < n1_u64s &&
14781488
u64s + k->u64s >= n1_u64s &&
1479-
bch2_key_deleted_in_journal(trans, b->c.btree_id, b->c.level, uk.p))
1489+
(bch2_key_deleted_in_journal(trans, b->c.btree_id, b->c.level, uk.p) ||
1490+
key_deleted_in_insert(insert_keys, uk.p)))
14801491
n1_u64s += k->u64s;
14811492

14821493
i = u64s >= n1_u64s;
@@ -1603,7 +1614,7 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
16031614
n[0] = n1 = bch2_btree_node_alloc(as, trans, b->c.level);
16041615
n[1] = n2 = bch2_btree_node_alloc(as, trans, b->c.level);
16051616

1606-
__btree_split_node(as, trans, b, n);
1617+
__btree_split_node(as, trans, b, n, keys);
16071618

16081619
if (keys) {
16091620
btree_split_insert_keys(as, trans, path, n1, keys);

0 commit comments

Comments
 (0)