summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-12-21 15:06:09 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2022-03-14 14:08:25 -0400
commit4e8f23e67aa1fe4706f53e058852c3c0d87223d7 (patch)
tree60f8f7262747795284ca5196265910a49e2fa850
parenta9318c09cd7197425d7fa035c1398132493ea27e (diff)
bcachefs: Fix for iterator not being traverse at commit timebcachefs-v4.19-backport-2022-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.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index e7816afe4a08..3723e845d5e3 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -695,17 +695,20 @@ static inline int btree_iter_pos_cmp(const struct btree_iter *l,
bkey_cmp(l->pos, r->pos);
}
-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 >= BTREE_ITER_MAX);
@@ -714,7 +717,7 @@ static void bch2_trans_update2(struct btree_trans *trans,
trans_for_each_update2(trans, i) {
if (btree_iter_pos_cmp(n.iter, i->iter) == 0) {
*i = n;
- return;
+ return 0;
}
if (btree_iter_pos_cmp(n.iter, i->iter) <= 0)
@@ -723,6 +726,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,
@@ -743,9 +747,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,
@@ -775,8 +779,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) {
@@ -790,8 +796,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);
@@ -805,8 +813,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);
@@ -914,7 +924,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;
}
}