diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2020-11-30 02:08:14 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2020-12-07 11:50:41 -0500 |
commit | b7d46b6ded97cdde4b32ef01765e1213d8f78dac (patch) | |
tree | c5d8e04bf485051cc51e5241b205e47eba323c5c | |
parent | b23987dc5529822b36d0f91e303dfccca2689ee1 (diff) |
bcachefs: Ensure we always have a journal pin in interior update path
For the new nodes an interior btree update makes reachable, updates to
those nodes may be journalled after the btree update starts but before
the transactional part - where we make those nodes reachable. Those
updates need to be kept in the journal until after the btree update
completes, hence we should always get a journal pin at the start of the
interior update.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/btree_update_interior.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c index 5143896e1b29..dc7b1342410e 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -544,6 +544,8 @@ static void btree_update_nodes_written(struct btree_update *as) unsigned i; int ret; + BUG_ON(!journal_pin_active(&as->journal)); + /* * We did an update to a parent node where the pointers we added pointed * to child nodes that weren't written yet: now, the child nodes have @@ -699,17 +701,7 @@ static void btree_update_reparent(struct btree_update *as, child->b = NULL; child->mode = BTREE_INTERIOR_UPDATING_AS; - /* - * When we write a new btree root, we have to drop our journal pin - * _before_ the new nodes are technically reachable; see - * btree_update_nodes_written(). - * - * This goes for journal pins that are recursively blocked on us - so, - * just transfer the journal pin to the new interior update so - * btree_update_nodes_written() can drop it. - */ bch2_journal_pin_copy(&c->journal, &as->journal, &child->journal, NULL); - bch2_journal_pin_drop(&c->journal, &child->journal); } static void btree_update_updated_root(struct btree_update *as, struct btree *b) @@ -956,6 +948,10 @@ bch2_btree_update_start(struct btree_trans *trans, enum btree_id id, if (ret) goto err; + bch2_journal_pin_add(&c->journal, + atomic64_read(&c->journal.seq), + &as->journal, NULL); + mutex_lock(&c->btree_interior_update_lock); list_add_tail(&as->list, &c->btree_interior_update_list); mutex_unlock(&c->btree_interior_update_lock); |