Commit 912ad8b3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'bcachefs-2025-03-14' of git://evilpiepirate.org/bcachefs

Pull bcachefs hotfix from Kent Overstreet:
 "This one is high priority: a user hit an assertion in the upgrade to
  6.14, and we don't have a reproducer, so this changes the assertion to
  an emergency read-only with more info so we can debug it"

* tag 'bcachefs-2025-03-14' of git://evilpiepirate.org/bcachefs:
  bcachefs: Change btree wb assert to runtime error
parents b35233e7 90fd9ad5
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -126,10 +126,18 @@ bch2_trans_jset_entry_alloc(struct btree_trans *trans, unsigned u64s)

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

int bch2_btree_write_buffer_insert_err(struct btree_trans *,
				       enum btree_id, struct bkey_i *);

static inline int __must_check bch2_trans_update_buffered(struct btree_trans *trans,
					    enum btree_id btree,
					    struct bkey_i *k)
{
	if (unlikely(!btree_type_uses_write_buffer(btree))) {
		int ret = bch2_btree_write_buffer_insert_err(trans, btree, k);
		dump_stack();
		return ret;
	}
	/*
	 * Most updates skip the btree write buffer until journal replay is
	 * finished because synchronization with journal replay relies on having
+20 −1
Original line number Diff line number Diff line
@@ -264,6 +264,22 @@ static void move_keys_from_inc_to_flushing(struct btree_write_buffer *wb)
	BUG_ON(wb->sorted.size < wb->flushing.keys.nr);
}

int bch2_btree_write_buffer_insert_err(struct btree_trans *trans,
				       enum btree_id btree, struct bkey_i *k)
{
	struct bch_fs *c = trans->c;
	struct printbuf buf = PRINTBUF;

	prt_printf(&buf, "attempting to do write buffer update on non wb btree=");
	bch2_btree_id_to_text(&buf, btree);
	prt_str(&buf, "\n");
	bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(k));

	bch2_fs_inconsistent(c, "%s", buf.buf);
	printbuf_exit(&buf);
	return -EROFS;
}

static int bch2_btree_write_buffer_flush_locked(struct btree_trans *trans)
{
	struct bch_fs *c = trans->c;
@@ -312,7 +328,10 @@ static int bch2_btree_write_buffer_flush_locked(struct btree_trans *trans)
	darray_for_each(wb->sorted, i) {
		struct btree_write_buffered_key *k = &wb->flushing.keys.data[i->idx];

		BUG_ON(!btree_type_uses_write_buffer(k->btree));
		if (unlikely(!btree_type_uses_write_buffer(k->btree))) {
			ret = bch2_btree_write_buffer_insert_err(trans, k->btree, &k->k);
			goto err;
		}

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