bcachefs: Topology error after insert is now an ERO

A user hit this, and this will naturally be easier to debug if we don't
panic.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet
2025-04-28 20:38:04 -04:00
parent 9a4a858c9b
commit dbe4674802
+32 -17
View File
@@ -1389,7 +1389,7 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as,
printbuf_exit(&buf);
}
static void
static int
bch2_btree_insert_keys_interior(struct btree_update *as,
struct btree_trans *trans,
struct btree_path *path,
@@ -1411,7 +1411,8 @@ bch2_btree_insert_keys_interior(struct btree_update *as,
insert = bkey_next(insert))
bch2_insert_fixup_btree_ptr(as, trans, path, b, &node_iter, insert);
if (bch2_btree_node_check_topology(trans, b)) {
int ret = bch2_btree_node_check_topology(trans, b);
if (ret) {
struct printbuf buf = PRINTBUF;
for (struct bkey_i *k = keys->keys;
@@ -1421,11 +1422,15 @@ bch2_btree_insert_keys_interior(struct btree_update *as,
prt_newline(&buf);
}
panic("%s(): check_topology error: inserted keys\n%s", __func__, buf.buf);
bch2_fs_fatal_error(as->c, "%ps -> %s(): check_topology error %s: inserted keys\n%s",
(void *) _RET_IP_, __func__, bch2_err_str(ret), buf.buf);
dump_stack();
return ret;
}
memmove_u64s_down(keys->keys, insert, keys->top_p - insert->_data);
keys->top_p -= insert->_data - keys->keys_p;
return 0;
}
static bool key_deleted_in_insert(struct keylist *insert_keys, struct bpos pos)
@@ -1559,11 +1564,11 @@ static void __btree_split_node(struct btree_update *as,
* nodes that were coalesced, and thus in the middle of a child node post
* coalescing:
*/
static void btree_split_insert_keys(struct btree_update *as,
struct btree_trans *trans,
btree_path_idx_t path_idx,
struct btree *b,
struct keylist *keys)
static int btree_split_insert_keys(struct btree_update *as,
struct btree_trans *trans,
btree_path_idx_t path_idx,
struct btree *b,
struct keylist *keys)
{
struct btree_path *path = trans->paths + path_idx;
@@ -1573,8 +1578,12 @@ static void btree_split_insert_keys(struct btree_update *as,
bch2_btree_node_iter_init(&node_iter, b, &bch2_keylist_front(keys)->k.p);
bch2_btree_insert_keys_interior(as, trans, path, b, node_iter, keys);
int ret = bch2_btree_insert_keys_interior(as, trans, path, b, node_iter, keys);
if (ret)
return ret;
}
return 0;
}
static int btree_split(struct btree_update *as, struct btree_trans *trans,
@@ -1607,8 +1616,10 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
__btree_split_node(as, trans, b, n, keys);
if (keys) {
btree_split_insert_keys(as, trans, path, n1, keys);
btree_split_insert_keys(as, trans, path, n2, keys);
ret = btree_split_insert_keys(as, trans, path, n1, keys) ?:
btree_split_insert_keys(as, trans, path, n2, keys);
if (ret)
goto err;
BUG_ON(!bch2_keylist_empty(keys));
}
@@ -1654,7 +1665,9 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
n3->sib_u64s[0] = U16_MAX;
n3->sib_u64s[1] = U16_MAX;
btree_split_insert_keys(as, trans, path, n3, &as->parent_keys);
ret = btree_split_insert_keys(as, trans, path, n3, &as->parent_keys);
if (ret)
goto err;
}
} else {
trace_and_count(c, btree_node_compact, trans, b);
@@ -1662,7 +1675,9 @@ static int btree_split(struct btree_update *as, struct btree_trans *trans,
n1 = bch2_btree_node_alloc_replacement(as, trans, b);
if (keys) {
btree_split_insert_keys(as, trans, path, n1, keys);
ret = btree_split_insert_keys(as, trans, path, n1, keys);
if (ret)
goto err;
BUG_ON(!bch2_keylist_empty(keys));
}
@@ -1809,15 +1824,15 @@ static int bch2_btree_insert_node(struct btree_update *as, struct btree_trans *t
goto split;
}
ret = bch2_btree_node_check_topology(trans, b);
ret = bch2_btree_node_check_topology(trans, b) ?:
bch2_btree_insert_keys_interior(as, trans, path, b,
path->l[b->c.level].iter, keys);
if (ret) {
bch2_btree_node_unlock_write(trans, path, b);
return ret;
}
bch2_btree_insert_keys_interior(as, trans, path, b,
path->l[b->c.level].iter, keys);
trans_for_each_path_with_node(trans, b, linked, i)
bch2_btree_node_iter_peek(&linked->l[b->c.level].iter, b);