Commit 5db43418 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Don't issue btree writes that weren't journalled

If we have an error in the btree interior update path that prevents us
from journalling the update, we can't issue the corresponding btree node
write - we didn't get a journal sequence number that would cause it to
be ignored in recovery.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent afa7cb0c
...@@ -1499,6 +1499,9 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b, ...@@ -1499,6 +1499,9 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b,
if (!btree_node_may_write(b)) if (!btree_node_may_write(b))
return; return;
if (old & (1 << BTREE_NODE_never_write))
return;
if (old & (1 << BTREE_NODE_write_in_flight)) { if (old & (1 << BTREE_NODE_write_in_flight)) {
btree_node_wait_on_io(b); btree_node_wait_on_io(b);
continue; continue;
...@@ -1545,6 +1548,8 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b, ...@@ -1545,6 +1548,8 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b,
seq = max(seq, le64_to_cpu(i->journal_seq)); seq = max(seq, le64_to_cpu(i->journal_seq));
} }
BUG_ON(b->written && !seq);
/* bch2_varint_decode may read up to 7 bytes past the end of the buffer: */ /* bch2_varint_decode may read up to 7 bytes past the end of the buffer: */
bytes += 8; bytes += 8;
......
...@@ -415,6 +415,7 @@ enum btree_flags { ...@@ -415,6 +415,7 @@ enum btree_flags {
BTREE_NODE_fake, BTREE_NODE_fake,
BTREE_NODE_old_extent_overwrite, BTREE_NODE_old_extent_overwrite,
BTREE_NODE_need_rewrite, BTREE_NODE_need_rewrite,
BTREE_NODE_never_write,
}; };
BTREE_FLAG(read_in_flight); BTREE_FLAG(read_in_flight);
...@@ -429,6 +430,7 @@ BTREE_FLAG(dying); ...@@ -429,6 +430,7 @@ BTREE_FLAG(dying);
BTREE_FLAG(fake); BTREE_FLAG(fake);
BTREE_FLAG(old_extent_overwrite); BTREE_FLAG(old_extent_overwrite);
BTREE_FLAG(need_rewrite); BTREE_FLAG(need_rewrite);
BTREE_FLAG(never_write);
static inline struct btree_write *btree_current_write(struct btree *b) static inline struct btree_write *btree_current_write(struct btree *b)
{ {
......
...@@ -603,17 +603,30 @@ static void btree_update_nodes_written(struct btree_update *as) ...@@ -603,17 +603,30 @@ static void btree_update_nodes_written(struct btree_update *as)
list_del(&as->write_blocked_list); list_del(&as->write_blocked_list);
if (!ret && as->b == b) { /*
* Node might have been freed, recheck under
* btree_interior_update_lock:
*/
if (as->b == b) {
struct bset *i = btree_bset_last(b); struct bset *i = btree_bset_last(b);
BUG_ON(!b->c.level); BUG_ON(!b->c.level);
BUG_ON(!btree_node_dirty(b)); BUG_ON(!btree_node_dirty(b));
i->journal_seq = cpu_to_le64( if (!ret) {
max(journal_seq, i->journal_seq = cpu_to_le64(
le64_to_cpu(i->journal_seq))); max(journal_seq,
le64_to_cpu(i->journal_seq)));
bch2_btree_add_journal_pin(c, b, journal_seq);
bch2_btree_add_journal_pin(c, b, journal_seq);
} else {
/*
* If we didn't get a journal sequence number we
* can't write this btree node, because recovery
* won't know to ignore this write:
*/
set_btree_node_never_write(b);
}
} }
mutex_unlock(&c->btree_interior_update_lock); mutex_unlock(&c->btree_interior_update_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment