X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Fmigrate.c;h=5345697f2712cebdf44a59022cb3d93be1edf2c5;hb=bad0c8c50758b4447d529f61017c1a8c85976a3e;hp=4b59dcd04cce3dd0140c7f87f0acbe3a6cfa30c8;hpb=92d34f6ed29e90d48c40a4c31816df805edfe483;p=bcachefs-tools-debian diff --git a/libbcachefs/migrate.c b/libbcachefs/migrate.c index 4b59dcd..5345697 100644 --- a/libbcachefs/migrate.c +++ b/libbcachefs/migrate.c @@ -4,7 +4,7 @@ */ #include "bcachefs.h" -#include "bkey_on_stack.h" +#include "bkey_buf.h" #include "btree_update.h" #include "btree_update_interior.h" #include "buckets.h" @@ -39,28 +39,27 @@ static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags enum btree_id btree_id) { struct btree_trans trans; - struct btree_iter *iter; + struct btree_iter iter; struct bkey_s_c k; - struct bkey_on_stack sk; + struct bkey_buf sk; int ret = 0; - bkey_on_stack_init(&sk); + bch2_bkey_buf_init(&sk); bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0); - iter = bch2_trans_get_iter(&trans, btree_id, POS_MIN, - BTREE_ITER_PREFETCH); + bch2_trans_iter_init(&trans, &iter, btree_id, POS_MIN, + BTREE_ITER_PREFETCH| + BTREE_ITER_ALL_SNAPSHOTS); - while ((k = bch2_btree_iter_peek(iter)).k && + while ((bch2_trans_begin(&trans), + (k = bch2_btree_iter_peek(&iter)).k) && !(ret = bkey_err(k))) { if (!bch2_bkey_has_device(k, dev_idx)) { - ret = bch2_mark_bkey_replicas(c, k); - if (ret) - break; - bch2_btree_iter_next(iter); + bch2_btree_iter_advance(&iter); continue; } - bkey_on_stack_reassemble(&sk, c, k); + bch2_bkey_buf_reassemble(&sk, c, k); ret = drop_dev_ptrs(c, bkey_i_to_s(sk.k), dev_idx, flags, false); @@ -74,12 +73,19 @@ static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags */ bch2_extent_normalize(c, bkey_i_to_s(sk.k)); - bch2_btree_iter_set_pos(iter, bkey_start_pos(&sk.k->k)); - - bch2_trans_update(&trans, iter, sk.k); + /* + * Since we're not inserting through an extent iterator + * (BTREE_ITER_ALL_SNAPSHOTS iterators aren't extent iterators), + * we aren't using the extent overwrite path to delete, we're + * just using the normal key deletion path: + */ + if (bkey_deleted(&sk.k->k)) + sk.k->k.size = 0; - ret = bch2_trans_commit(&trans, NULL, NULL, - BTREE_INSERT_ATOMIC| + ret = bch2_btree_iter_traverse(&iter) ?: + bch2_trans_update(&trans, &iter, sk.k, + BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE) ?: + bch2_trans_commit(&trans, NULL, NULL, BTREE_INSERT_NOFAIL); /* @@ -92,9 +98,10 @@ static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags if (ret) break; } + bch2_trans_iter_exit(&trans, &iter); - ret = bch2_trans_exit(&trans) ?: ret; - bkey_on_stack_exit(&sk, c); + bch2_trans_exit(&trans); + bch2_bkey_buf_exit(&sk, c); BUG_ON(ret == -EINTR); @@ -103,16 +110,17 @@ static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags) { - return __bch2_dev_usrdata_drop(c, dev_idx, flags, BTREE_ID_EXTENTS) ?: - __bch2_dev_usrdata_drop(c, dev_idx, flags, BTREE_ID_REFLINK); + return __bch2_dev_usrdata_drop(c, dev_idx, flags, BTREE_ID_extents) ?: + __bch2_dev_usrdata_drop(c, dev_idx, flags, BTREE_ID_reflink); } static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags) { struct btree_trans trans; - struct btree_iter *iter; + struct btree_iter iter; struct closure cl; struct btree *b; + struct bkey_buf k; unsigned id; int ret; @@ -120,62 +128,58 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags) if (flags & BCH_FORCE_IF_METADATA_LOST) return -EINVAL; + bch2_bkey_buf_init(&k); bch2_trans_init(&trans, c, 0, 0); closure_init_stack(&cl); for (id = 0; id < BTREE_ID_NR; id++) { - for_each_btree_node(&trans, iter, id, POS_MIN, - BTREE_ITER_PREFETCH, b) { - __BKEY_PADDED(k, BKEY_BTREE_PTR_VAL_U64s_MAX) tmp; - struct bkey_i_btree_ptr *new_key; + bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0, + BTREE_ITER_PREFETCH); retry: + ret = 0; + while (bch2_trans_begin(&trans), + (b = bch2_btree_iter_peek_node(&iter)) && + !(ret = PTR_ERR_OR_ZERO(b))) { if (!bch2_bkey_has_device(bkey_i_to_s_c(&b->key), - dev_idx)) { - /* - * we might have found a btree node key we - * needed to update, and then tried to update it - * but got -EINTR after upgrading the iter, but - * then raced and the node is now gone: - */ - bch2_btree_iter_downgrade(iter); - - ret = bch2_mark_bkey_replicas(c, bkey_i_to_s_c(&b->key)); - if (ret) - goto err; - } else { - bkey_copy(&tmp.k, &b->key); - new_key = bkey_i_to_btree_ptr(&tmp.k); - - ret = drop_dev_ptrs(c, bkey_i_to_s(&new_key->k_i), - dev_idx, flags, true); - if (ret) - goto err; - - ret = bch2_btree_node_update_key(c, iter, b, new_key); - if (ret == -EINTR) { - b = bch2_btree_iter_peek_node(iter); - goto retry; - } - if (ret) - goto err; + dev_idx)) + goto next; + + bch2_bkey_buf_copy(&k, c, &b->key); + + ret = drop_dev_ptrs(c, bkey_i_to_s(k.k), + dev_idx, flags, true); + if (ret) { + bch_err(c, "Cannot drop device without losing data"); + break; + } + + ret = bch2_btree_node_update_key(&trans, &iter, b, k.k, false); + if (ret == -EINTR) { + ret = 0; + continue; } + + if (ret) { + bch_err(c, "Error updating btree node key: %i", ret); + break; + } +next: + bch2_btree_iter_next_node(&iter); } - bch2_trans_iter_free(&trans, iter); - } + if (ret == -EINTR) + goto retry; - /* flush relevant btree updates */ - while (1) { - closure_wait_event(&c->btree_interior_update_wait, - !bch2_btree_interior_updates_nr_pending(c) || - c->btree_roots_dirty); - if (!bch2_btree_interior_updates_nr_pending(c)) - break; - bch2_journal_meta(&c->journal); + bch2_trans_iter_exit(&trans, &iter); + + if (ret) + goto err; } + bch2_btree_interior_updates_flush(c); ret = 0; err: - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); + bch2_bkey_buf_exit(&k, c); BUG_ON(ret == -EINTR); @@ -185,6 +189,5 @@ err: int bch2_dev_data_drop(struct bch_fs *c, unsigned dev_idx, int flags) { return bch2_dev_usrdata_drop(c, dev_idx, flags) ?: - bch2_dev_metadata_drop(c, dev_idx, flags) ?: - bch2_replicas_gc2(c); + bch2_dev_metadata_drop(c, dev_idx, flags); }