]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_trans_commit.c
btree_write_buffer: ensure atomic64_sub_return_release availability
[bcachefs-tools-debian] / libbcachefs / btree_trans_commit.c
index 83cc7f64c57c9841ed1b288a57f0c271adb3428d..32693f7c6221043d0c28b07e57f1b396bd845582 100644 (file)
@@ -97,6 +97,7 @@ bool bch2_btree_bset_insert_key(struct btree_trans *trans,
        EBUG_ON(bpos_gt(insert->k.p, b->data->max_key));
        EBUG_ON(insert->k.u64s >
                bch_btree_keys_u64s_remaining(trans->c, b));
+       EBUG_ON(!b->c.level && !bpos_eq(insert->k.p, path->pos));
 
        k = bch2_btree_node_iter_peek_all(node_iter, b);
        if (k && bkey_cmp_left_packed(b, k, &insert->k.p))
@@ -162,13 +163,11 @@ static int __btree_node_flush(struct journal *j, struct journal_entry_pin *pin,
        struct bch_fs *c = container_of(j, struct bch_fs, journal);
        struct btree_write *w = container_of(pin, struct btree_write, journal);
        struct btree *b = container_of(w, struct btree, writes[i]);
-       struct btree_trans trans;
+       struct btree_trans *trans = bch2_trans_get(c);
        unsigned long old, new, v;
        unsigned idx = w - b->writes;
 
-       bch2_trans_init(&trans, c, 0, 0);
-
-       btree_node_lock_nopath_nofail(&trans, &b->c, SIX_LOCK_read);
+       btree_node_lock_nopath_nofail(trans, &b->c, SIX_LOCK_read);
        v = READ_ONCE(b->flags);
 
        do {
@@ -187,7 +186,7 @@ static int __btree_node_flush(struct journal *j, struct journal_entry_pin *pin,
        btree_node_write_if_need(c, b, SIX_LOCK_read);
        six_unlock_read(&b->c.lock);
 
-       bch2_trans_exit(&trans);
+       bch2_trans_put(trans);
        return 0;
 }
 
@@ -213,7 +212,11 @@ inline void bch2_btree_add_journal_pin(struct bch_fs *c,
 }
 
 /**
- * btree_insert_key - insert a key one key into a leaf node
+ * bch2_btree_insert_key_leaf() - insert a key one key into a leaf node
+ * @trans:             btree transaction object
+ * @path:              path pointing to @insert's pos
+ * @insert:            key to insert
+ * @journal_seq:       sequence number of journal reservation
  */
 inline void bch2_btree_insert_key_leaf(struct btree_trans *trans,
                                       struct btree_path *path,
@@ -346,7 +349,7 @@ static int btree_key_can_insert_cached(struct btree_trans *trans, unsigned flags
        new_k           = krealloc(ck->k, new_u64s * sizeof(u64), GFP_NOFS);
        if (!new_k) {
                bch_err(c, "error allocating memory for key cache key, btree %s u64s %u",
-                       bch2_btree_ids[path->btree_id], new_u64s);
+                       bch2_btree_id_str(path->btree_id), new_u64s);
                return -BCH_ERR_ENOMEM_btree_key_cache_insert;
        }
 
@@ -376,11 +379,10 @@ static int run_one_mem_trigger(struct btree_trans *trans,
        if (unlikely(flags & BTREE_TRIGGER_NORUN))
                return 0;
 
-       if (!btree_node_type_needs_gc((enum btree_node_type) i->btree_id))
+       if (!btree_node_type_needs_gc(__btree_node_type(i->level, i->btree_id)))
                return 0;
 
-       if (old_ops->atomic_trigger == new_ops->atomic_trigger &&
-           ((1U << old.k->type) & BTREE_TRIGGER_WANTS_OLD_AND_NEW)) {
+       if (old_ops->atomic_trigger == new_ops->atomic_trigger) {
                ret   = bch2_mark_key(trans, i->btree_id, i->level,
                                old, bkey_i_to_s_c(new),
                                BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE|flags);
@@ -422,8 +424,7 @@ static int run_one_trans_trigger(struct btree_trans *trans, struct btree_insert_
 
        if (!i->insert_trigger_run &&
            !i->overwrite_trigger_run &&
-           old_ops->trans_trigger == new_ops->trans_trigger &&
-           ((1U << old.k->type) & BTREE_TRIGGER_WANTS_OLD_AND_NEW)) {
+           old_ops->trans_trigger == new_ops->trans_trigger) {
                i->overwrite_trigger_run = true;
                i->insert_trigger_run = true;
                return bch2_trans_mark_key(trans, i->btree_id, i->level, old, i->k,
@@ -554,7 +555,6 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
        struct btree_write_buffered_key *wb;
        struct btree_trans_commit_hook *h;
        unsigned u64s = 0;
-       bool marking = false;
        int ret;
 
        if (race_fault()) {
@@ -583,9 +583,6 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
                        *stopped_at = i;
                        return ret;
                }
-
-               if (btree_node_type_needs_gc(i->bkey_type))
-                       marking = true;
        }
 
        if (trans->nr_wb_updates &&
@@ -684,7 +681,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
                                                       BCH_JSET_ENTRY_overwrite,
                                                       i->btree_id, i->level,
                                                       i->old_k.u64s);
-                               bkey_reassemble(&entry->start[0],
+                               bkey_reassemble((struct bkey_i *) entry->start,
                                                (struct bkey_s_c) { &i->old_k, i->old_v });
                        }
 
@@ -692,7 +689,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
                                               BCH_JSET_ENTRY_btree_keys,
                                               i->btree_id, i->level,
                                               i->k->k.u64s);
-                       bkey_copy(&entry->start[0], i->k);
+                       bkey_copy((struct bkey_i *) entry->start, i->k);
                }
 
                trans_for_each_wb_update(trans, wb) {
@@ -700,7 +697,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, unsigned flags,
                                               BCH_JSET_ENTRY_btree_keys,
                                               wb->btree, 0,
                                               wb->k.k.u64s);
-                       bkey_copy(&entry->start[0], &wb->k);
+                       bkey_copy((struct bkey_i *) entry->start, &wb->k);
                }
 
                if (trans->journal_seq)
@@ -777,13 +774,12 @@ static noinline void bch2_drop_overwrites_from_journal(struct btree_trans *trans
                bch2_journal_key_overwritten(trans->c, wb->btree, 0, wb->k.k.p);
 }
 
-#ifdef CONFIG_BCACHEFS_DEBUG
-static noinline int bch2_trans_commit_bkey_invalid(struct btree_trans *trans, unsigned flags,
+static noinline int bch2_trans_commit_bkey_invalid(struct btree_trans *trans,
+                                                  enum bkey_invalid_flags flags,
                                                   struct btree_insert_entry *i,
                                                   struct printbuf *err)
 {
        struct bch_fs *c = trans->c;
-       int rw = (flags & BTREE_INSERT_JOURNAL_REPLAY) ? READ : WRITE;
 
        printbuf_reset(err);
        prt_printf(err, "invalid bkey on insert from %s -> %ps",
@@ -794,17 +790,14 @@ static noinline int bch2_trans_commit_bkey_invalid(struct btree_trans *trans, un
        bch2_bkey_val_to_text(err, c, bkey_i_to_s_c(i->k));
        prt_newline(err);
 
-       bch2_bkey_invalid(c, bkey_i_to_s_c(i->k),
-                         i->bkey_type, rw, err);
+       bch2_bkey_invalid(c, bkey_i_to_s_c(i->k), i->bkey_type, flags, err);
        bch2_print_string_as_lines(KERN_ERR, err->buf);
 
        bch2_inconsistent_error(c);
        bch2_dump_trans_updates(trans);
-       printbuf_exit(err);
 
        return -EINVAL;
 }
-#endif
 
 /*
  * Get journal reservation, take write locks, and attempt to do btree update(s):
@@ -817,25 +810,6 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans, unsigned flags
        struct btree_insert_entry *i;
        int ret = 0, u64s_delta = 0;
 
-#ifdef CONFIG_BCACHEFS_DEBUG
-       trans_for_each_update(trans, i) {
-               struct printbuf buf = PRINTBUF;
-               enum bkey_invalid_flags invalid_flags = 0;
-
-               if (!(flags & BTREE_INSERT_JOURNAL_REPLAY))
-                       invalid_flags |= BKEY_INVALID_WRITE|BKEY_INVALID_COMMIT;
-
-               if (unlikely(bch2_bkey_invalid(c, bkey_i_to_s_c(i->k),
-                                              i->bkey_type, invalid_flags, &buf)))
-                       ret = bch2_trans_commit_bkey_invalid(trans, flags, i, &buf);
-               btree_insert_entry_checks(trans, i);
-               printbuf_exit(&buf);
-
-               if (ret)
-                       return ret;
-       }
-#endif
-
        trans_for_each_update(trans, i) {
                if (i->cached)
                        continue;
@@ -887,12 +861,7 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans, unsigned flags
         */
        bch2_journal_res_put(&c->journal, &trans->journal_res);
 
-       if (unlikely(ret))
-               return ret;
-
-       bch2_trans_downgrade(trans);
-
-       return 0;
+       return ret;
 }
 
 static int journal_reclaim_wait_done(struct bch_fs *c)
@@ -1048,6 +1017,23 @@ int __bch2_trans_commit(struct btree_trans *trans, unsigned flags)
        if (ret)
                goto out_reset;
 
+       trans_for_each_update(trans, i) {
+               struct printbuf buf = PRINTBUF;
+               enum bkey_invalid_flags invalid_flags = 0;
+
+               if (!(flags & BTREE_INSERT_JOURNAL_REPLAY))
+                       invalid_flags |= BKEY_INVALID_WRITE|BKEY_INVALID_COMMIT;
+
+               if (unlikely(bch2_bkey_invalid(c, bkey_i_to_s_c(i->k),
+                                              i->bkey_type, invalid_flags, &buf)))
+                       ret = bch2_trans_commit_bkey_invalid(trans, invalid_flags, i, &buf);
+               btree_insert_entry_checks(trans, i);
+               printbuf_exit(&buf);
+
+               if (ret)
+                       return ret;
+       }
+
        if (unlikely(!test_bit(BCH_FS_MAY_GO_RW, &c->flags))) {
                ret = do_bch2_trans_commit_to_journal_replay(trans);
                goto out_reset;
@@ -1144,6 +1130,8 @@ out:
        if (likely(!(flags & BTREE_INSERT_NOCHECK_RW)))
                bch2_write_ref_put(c, BCH_WRITE_REF_trans);
 out_reset:
+       if (!ret)
+               bch2_trans_downgrade(trans);
        bch2_trans_reset_updates(trans);
 
        return ret;