summaryrefslogtreecommitdiff
path: root/libbcachefs/btree_update_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/btree_update_leaf.c')
-rw-r--r--libbcachefs/btree_update_leaf.c43
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);