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.c108
1 files changed, 49 insertions, 59 deletions
diff --git a/libbcachefs/btree_update_leaf.c b/libbcachefs/btree_update_leaf.c
index e207b099..142230cf 100644
--- a/libbcachefs/btree_update_leaf.c
+++ b/libbcachefs/btree_update_leaf.c
@@ -50,25 +50,6 @@ static void btree_trans_unlock_write(struct btree_trans *trans)
bch2_btree_node_unlock_write(i->iter->l[0].b, i->iter);
}
-static bool btree_trans_relock(struct btree_trans *trans)
-{
- struct btree_insert_entry *i;
-
- trans_for_each_update_iter(trans, i)
- return bch2_btree_iter_relock(i->iter);
- return true;
-}
-
-static void btree_trans_unlock(struct btree_trans *trans)
-{
- struct btree_insert_entry *i;
-
- trans_for_each_update_iter(trans, i) {
- bch2_btree_iter_unlock(i->iter);
- break;
- }
-}
-
static inline int btree_trans_cmp(struct btree_insert_entry l,
struct btree_insert_entry r)
{
@@ -421,8 +402,6 @@ static inline void btree_insert_entry_checks(struct btree_trans *trans,
EBUG_ON((i->iter->flags & BTREE_ITER_IS_EXTENTS) &&
!(trans->flags & BTREE_INSERT_ATOMIC));
-
- bch2_btree_iter_verify_locks(i->iter);
}
BUG_ON(debug_check_bkeys(c) &&
@@ -450,14 +429,14 @@ static int bch2_trans_journal_preres_get(struct btree_trans *trans)
if (ret != -EAGAIN)
return ret;
- btree_trans_unlock(trans);
+ bch2_btree_trans_unlock(trans);
ret = bch2_journal_preres_get(&c->journal,
&trans->journal_preres, u64s, 0);
if (ret)
return ret;
- if (!btree_trans_relock(trans)) {
+ if (!bch2_btree_trans_relock(trans)) {
trans_restart(" (iter relock after journal preres get blocked)");
return -EINTR;
}
@@ -616,12 +595,9 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
* have been traversed/locked, depending on what the caller was
* doing:
*/
- trans_for_each_update_iter(trans, i) {
- for_each_btree_iter(i->iter, linked)
- if (linked->uptodate < BTREE_ITER_NEED_RELOCK)
- linked->flags |= BTREE_ITER_NOUNLOCK;
- break;
- }
+ trans_for_each_iter(trans, linked)
+ if (linked->uptodate < BTREE_ITER_NEED_RELOCK)
+ linked->flags |= BTREE_ITER_NOUNLOCK;
}
trans_for_each_update_iter(trans, i)
@@ -706,20 +682,20 @@ int bch2_trans_commit_error(struct btree_trans *trans,
return ret;
}
- if (btree_trans_relock(trans))
+ if (bch2_btree_trans_relock(trans))
return 0;
trans_restart(" (iter relock after marking replicas)");
ret = -EINTR;
break;
case BTREE_INSERT_NEED_JOURNAL_RES:
- btree_trans_unlock(trans);
+ bch2_btree_trans_unlock(trans);
ret = bch2_trans_journal_res_get(trans, JOURNAL_RES_GET_CHECK);
if (ret)
return ret;
- if (btree_trans_relock(trans))
+ if (bch2_btree_trans_relock(trans))
return 0;
trans_restart(" (iter relock after journal res get blocked)");
@@ -731,14 +707,11 @@ int bch2_trans_commit_error(struct btree_trans *trans,
}
if (ret == -EINTR) {
- trans_for_each_update_iter(trans, i) {
- int ret2 = bch2_btree_iter_traverse(i->iter);
- if (ret2) {
- trans_restart(" (traverse)");
- return ret2;
- }
+ int ret2 = bch2_btree_iter_traverse_all(trans);
- BUG_ON(i->iter->uptodate > BTREE_ITER_NEED_PEEK);
+ if (ret2) {
+ trans_restart(" (traverse)");
+ return ret2;
}
/*
@@ -784,10 +757,9 @@ static int __bch2_trans_commit(struct btree_trans *trans,
goto err;
}
- if (i->iter->flags & BTREE_ITER_ERROR) {
- ret = -EIO;
+ ret = btree_iter_err(i->iter);
+ if (ret)
goto err;
- }
}
ret = do_btree_insert_at(trans, stopped_at);
@@ -801,16 +773,10 @@ static int __bch2_trans_commit(struct btree_trans *trans,
bch2_btree_iter_downgrade(i->iter);
err:
/* make sure we didn't drop or screw up locks: */
- trans_for_each_update_iter(trans, i) {
- bch2_btree_iter_verify_locks(i->iter);
- break;
- }
+ bch2_btree_trans_verify_locks(trans);
- trans_for_each_update_iter(trans, i) {
- for_each_btree_iter(i->iter, linked)
- linked->flags &= ~BTREE_ITER_NOUNLOCK;
- break;
- }
+ trans_for_each_iter(trans, linked)
+ linked->flags &= ~BTREE_ITER_NOUNLOCK;
return ret;
}
@@ -842,17 +808,16 @@ int bch2_trans_commit(struct btree_trans *trans,
trans->journal_seq = journal_seq;
trans->flags = flags;
- bubble_sort(trans->updates, trans->nr_updates, btree_trans_cmp);
-
trans_for_each_update(trans, i)
btree_insert_entry_checks(trans, i);
+ bch2_btree_trans_verify_locks(trans);
if (unlikely(!(trans->flags & BTREE_INSERT_NOCHECK_RW) &&
!percpu_ref_tryget(&c->writes))) {
if (likely(!(trans->flags & BTREE_INSERT_LAZY_RW)))
return -EROFS;
- btree_trans_unlock(trans);
+ bch2_btree_trans_unlock(trans);
ret = bch2_fs_read_write_early(c);
if (ret)
@@ -860,7 +825,7 @@ int bch2_trans_commit(struct btree_trans *trans,
percpu_ref_get(&c->writes);
- if (!btree_trans_relock(trans)) {
+ if (!bch2_btree_trans_relock(trans)) {
ret = -EINTR;
goto err;
}
@@ -885,10 +850,15 @@ out_noupdates:
trans->commit_start = 0;
}
- trans->nr_updates = 0;
-
BUG_ON(!(trans->flags & BTREE_INSERT_ATOMIC) && ret == -EINTR);
+ bch2_trans_unlink_iters(trans, trans->iters_unlink_on_commit);
+ if (!ret) {
+ bch2_trans_unlink_iters(trans, ~trans->iters_touched);
+ trans->iters_touched = 0;
+ }
+ trans->nr_updates = 0;
+
return ret;
err:
ret = bch2_trans_commit_error(trans, i, ret);
@@ -898,6 +868,26 @@ err:
goto out;
}
+struct btree_insert_entry *bch2_trans_update(struct btree_trans *trans,
+ struct btree_insert_entry entry)
+{
+ struct btree_insert_entry *i;
+
+ BUG_ON(trans->nr_updates >= trans->nr_iters + 4);
+
+ for (i = trans->updates;
+ i < trans->updates + trans->nr_updates;
+ i++)
+ if (btree_trans_cmp(entry, *i) < 0)
+ break;
+
+ memmove(&i[1], &i[0],
+ (void *) &trans->updates[trans->nr_updates] - (void *) i);
+ trans->nr_updates++;
+ *i = entry;
+ return i;
+}
+
int bch2_btree_delete_at(struct btree_trans *trans,
struct btree_iter *iter, unsigned flags)
{
@@ -960,7 +950,7 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
iter = bch2_trans_get_iter(&trans, id, start, BTREE_ITER_INTENT);
while ((k = bch2_btree_iter_peek(iter)).k &&
- !(ret = btree_iter_err(k)) &&
+ !(ret = bkey_err(k)) &&
bkey_cmp(iter->pos, end) < 0) {
unsigned max_sectors = KEY_SIZE_MAX & (~0 << c->block_bits);
/* really shouldn't be using a bare, unpadded bkey_i */
@@ -997,7 +987,7 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
if (ret)
break;
- bch2_btree_iter_cond_resched(iter);
+ bch2_trans_cond_resched(&trans);
}
bch2_trans_exit(&trans);