Skip to content

Commit 90fd9ad

Browse files
author
Kent Overstreet
committed
bcachefs: Change btree wb assert to runtime error
We just had a report of the assert for "btree in write buffer for non-write buffer btree" popping during the 6.14 upgrade. - 150TB filesystem, after a reboot the upgrade was able to continue from where it left off, so no major damage. But with 6.14 about to come out we want to get this tracked down asap, and need more data if other users hit this. Convert the BUG_ON() to an emergency read-only, and print out btree, the key itself, and stack trace from the original write buffer update (which did not have this check before). Reported-by: Stijn Tintel <stijn@linux-ipv6.be> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 9c18ea7 commit 90fd9ad

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

fs/bcachefs/btree_update.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,18 @@ bch2_trans_jset_entry_alloc(struct btree_trans *trans, unsigned u64s)
126126

127127
int bch2_btree_insert_clone_trans(struct btree_trans *, enum btree_id, struct bkey_i *);
128128

129+
int bch2_btree_write_buffer_insert_err(struct btree_trans *,
130+
enum btree_id, struct bkey_i *);
131+
129132
static inline int __must_check bch2_trans_update_buffered(struct btree_trans *trans,
130133
enum btree_id btree,
131134
struct bkey_i *k)
132135
{
136+
if (unlikely(!btree_type_uses_write_buffer(btree))) {
137+
int ret = bch2_btree_write_buffer_insert_err(trans, btree, k);
138+
dump_stack();
139+
return ret;
140+
}
133141
/*
134142
* Most updates skip the btree write buffer until journal replay is
135143
* finished because synchronization with journal replay relies on having

fs/bcachefs/btree_write_buffer.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,22 @@ static void move_keys_from_inc_to_flushing(struct btree_write_buffer *wb)
264264
BUG_ON(wb->sorted.size < wb->flushing.keys.nr);
265265
}
266266

267+
int bch2_btree_write_buffer_insert_err(struct btree_trans *trans,
268+
enum btree_id btree, struct bkey_i *k)
269+
{
270+
struct bch_fs *c = trans->c;
271+
struct printbuf buf = PRINTBUF;
272+
273+
prt_printf(&buf, "attempting to do write buffer update on non wb btree=");
274+
bch2_btree_id_to_text(&buf, btree);
275+
prt_str(&buf, "\n");
276+
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(k));
277+
278+
bch2_fs_inconsistent(c, "%s", buf.buf);
279+
printbuf_exit(&buf);
280+
return -EROFS;
281+
}
282+
267283
static int bch2_btree_write_buffer_flush_locked(struct btree_trans *trans)
268284
{
269285
struct bch_fs *c = trans->c;
@@ -312,7 +328,10 @@ static int bch2_btree_write_buffer_flush_locked(struct btree_trans *trans)
312328
darray_for_each(wb->sorted, i) {
313329
struct btree_write_buffered_key *k = &wb->flushing.keys.data[i->idx];
314330

315-
BUG_ON(!btree_type_uses_write_buffer(k->btree));
331+
if (unlikely(!btree_type_uses_write_buffer(k->btree))) {
332+
ret = bch2_btree_write_buffer_insert_err(trans, k->btree, &k->k);
333+
goto err;
334+
}
316335

317336
for (struct wb_key_ref *n = i + 1; n < min(i + 4, &darray_top(wb->sorted)); n++)
318337
prefetch(&wb->flushing.keys.data[n->idx]);

0 commit comments

Comments
 (0)