]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - libbcachefs/btree_update_leaf.c
Update bcachefs sources to 33a60d9b05 bcachefs: Assorted fixes for clang
[bcachefs-tools-debian] / libbcachefs / btree_update_leaf.c
index 336a91e4fb20439b7ae3c7465ba8be53f17e426a..369e37a415f3c61733ff83a494c07d0cb9b3a34c 100644 (file)
@@ -413,7 +413,7 @@ static int run_one_mem_trigger(struct btree_trans *trans,
        if (unlikely(flags & BTREE_TRIGGER_NORUN))
                return 0;
 
-       if (!btree_node_type_needs_gc(i->btree_id))
+       if (!btree_node_type_needs_gc((enum btree_node_type) i->btree_id))
                return 0;
 
        if (old_ops->atomic_trigger == new_ops->atomic_trigger &&
@@ -852,12 +852,11 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans, unsigned flags
 {
        struct bch_fs *c = trans->c;
        struct btree_insert_entry *i;
-       int ret, u64s_delta = 0;
+       int ret = 0, u64s_delta = 0;
 
 #ifdef CONFIG_BCACHEFS_DEBUG
-       struct printbuf buf = PRINTBUF;
-
        trans_for_each_update(trans, i) {
+               struct printbuf buf = PRINTBUF;
                enum bkey_invalid_flags invalid_flags = 0;
 
                if (!(flags & BTREE_INSERT_JOURNAL_REPLAY))
@@ -865,10 +864,13 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans, unsigned flags
 
                if (unlikely(bch2_bkey_invalid(c, bkey_i_to_s_c(i->k),
                                               i->bkey_type, invalid_flags, &buf)))
-                       return bch2_trans_commit_bkey_invalid(trans, flags, i, &buf);
+                       ret = bch2_trans_commit_bkey_invalid(trans, flags, i, &buf);
                btree_insert_entry_checks(trans, i);
+               printbuf_exit(&buf);
+
+               if (ret)
+                       return ret;
        }
-       printbuf_exit(&buf);
 #endif
 
        trans_for_each_update(trans, i) {
@@ -1327,7 +1329,7 @@ int __bch2_insert_snapshot_whiteouts(struct btree_trans *trans,
                                   struct bpos new_pos)
 {
        struct bch_fs *c = trans->c;
-       struct btree_iter old_iter, new_iter;
+       struct btree_iter old_iter, new_iter = { NULL };
        struct bkey_s_c old_k, new_k;
        snapshot_id_list s;
        struct bkey_i *update;
@@ -1377,25 +1379,122 @@ int __bch2_insert_snapshot_whiteouts(struct btree_trans *trans,
                if (ret)
                        break;
        }
+       bch2_trans_iter_exit(trans, &new_iter);
        bch2_trans_iter_exit(trans, &old_iter);
        darray_exit(&s);
 
        return ret;
 }
 
-int bch2_trans_update_extent(struct btree_trans *trans,
-                            struct btree_iter *orig_iter,
-                            struct bkey_i *insert,
-                            enum btree_update_flags flags)
+int bch2_trans_update_extent_overwrite(struct btree_trans *trans,
+                                      struct btree_iter *iter,
+                                      enum btree_update_flags flags,
+                                      struct bkey_s_c old,
+                                      struct bkey_s_c new)
 {
-       struct btree_iter iter;
-       struct bpos start = bkey_start_pos(&insert->k);
+       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);
+       int ret = 0, compressed_sectors;
+
+       /*
+        * If we're going to be splitting a compressed extent, note it
+        * 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)) &&
+           (compressed_sectors = bch2_bkey_sectors_compressed(old)))
+               trans->extra_journal_res += compressed_sectors;
+
+       if (front_split) {
+               update = bch2_bkey_make_mut_noupdate(trans, old);
+               if ((ret = PTR_ERR_OR_ZERO(update)))
+                       return ret;
+
+               bch2_cut_back(new_start, update);
+
+               ret =   bch2_insert_snapshot_whiteouts(trans, btree_id,
+                                       old.k->p, update->k.p) ?:
+                       bch2_btree_insert_nonextent(trans, btree_id, update,
+                                       BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE|flags);
+               if (ret)
+                       return ret;
+       }
+
+       /* If we're overwriting in a different snapshot - middle split: */
+       if (old.k->p.snapshot != new.k->p.snapshot &&
+           (front_split || back_split)) {
+               update = bch2_bkey_make_mut_noupdate(trans, old);
+               if ((ret = PTR_ERR_OR_ZERO(update)))
+                       return ret;
+
+               bch2_cut_front(new_start, update);
+               bch2_cut_back(new.k->p, update);
+
+               ret =   bch2_insert_snapshot_whiteouts(trans, btree_id,
+                                       old.k->p, update->k.p) ?:
+                       bch2_btree_insert_nonextent(trans, btree_id, update,
+                                         BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE|flags);
+               if (ret)
+                       return ret;
+       }
+
+       if (bkey_le(old.k->p, new.k->p)) {
+               update = bch2_trans_kmalloc(trans, sizeof(*update));
+               if ((ret = PTR_ERR_OR_ZERO(update)))
+                       return ret;
+
+               bkey_init(&update->k);
+               update->k.p = old.k->p;
+               update->k.p.snapshot = new.k->p.snapshot;
+
+               if (new.k->p.snapshot != old.k->p.snapshot) {
+                       update->k.type = KEY_TYPE_whiteout;
+               } else if (btree_type_has_snapshots(btree_id)) {
+                       ret = need_whiteout_for_snapshot(trans, btree_id, update->k.p);
+                       if (ret < 0)
+                               return ret;
+                       if (ret)
+                               update->k.type = KEY_TYPE_whiteout;
+               }
+
+               ret = bch2_btree_insert_nonextent(trans, btree_id, update,
+                                         BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE|flags);
+               if (ret)
+                       return ret;
+       }
+
+       if (back_split) {
+               update = bch2_bkey_make_mut_noupdate(trans, old);
+               if ((ret = PTR_ERR_OR_ZERO(update)))
+                       return ret;
+
+               bch2_cut_front(new.k->p, update);
+
+               ret = bch2_trans_update_by_path(trans, iter->path, update,
+                                         BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE|
+                                         flags, _RET_IP_);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int bch2_trans_update_extent(struct btree_trans *trans,
+                                   struct btree_iter *orig_iter,
+                                   struct bkey_i *insert,
+                                   enum btree_update_flags flags)
+{
+       struct btree_iter iter;
        struct bkey_s_c k;
        enum btree_id btree_id = orig_iter->btree_id;
-       int ret = 0, compressed_sectors;
+       int ret = 0;
 
-       bch2_trans_iter_init(trans, &iter, btree_id, start,
+       bch2_trans_iter_init(trans, &iter, btree_id, bkey_start_pos(&insert->k),
                             BTREE_ITER_INTENT|
                             BTREE_ITER_WITH_UPDATES|
                             BTREE_ITER_NOT_EXTENTS);
@@ -1416,90 +1515,14 @@ int bch2_trans_update_extent(struct btree_trans *trans,
        }
 
        while (bkey_gt(insert->k.p, bkey_start_pos(k.k))) {
-               bool front_split = bkey_lt(bkey_start_pos(k.k), start);
-               bool back_split  = bkey_gt(k.k->p, insert->k.p);
+               bool done = bkey_lt(insert->k.p, k.k->p);
 
-               /*
-                * If we're going to be splitting a compressed extent, note it
-                * so that __bch2_trans_commit() can increase our disk
-                * reservation:
-                */
-               if (((front_split && back_split) ||
-                    ((front_split || back_split) && k.k->p.snapshot != insert->k.p.snapshot)) &&
-                   (compressed_sectors = bch2_bkey_sectors_compressed(k)))
-                       trans->extra_journal_res += compressed_sectors;
-
-               if (front_split) {
-                       update = bch2_bkey_make_mut_noupdate(trans, k);
-                       if ((ret = PTR_ERR_OR_ZERO(update)))
-                               goto err;
-
-                       bch2_cut_back(start, update);
-
-                       ret =   bch2_insert_snapshot_whiteouts(trans, btree_id,
-                                               k.k->p, update->k.p) ?:
-                               bch2_btree_insert_nonextent(trans, btree_id, update,
-                                               BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE|flags);
-                       if (ret)
-                               goto err;
-               }
-
-               if (k.k->p.snapshot != insert->k.p.snapshot &&
-                   (front_split || back_split)) {
-                       update = bch2_bkey_make_mut_noupdate(trans, k);
-                       if ((ret = PTR_ERR_OR_ZERO(update)))
-                               goto err;
-
-                       bch2_cut_front(start, update);
-                       bch2_cut_back(insert->k.p, update);
-
-                       ret =   bch2_insert_snapshot_whiteouts(trans, btree_id,
-                                               k.k->p, update->k.p) ?:
-                               bch2_btree_insert_nonextent(trans, btree_id, update,
-                                                 BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE|flags);
-                       if (ret)
-                               goto err;
-               }
-
-               if (bkey_le(k.k->p, insert->k.p)) {
-                       update = bch2_trans_kmalloc(trans, sizeof(*update));
-                       if ((ret = PTR_ERR_OR_ZERO(update)))
-                               goto err;
-
-                       bkey_init(&update->k);
-                       update->k.p = k.k->p;
-                       update->k.p.snapshot = insert->k.p.snapshot;
-
-                       if (insert->k.p.snapshot != k.k->p.snapshot) {
-                               update->k.type = KEY_TYPE_whiteout;
-                       } else if (btree_type_has_snapshots(btree_id)) {
-                               ret = need_whiteout_for_snapshot(trans, btree_id, update->k.p);
-                               if (ret < 0)
-                                       goto err;
-                               if (ret)
-                                       update->k.type = KEY_TYPE_whiteout;
-                       }
-
-                       ret = bch2_btree_insert_nonextent(trans, btree_id, update,
-                                                 BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE|flags);
-                       if (ret)
-                               goto err;
-               }
-
-               if (back_split) {
-                       update = bch2_bkey_make_mut_noupdate(trans, k);
-                       if ((ret = PTR_ERR_OR_ZERO(update)))
-                               goto err;
-
-                       bch2_cut_front(insert->k.p, update);
+               ret = bch2_trans_update_extent_overwrite(trans, &iter, flags, k, bkey_i_to_s_c(insert));
+               if (ret)
+                       goto err;
 
-                       ret = bch2_trans_update_by_path(trans, iter.path, update,
-                                                 BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE|
-                                                 flags, _RET_IP_);
-                       if (ret)
-                               goto err;
+               if (done)
                        goto out;
-               }
 next:
                bch2_btree_iter_advance(&iter);
                k = bch2_btree_iter_peek_upto(&iter, POS(insert->k.p.inode, U64_MAX));
@@ -1515,18 +1538,8 @@ next:
                        goto err;
        }
 out:
-       if (!bkey_deleted(&insert->k)) {
-               /*
-                * Rewinding iterators is expensive: get a new one and the one
-                * that points to the start of insert will be cloned from:
-                */
-               bch2_trans_iter_exit(trans, &iter);
-               bch2_trans_iter_init(trans, &iter, btree_id, insert->k.p,
-                                    BTREE_ITER_NOT_EXTENTS|
-                                    BTREE_ITER_INTENT);
-               ret   = bch2_btree_iter_traverse(&iter) ?:
-                       bch2_trans_update(trans, &iter, insert, flags);
-       }
+       if (!bkey_deleted(&insert->k))
+               ret = bch2_btree_insert_nonextent(trans, btree_id, insert, flags);
 err:
        bch2_trans_iter_exit(trans, &iter);