/*
* Can't be holding any read locks when we go to take write locks:
+ * another thread could be holding an intent lock on the same node we
+ * have a read lock on, and it'll block trying to take a write lock
+ * (because we hold a read lock) and it could be blocking us by holding
+ * its own read lock (while we're trying to to take write locks).
*
* note - this must be done after bch2_trans_journal_preres_get_cold()
* or anything else that might call bch2_trans_relock(), since that
*/
trans_for_each_iter(trans, iter) {
if (iter->nodes_locked != iter->nodes_intent_locked) {
- EBUG_ON(iter->flags & BTREE_ITER_KEEP_UNTIL_COMMIT);
- EBUG_ON(trans->iters_live & (1ULL << iter->idx));
- bch2_btree_iter_unlock_noinline(iter);
+ if ((iter->flags & BTREE_ITER_KEEP_UNTIL_COMMIT) ||
+ (trans->iters_live & (1ULL << iter->idx))) {
+ if (!bch2_btree_iter_upgrade(iter, 1)) {
+ trace_trans_restart_upgrade(trans->ip);
+ return -EINTR;
+ }
+ } else {
+ bch2_btree_iter_unlock_noinline(iter);
+ }
}
}