From 8933315689bcb57a3b282bad262ac584e095a2f5 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 17 Jul 2022 00:31:40 -0400 Subject: bcachefs: Convert bch2_dev_usrdata_drop() to for_each_btree_key2() The new for_each_btree_key2() macro handles transaction retries, allowing us to avoid nested transactions - which we want to avoid since they're tricky to do completely correctly and upcoming assertions are going to be checking for that. Signed-off-by: Kent Overstreet --- fs/bcachefs/migrate.c | 111 +++++++++++++++++++++++--------------------------- 1 file changed, 51 insertions(+), 60 deletions(-) (limited to 'fs/bcachefs/migrate.c') diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c index 5345697f2712..be89628702f7 100644 --- a/fs/bcachefs/migrate.c +++ b/fs/bcachefs/migrate.c @@ -35,85 +35,76 @@ static int drop_dev_ptrs(struct bch_fs *c, struct bkey_s k, return 0; } -static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags, - enum btree_id btree_id) +static int bch2_dev_usrdata_drop_key(struct btree_trans *trans, + struct btree_iter *iter, + struct bkey_s_c k, + unsigned dev_idx, + int flags) +{ + struct bch_fs *c = trans->c; + struct bkey_i *n; + int ret; + + if (!bch2_bkey_has_device(k, dev_idx)) + return 0; + + n = bch2_trans_kmalloc(trans, bkey_bytes(k.k)); + ret = PTR_ERR_OR_ZERO(n); + if (ret) + return ret; + + bkey_reassemble(n, k); + + ret = drop_dev_ptrs(c, bkey_i_to_s(n), dev_idx, flags, false); + if (ret) + return ret; + + /* + * If the new extent no longer has any pointers, bch2_extent_normalize() + * will do the appropriate thing with it (turning it into a + * KEY_TYPE_error key, or just a discard if it was a cached extent) + */ + bch2_extent_normalize(c, bkey_i_to_s(n)); + + /* + * 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(&n->k)) + n->k.size = 0; + + return bch2_trans_update(trans, iter, n, BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE); +} + +static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags) { struct btree_trans trans; struct btree_iter iter; struct bkey_s_c k; - struct bkey_buf sk; + enum btree_id id; int ret = 0; - bch2_bkey_buf_init(&sk); bch2_trans_init(&trans, c, BTREE_ITER_MAX, 0); - bch2_trans_iter_init(&trans, &iter, btree_id, POS_MIN, - BTREE_ITER_PREFETCH| - BTREE_ITER_ALL_SNAPSHOTS); - - while ((bch2_trans_begin(&trans), - (k = bch2_btree_iter_peek(&iter)).k) && - !(ret = bkey_err(k))) { - if (!bch2_bkey_has_device(k, dev_idx)) { - bch2_btree_iter_advance(&iter); + for (id = 0; id < BTREE_ID_NR; id++) { + if (!btree_type_has_ptrs(id)) continue; - } - - bch2_bkey_buf_reassemble(&sk, c, k); - ret = drop_dev_ptrs(c, bkey_i_to_s(sk.k), - dev_idx, flags, false); - if (ret) - break; - - /* - * If the new extent no longer has any pointers, bch2_extent_normalize() - * will do the appropriate thing with it (turning it into a - * KEY_TYPE_error key, or just a discard if it was a cached extent) - */ - bch2_extent_normalize(c, bkey_i_to_s(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_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); - - /* - * don't want to leave ret == -EINTR, since if we raced and - * something else overwrote the key we could spuriously return - * -EINTR below: - */ - if (ret == -EINTR) - ret = 0; + ret = for_each_btree_key_commit(&trans, iter, id, POS_MIN, + BTREE_ITER_PREFETCH|BTREE_ITER_ALL_SNAPSHOTS, k, + NULL, NULL, BTREE_INSERT_NOFAIL, + bch2_dev_usrdata_drop_key(&trans, &iter, k, dev_idx, flags)); if (ret) break; } - bch2_trans_iter_exit(&trans, &iter); bch2_trans_exit(&trans); - bch2_bkey_buf_exit(&sk, c); - - BUG_ON(ret == -EINTR); return ret; } -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); -} - static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags) { struct btree_trans trans; -- cgit v1.2.3