bcachefs: Improve an insert path optimization
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 31 Jan 2020 01:26:08 +0000 (20:26 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:35 +0000 (17:08 -0400)
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>
fs/bcachefs/bset.c
fs/bcachefs/btree_update_leaf.c

index cff664ab75fae9d504a637bcc3d311383ca0172c..b8fe361978ef25d98d00b4e39057d542b3815371 100644 (file)
@@ -1189,7 +1189,8 @@ void bch2_bset_insert(struct btree *b,
        memcpy_u64s(bkeyp_val(f, where), &insert->v,
                    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);
 }
index baf97d785774ea284540cbd61e15db21e0e3fb16..9cf7075dd2657e19ea5f64e4b515b31918deee57 100644 (file)
@@ -53,9 +53,8 @@ bool bch2_btree_bset_insert_key(struct btree_iter *iter,
                                struct btree_node_iter *node_iter,
                                struct bkey_i *insert)
 {
-       const struct bkey_format *f = &b->format;
        struct bkey_packed *k;
-       unsigned clobber_u64s;
+       unsigned clobber_u64s = 0, new_u64s = 0;
 
        EBUG_ON(btree_node_just_written(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 is the key being overwritten/deleted, if any: */
-
        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)) {
                /* Deleting: */
-
-               /* Not found? Nothing to do: */
-               if (!k)
-                       return false;
-
                btree_account_key_drop(b, k);
                k->type = KEY_TYPE_deleted;
 
-               if (k->needs_whiteout) {
+               if (k->needs_whiteout)
                        push_whiteout(iter->trans->c, b, k);
-                       k->needs_whiteout = false;
-               }
+               k->needs_whiteout = false;
 
                if (k >= btree_bset_last(b)->start) {
                        clobber_u64s = k->u64s;
-
                        bch2_bset_delete(b, k, clobber_u64s);
-                       bch2_btree_node_iter_fix(iter, b, node_iter, k,
-                                                clobber_u64s, 0);
+                       goto fix_iter;
                } else {
                        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) {
                /* 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);
                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));
-       clobber_u64s = 0;
 overwrite:
        bch2_bset_insert(b, node_iter, k, insert, clobber_u64s);
-       bch2_btree_node_iter_fix(iter, b, node_iter, k,
-                                clobber_u64s, k->u64s);
+       new_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;
 }