diff options
Diffstat (limited to 'libbcachefs/btree_update_leaf.c')
-rw-r--r-- | libbcachefs/btree_update_leaf.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/libbcachefs/btree_update_leaf.c b/libbcachefs/btree_update_leaf.c index 288d7ca6..e8d6e078 100644 --- a/libbcachefs/btree_update_leaf.c +++ b/libbcachefs/btree_update_leaf.c @@ -343,19 +343,40 @@ static inline int do_btree_insert_at(struct btree_insert *trans, trans_for_each_entry(trans, i) BUG_ON(i->iter->uptodate >= BTREE_ITER_NEED_RELOCK); - u64s = 0; - trans_for_each_entry(trans, i) - u64s += jset_u64s(i->k->k.u64s); - memset(&trans->journal_res, 0, sizeof(trans->journal_res)); - ret = !(trans->flags & BTREE_INSERT_JOURNAL_REPLAY) - ? bch2_journal_res_get(&c->journal, - &trans->journal_res, - u64s, u64s) - : 0; - if (ret) - return ret; + if (likely(!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY))) { + u64s = 0; + trans_for_each_entry(trans, i) + u64s += jset_u64s(i->k->k.u64s); + + while ((ret = bch2_journal_res_get(&c->journal, + &trans->journal_res, u64s, + JOURNAL_RES_GET_NONBLOCK)) == -EAGAIN) { + struct btree_iter *iter = trans->entries[0].iter; + struct closure cl; + + bch2_btree_iter_unlock(iter); + + closure_init_stack(&cl); + + while ((ret = bch2_journal_open_seq_async(&c->journal, + trans->journal_res.seq, + &cl)) == -EAGAIN) + closure_sync(&cl); + + if (ret) + return ret; + + if (!bch2_btree_iter_relock(iter)) { + trans_restart(" (iter relock after journal res get blocked)"); + return -EINTR; + } + } + + if (ret) + return ret; + } multi_lock_write(c, trans); |