diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-12-21 15:06:09 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2021-12-23 16:59:03 -0500 |
commit | e027d73ebc0ed5b0c28868f6612a275ea8f092de (patch) | |
tree | df9f5590a11ab031c054b7351e9501447131aa6a | |
parent | 7d679fb274b1a05bf06894c681e7ab6393f4742f (diff) |
bcachefs: Fix for iterator not being traverse at commit timebcachefs-v4.19-backport-2019-hotfix
Custumer system is hitting a BUG_ON() at btree_update_leaf +692: btree
iterator is not uptodate, meaning we dropped locks somewhere.
A proper backported fix is not possible, but we can re-traverse the
iterator, ensuring it is uptodate before calling bch2_trans_commit().
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index cd699c257244..af408861a5d4 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -679,17 +679,20 @@ bch2_trans_commit_get_rw_cold(struct btree_trans *trans) return 0; } -static void bch2_trans_update2(struct btree_trans *trans, - struct btree_iter *iter, - struct bkey_i *insert) +static int bch2_trans_update2(struct btree_trans *trans, + struct btree_iter *iter, + struct bkey_i *insert) { struct btree_insert_entry *i, n = (struct btree_insert_entry) { .iter = iter, .k = insert }; + int ret; btree_insert_entry_checks(trans, n.iter, n.k); - BUG_ON(iter->uptodate > BTREE_ITER_NEED_PEEK); + ret = bch2_btree_iter_traverse(iter); + if (ret) + return ret; EBUG_ON(trans->nr_updates2 >= trans->nr_iters); @@ -698,7 +701,7 @@ static void bch2_trans_update2(struct btree_trans *trans, trans_for_each_update2(trans, i) { if (btree_iter_cmp(n.iter, i->iter) == 0) { *i = n; - return; + return 0; } if (btree_iter_cmp(n.iter, i->iter) <= 0) @@ -707,6 +710,7 @@ static void bch2_trans_update2(struct btree_trans *trans, array_insert_item(trans->updates2, trans->nr_updates2, i - trans->updates2, n); + return 0; } static int extent_update_to_keys(struct btree_trans *trans, @@ -729,9 +733,9 @@ static int extent_update_to_keys(struct btree_trans *trans, iter->flags |= BTREE_ITER_INTENT; __bch2_btree_iter_set_pos(iter, insert->k.p, false); - bch2_trans_update2(trans, iter, insert); + ret = bch2_trans_update2(trans, iter, insert); bch2_trans_iter_put(trans, iter); - return 0; + return ret; } static int extent_handle_overwrites(struct btree_trans *trans, @@ -767,8 +771,10 @@ static int extent_handle_overwrites(struct btree_trans *trans, bch2_cut_back(start, update); __bch2_btree_iter_set_pos(update_iter, update->k.p, false); - bch2_trans_update2(trans, update_iter, update); + ret = bch2_trans_update2(trans, update_iter, update); bch2_trans_iter_put(trans, update_iter); + if (ret) + goto err; } if (bkey_cmp(k.k->p, end) > 0) { @@ -784,8 +790,10 @@ static int extent_handle_overwrites(struct btree_trans *trans, bch2_cut_front(end, update); __bch2_btree_iter_set_pos(update_iter, update->k.p, false); - bch2_trans_update2(trans, update_iter, update); + ret = bch2_trans_update2(trans, update_iter, update); bch2_trans_iter_put(trans, update_iter); + if (ret) + goto err; } else { update_iter = bch2_trans_copy_iter(trans, iter); if ((ret = PTR_ERR_OR_ZERO(update_iter))) @@ -801,8 +809,10 @@ static int extent_handle_overwrites(struct btree_trans *trans, update->k.size = 0; __bch2_btree_iter_set_pos(update_iter, update->k.p, false); - bch2_trans_update2(trans, update_iter, update); + ret = bch2_trans_update2(trans, update_iter, update); bch2_trans_iter_put(trans, update_iter); + if (ret) + goto err; } k = bch2_btree_iter_next_with_updates(iter); @@ -912,7 +922,9 @@ int __bch2_trans_commit(struct btree_trans *trans) if (ret) goto out; } else { - bch2_trans_update2(trans, i->iter, i->k); + ret = bch2_trans_update2(trans, i->iter, i->k); + if (ret) + goto out; } } |