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.c103
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;