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.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/libbcachefs/btree_update_leaf.c b/libbcachefs/btree_update_leaf.c
index cd23d7d..154a819 100644
--- a/libbcachefs/btree_update_leaf.c
+++ b/libbcachefs/btree_update_leaf.c
@@ -24,6 +24,28 @@
#include <linux/sort.h>
#include <trace/events/bcachefs.h>
+static void verify_update_old_key(struct btree_trans *trans, struct btree_insert_entry *i)
+{
+#ifdef CONFIG_BCACHEFS_DEBUG
+ struct bch_fs *c = trans->c;
+ struct bkey u;
+ struct bkey_s_c k = bch2_btree_path_peek_slot(i->path, &u);
+
+ if (unlikely(trans->journal_replay_not_finished)) {
+ struct bkey_i *j_k =
+ bch2_journal_keys_peek_slot(c, i->btree_id, i->level, i->k->k.p);
+
+ if (j_k)
+ k = bkey_i_to_s_c(j_k);
+ }
+
+ i->old_k.needs_whiteout = k.k->needs_whiteout;
+
+ BUG_ON(memcmp(&i->old_k, k.k, sizeof(struct bkey)));
+ BUG_ON(i->old_v != k.v);
+#endif
+}
+
static int __must_check
bch2_trans_update_by_path(struct btree_trans *, struct btree_path *,
struct bkey_i *, enum btree_update_flags);
@@ -341,6 +363,7 @@ btree_key_can_insert_cached(struct btree_trans *trans,
{
struct bch_fs *c = trans->c;
struct bkey_cached *ck = (void *) path->l[0].b;
+ struct btree_insert_entry *i;
unsigned new_u64s;
struct bkey_i *new_k;
@@ -368,6 +391,10 @@ btree_key_can_insert_cached(struct btree_trans *trans,
return -ENOMEM;
}
+ trans_for_each_update(trans, i)
+ if (i->old_v == &ck->k->v)
+ i->old_v = &new_k->v;
+
ck->u64s = new_u64s;
ck->k = new_k;
return 0;
@@ -383,6 +410,8 @@ static int run_one_mem_trigger(struct btree_trans *trans,
struct bkey_i *new = i->k;
int ret;
+ verify_update_old_key(trans, i);
+
if (unlikely(flags & BTREE_TRIGGER_NORUN))
return 0;
@@ -420,6 +449,8 @@ static int run_one_trans_trigger(struct btree_trans *trans, struct btree_insert_
struct bkey old_k = i->old_k;
struct bkey_s_c old = { &old_k, i->old_v };
+ verify_update_old_key(trans, i);
+
if ((i->flags & BTREE_TRIGGER_NORUN) ||
!(BTREE_NODE_TYPE_HAS_TRANS_TRIGGERS & (1U << i->bkey_type)))
return 0;
@@ -598,33 +629,6 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
if (btree_node_type_needs_gc(i->bkey_type))
marking = true;
-
- /*
- * Revalidate before calling mem triggers - XXX, ugly:
- *
- * - successful btree node splits don't cause transaction
- * restarts and will have invalidated the pointer to the bkey
- * value
- * - btree_node_lock_for_insert() -> btree_node_prep_for_write()
- * when it has to resort
- * - btree_key_can_insert_cached() when it has to reallocate
- *
- * Ugly because we currently have no way to tell if the
- * pointer's been invalidated, which means it's debatabale
- * whether we should be stashing the old key at all.
- */
- i->old_v = bch2_btree_path_peek_slot(i->path, &i->old_k).v;
-
- if (unlikely(trans->journal_replay_not_finished)) {
- struct bkey_i *j_k =
- bch2_journal_keys_peek_slot(c, i->btree_id, i->level,
- i->k->k.p);
-
- if (j_k) {
- i->old_k = j_k->k;
- i->old_v = &j_k->v;
- }
- }
}
/*
@@ -690,6 +694,8 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
if (i->key_cache_already_flushed)
continue;
+ verify_update_old_key(trans, i);
+
entry = bch2_journal_add_entry(j, &trans->journal_res,
BCH_JSET_ENTRY_overwrite,
i->btree_id, i->level,