]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_update.c
Update bcachefs sources to 9a555a741e80 bcachefs: omit alignment attribute on big...
[bcachefs-tools-debian] / libbcachefs / btree_update.c
index 74ec99dbc55e0d32e5ac8bbb5e9b9103685f9024..cbb7cf21da5be15c267ddd07dbc0eb09f2fba479 100644 (file)
@@ -14,6 +14,8 @@
 #include "snapshot.h"
 #include "trace.h"
 
+#include <linux/darray.h>
+
 static inline int btree_insert_entry_cmp(const struct btree_insert_entry *l,
                                         const struct btree_insert_entry *r)
 {
@@ -186,8 +188,11 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans,
        enum btree_id btree_id = iter->btree_id;
        struct bkey_i *update;
        struct bpos new_start = bkey_start_pos(new.k);
-       bool front_split = bkey_lt(bkey_start_pos(old.k), new_start);
-       bool back_split  = bkey_gt(old.k->p, new.k->p);
+       unsigned front_split = bkey_lt(bkey_start_pos(old.k), new_start);
+       unsigned back_split  = bkey_gt(old.k->p, new.k->p);
+       unsigned middle_split = (front_split || back_split) &&
+               old.k->p.snapshot != new.k->p.snapshot;
+       unsigned nr_splits = front_split + back_split + middle_split;
        int ret = 0, compressed_sectors;
 
        /*
@@ -195,10 +200,9 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans,
         * so that __bch2_trans_commit() can increase our disk
         * reservation:
         */
-       if (((front_split && back_split) ||
-            ((front_split || back_split) && old.k->p.snapshot != new.k->p.snapshot)) &&
+       if (nr_splits > 1 &&
            (compressed_sectors = bch2_bkey_sectors_compressed(old)))
-               trans->extra_disk_res += compressed_sectors;
+               trans->extra_disk_res += compressed_sectors * (nr_splits - 1);
 
        if (front_split) {
                update = bch2_bkey_make_mut_noupdate(trans, old);
@@ -216,8 +220,7 @@ int bch2_trans_update_extent_overwrite(struct btree_trans *trans,
        }
 
        /* If we're overwriting in a different snapshot - middle split: */
-       if (old.k->p.snapshot != new.k->p.snapshot &&
-           (front_split || back_split)) {
+       if (middle_split) {
                update = bch2_bkey_make_mut_noupdate(trans, old);
                if ((ret = PTR_ERR_OR_ZERO(update)))
                        return ret;
@@ -409,7 +412,7 @@ bch2_trans_update_by_path(struct btree_trans *trans, btree_path_idx_t path_idx,
         * Pending updates are kept sorted: first, find position of new update,
         * then delete/trim any updates the new update overwrites:
         */
-       trans_for_each_update(trans, i) {
+       for (i = trans->updates; i < trans->updates + trans->nr_updates; i++) {
                cmp = btree_insert_entry_cmp(&n, i);
                if (cmp <= 0)
                        break;
@@ -556,9 +559,7 @@ struct jset_entry *__bch2_trans_jset_entry_alloc(struct btree_trans *trans, unsi
        if (new_top > trans->journal_entries_size) {
                trans->journal_entries_size = roundup_pow_of_two(new_top);
 
-               struct btree_transaction_stats *s = btree_trans_stats(trans);
-               if (s)
-                       s->journal_entries_size = trans->journal_entries_size;
+               btree_trans_stats(trans)->journal_entries_size = trans->journal_entries_size;
        }
 
        struct jset_entry *n =
@@ -788,6 +789,27 @@ int bch2_btree_delete_range(struct bch_fs *c, enum btree_id id,
 
 int bch2_btree_bit_mod(struct btree_trans *trans, enum btree_id btree,
                       struct bpos pos, bool set)
+{
+       struct bkey_i *k = bch2_trans_kmalloc(trans, sizeof(*k));
+       int ret = PTR_ERR_OR_ZERO(k);
+       if (ret)
+               return ret;
+
+       bkey_init(&k->k);
+       k->k.type = set ? KEY_TYPE_set : KEY_TYPE_deleted;
+       k->k.p = pos;
+
+       struct btree_iter iter;
+       bch2_trans_iter_init(trans, &iter, btree, pos, BTREE_ITER_INTENT);
+
+       ret   = bch2_btree_iter_traverse(&iter) ?:
+               bch2_trans_update(trans, &iter, k, 0);
+       bch2_trans_iter_exit(trans, &iter);
+       return ret;
+}
+
+int bch2_btree_bit_mod_buffered(struct btree_trans *trans, enum btree_id btree,
+                               struct bpos pos, bool set)
 {
        struct bkey_i k;