diff options
Diffstat (limited to 'libbcachefs/btree_update_leaf.c')
-rw-r--r-- | libbcachefs/btree_update_leaf.c | 103 |
1 files changed, 53 insertions, 50 deletions
diff --git a/libbcachefs/btree_update_leaf.c b/libbcachefs/btree_update_leaf.c index 0df894fc..da8c6987 100644 --- a/libbcachefs/btree_update_leaf.c +++ b/libbcachefs/btree_update_leaf.c @@ -415,6 +415,25 @@ static inline int btree_trans_cmp(struct btree_insert_entry l, btree_iter_cmp(l.iter, r.iter); } +static bool btree_trans_relock(struct btree_insert *trans) +{ + struct btree_insert_entry *i; + + trans_for_each_iter(trans, i) + return bch2_btree_iter_relock(i->iter); + return true; +} + +static void btree_trans_unlock(struct btree_insert *trans) +{ + struct btree_insert_entry *i; + + trans_for_each_iter(trans, i) { + bch2_btree_iter_unlock(i->iter); + break; + } +} + /* Normal update interface: */ static enum btree_insert_ret @@ -466,49 +485,12 @@ static inline int do_btree_insert_at(struct btree_insert *trans, struct btree_iter *linked; unsigned u64s; int ret; - +retry: trans_for_each_iter(trans, i) BUG_ON(i->iter->uptodate >= BTREE_ITER_NEED_RELOCK); - /* reserve space for deferred updates */ - __trans_for_each_entry(trans, i, i->deferred) { - - } - memset(&trans->journal_res, 0, sizeof(trans->journal_res)); - 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 = NULL; - - trans_for_each_iter(trans, i) - iter = i->iter; - - if (iter) - bch2_btree_iter_unlock(iter); - - ret = bch2_journal_res_get(&c->journal, - &trans->journal_res, u64s, - JOURNAL_RES_GET_CHECK); - if (ret) - return ret; - - if (iter && !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); if (race_fault()) { @@ -536,6 +518,36 @@ static inline int do_btree_insert_at(struct btree_insert *trans, } } + if (likely(!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY))) { + u64s = 0; + trans_for_each_entry(trans, i) + u64s += jset_u64s(i->k->k.u64s); + + ret = bch2_journal_res_get(&c->journal, + &trans->journal_res, u64s, + JOURNAL_RES_GET_NONBLOCK); + if (likely(!ret)) + goto got_journal_res; + if (ret != -EAGAIN) + goto out; + + multi_unlock_write(trans); + btree_trans_unlock(trans); + + ret = bch2_journal_res_get(&c->journal, + &trans->journal_res, u64s, + JOURNAL_RES_GET_CHECK); + if (ret) + return ret; + + if (!btree_trans_relock(trans)) { + trans_restart(" (iter relock after journal res get blocked)"); + return -EINTR; + } + + goto retry; + } +got_journal_res: if (!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY)) { if (journal_seq_verify(c)) trans_for_each_entry(trans, i) @@ -623,6 +635,9 @@ int __bch2_btree_insert_at(struct btree_insert *trans) /* for the sake of sanity: */ BUG_ON(trans->nr > 1 && !(trans->flags & BTREE_INSERT_ATOMIC)); + if (trans->flags & BTREE_INSERT_GC_LOCK_HELD) + lockdep_assert_held(&c->gc_lock); + bubble_sort(trans->entries, trans->nr, btree_trans_cmp); trans_for_each_entry(trans, i) @@ -715,18 +730,6 @@ err: ret = -EINTR; } break; - case BTREE_INSERT_NEED_GC_LOCK: - ret = -EINTR; - - if (!down_read_trylock(&c->gc_lock)) { - if (flags & BTREE_INSERT_NOUNLOCK) - goto out; - - bch2_btree_iter_unlock(trans->entries[0].iter); - down_read(&c->gc_lock); - } - up_read(&c->gc_lock); - break; case BTREE_INSERT_ENOSPC: ret = -ENOSPC; break; |