mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2026-02-01 15:18:50 +00:00
bcachefs: Fix btree lock being incorrectly dropped
__btree_trans_get_iter() was using bch2_btree_iter_upgrade, but it shouldn't have been because on failure bch2_btree_iter_upgrade may drop locks in other iterators, expecting the transaction to be restarted. But __btree_trans_get_iter can't return an error to indicate that we need to restart thet transaction - oops. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
e323edd6d3
commit
07bd4c285b
@ -2124,9 +2124,12 @@ static struct btree_iter *__btree_trans_get_iter(struct btree_trans *trans,
|
||||
iter->flags &= ~BTREE_ITER_USER_FLAGS;
|
||||
iter->flags |= flags & BTREE_ITER_USER_FLAGS;
|
||||
|
||||
if (iter->flags & BTREE_ITER_INTENT)
|
||||
bch2_btree_iter_upgrade(iter, 1);
|
||||
else
|
||||
if (iter->flags & BTREE_ITER_INTENT) {
|
||||
if (!iter->locks_want) {
|
||||
__bch2_btree_iter_unlock(iter);
|
||||
iter->locks_want = 1;
|
||||
}
|
||||
} else
|
||||
bch2_btree_iter_downgrade(iter);
|
||||
|
||||
BUG_ON(iter->btree_id != btree_id);
|
||||
|
||||
@ -869,8 +869,8 @@ int __bch2_trans_commit(struct btree_trans *trans)
|
||||
trans_trigger_run = false;
|
||||
|
||||
trans_for_each_update(trans, i) {
|
||||
if (unlikely(i->iter->uptodate > BTREE_ITER_NEED_PEEK &&
|
||||
(ret = bch2_btree_iter_traverse(i->iter)))) {
|
||||
ret = bch2_btree_iter_traverse(i->iter);
|
||||
if (unlikely(ret)) {
|
||||
trace_trans_restart_traverse(trans->ip);
|
||||
goto out;
|
||||
}
|
||||
@ -879,8 +879,8 @@ int __bch2_trans_commit(struct btree_trans *trans)
|
||||
* We're not using bch2_btree_iter_upgrade here because
|
||||
* we know trans->nounlock can't be set:
|
||||
*/
|
||||
if (unlikely(i->iter->locks_want < 1 &&
|
||||
!__bch2_btree_iter_upgrade(i->iter, 1))) {
|
||||
if (unlikely(!btree_node_intent_locked(i->iter, i->iter->level) &&
|
||||
!__bch2_btree_iter_upgrade(i->iter, i->iter->level + 1))) {
|
||||
trace_trans_restart_upgrade(trans->ip);
|
||||
ret = -EINTR;
|
||||
goto out;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user