bcachefs: Improve an insert path optimization

The insert path had an optimization to short circuit lookup
table/iterator fixups when overwriting an existing key with the same
size value - but it was incorrect when other key fields
(size/version) were changing. This is important for the upcoming rework
to have extent updates use the same insert path as regular keys.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2020-01-30 20:26:08 -05:00 committed by Kent Overstreet
parent 7d4aed1ea4
commit fdf2240033
2 changed files with 15 additions and 26 deletions

View file

@ -1189,7 +1189,8 @@ void bch2_bset_insert(struct btree *b,
memcpy_u64s(bkeyp_val(f, where), &insert->v, memcpy_u64s(bkeyp_val(f, where), &insert->v,
bkeyp_val_u64s(f, src)); bkeyp_val_u64s(f, src));
bch2_bset_fix_lookup_table(b, t, where, clobber_u64s, src->u64s); if (src->u64s != clobber_u64s)
bch2_bset_fix_lookup_table(b, t, where, clobber_u64s, src->u64s);
bch2_verify_btree_nr_keys(b); bch2_verify_btree_nr_keys(b);
} }

View file

@ -53,9 +53,8 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
struct btree_node_iter *node_iter, struct btree_node_iter *node_iter,
struct bkey_i *insert) struct bkey_i *insert)
{ {
const struct bkey_format *f = &b->format;
struct bkey_packed *k; struct bkey_packed *k;
unsigned clobber_u64s; unsigned clobber_u64s = 0, new_u64s = 0;
EBUG_ON(btree_node_just_written(b)); EBUG_ON(btree_node_just_written(b));
EBUG_ON(bset_written(b, btree_bset_last(b))); EBUG_ON(bset_written(b, btree_bset_last(b)));
@ -68,30 +67,25 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
k = NULL; k = NULL;
/* @k is the key being overwritten/deleted, if any: */ /* @k is the key being overwritten/deleted, if any: */
EBUG_ON(k && bkey_whiteout(k)); EBUG_ON(k && bkey_whiteout(k));
/* Deleting, but not found? nothing to do: */
if (bkey_whiteout(&insert->k) && !k)
return false;
if (bkey_whiteout(&insert->k)) { if (bkey_whiteout(&insert->k)) {
/* Deleting: */ /* Deleting: */
/* Not found? Nothing to do: */
if (!k)
return false;
btree_account_key_drop(b, k); btree_account_key_drop(b, k);
k->type = KEY_TYPE_deleted; k->type = KEY_TYPE_deleted;
if (k->needs_whiteout) { if (k->needs_whiteout)
push_whiteout(iter->trans->c, b, k); push_whiteout(iter->trans->c, b, k);
k->needs_whiteout = false; k->needs_whiteout = false;
}
if (k >= btree_bset_last(b)->start) { if (k >= btree_bset_last(b)->start) {
clobber_u64s = k->u64s; clobber_u64s = k->u64s;
bch2_bset_delete(b, k, clobber_u64s); bch2_bset_delete(b, k, clobber_u64s);
bch2_btree_node_iter_fix(iter, b, node_iter, k, goto fix_iter;
clobber_u64s, 0);
} else { } else {
bch2_btree_iter_fix_key_modified(iter, b, k); bch2_btree_iter_fix_key_modified(iter, b, k);
} }
@ -101,14 +95,6 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
if (k) { if (k) {
/* Overwriting: */ /* Overwriting: */
if (!bkey_written(b, k) &&
bkey_val_u64s(&insert->k) == bkeyp_val_u64s(f, k)) {
k->type = insert->k.type;
memcpy_u64s(bkeyp_val(f, k), &insert->v,
bkey_val_u64s(&insert->k));
return true;
}
btree_account_key_drop(b, k); btree_account_key_drop(b, k);
k->type = KEY_TYPE_deleted; k->type = KEY_TYPE_deleted;
@ -124,11 +110,13 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
} }
k = bch2_btree_node_iter_bset_pos(node_iter, b, bset_tree_last(b)); k = bch2_btree_node_iter_bset_pos(node_iter, b, bset_tree_last(b));
clobber_u64s = 0;
overwrite: overwrite:
bch2_bset_insert(b, node_iter, k, insert, clobber_u64s); bch2_bset_insert(b, node_iter, k, insert, clobber_u64s);
bch2_btree_node_iter_fix(iter, b, node_iter, k, new_u64s = k->u64s;
clobber_u64s, k->u64s); fix_iter:
if (clobber_u64s != new_u64s)
bch2_btree_node_iter_fix(iter, b, node_iter, k,
clobber_u64s, new_u64s);
return true; return true;
} }