Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | /* |
| 3 | * Code for moving data off a device. |
| 4 | */ |
| 5 | |
| 6 | #include "bcachefs.h" |
Kent Overstreet | 07a1006 | 2020-12-17 15:08:58 -0500 | [diff] [blame] | 7 | #include "bkey_buf.h" |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 8 | #include "btree_update.h" |
Kent Overstreet | 7ef2a73 | 2019-01-21 15:32:13 -0500 | [diff] [blame] | 9 | #include "btree_update_interior.h" |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 10 | #include "buckets.h" |
Kent Overstreet | d4bf5ee | 2022-07-18 19:42:58 -0400 | [diff] [blame] | 11 | #include "errcode.h" |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 12 | #include "extents.h" |
Kent Overstreet | 1809b8c | 2023-09-10 18:05:17 -0400 | [diff] [blame] | 13 | #include "io_write.h" |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 14 | #include "journal.h" |
| 15 | #include "keylist.h" |
| 16 | #include "migrate.h" |
| 17 | #include "move.h" |
| 18 | #include "replicas.h" |
| 19 | #include "super-io.h" |
| 20 | |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 21 | static int drop_dev_ptrs(struct bch_fs *c, struct bkey_s k, |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 22 | unsigned dev_idx, int flags, bool metadata) |
| 23 | { |
| 24 | unsigned replicas = metadata ? c->opts.metadata_replicas : c->opts.data_replicas; |
| 25 | unsigned lost = metadata ? BCH_FORCE_IF_METADATA_LOST : BCH_FORCE_IF_DATA_LOST; |
| 26 | unsigned degraded = metadata ? BCH_FORCE_IF_METADATA_DEGRADED : BCH_FORCE_IF_DATA_DEGRADED; |
| 27 | unsigned nr_good; |
| 28 | |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 29 | bch2_bkey_drop_device(k, dev_idx); |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 30 | |
Kent Overstreet | 26609b6 | 2018-11-01 15:10:01 -0400 | [diff] [blame] | 31 | nr_good = bch2_bkey_durability(c, k.s_c); |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 32 | if ((!nr_good && !(flags & lost)) || |
| 33 | (nr_good < replicas && !(flags & degraded))) |
Kent Overstreet | ce3e928 | 2024-02-05 21:44:23 -0500 | [diff] [blame] | 34 | return -BCH_ERR_remove_would_lose_data; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 35 | |
| 36 | return 0; |
| 37 | } |
| 38 | |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 39 | static int bch2_dev_usrdata_drop_key(struct btree_trans *trans, |
| 40 | struct btree_iter *iter, |
| 41 | struct bkey_s_c k, |
| 42 | unsigned dev_idx, |
| 43 | int flags) |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 44 | { |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 45 | struct bch_fs *c = trans->c; |
| 46 | struct bkey_i *n; |
| 47 | int ret; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 48 | |
Kent Overstreet | 702ffea | 2023-03-10 16:28:37 -0500 | [diff] [blame] | 49 | if (!bch2_bkey_has_device_c(k, dev_idx)) |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 50 | return 0; |
Kent Overstreet | 0564b16 | 2019-03-13 20:49:16 -0400 | [diff] [blame] | 51 | |
Kent Overstreet | 5dd8c60 | 2024-04-07 18:05:34 -0400 | [diff] [blame] | 52 | n = bch2_bkey_make_mut(trans, iter, &k, BTREE_UPDATE_internal_snapshot_node); |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 53 | ret = PTR_ERR_OR_ZERO(n); |
| 54 | if (ret) |
| 55 | return ret; |
Kent Overstreet | 0564b16 | 2019-03-13 20:49:16 -0400 | [diff] [blame] | 56 | |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 57 | ret = drop_dev_ptrs(c, bkey_i_to_s(n), dev_idx, flags, false); |
| 58 | if (ret) |
| 59 | return ret; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 60 | |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 61 | /* |
| 62 | * If the new extent no longer has any pointers, bch2_extent_normalize() |
| 63 | * will do the appropriate thing with it (turning it into a |
| 64 | * KEY_TYPE_error key, or just a discard if it was a cached extent) |
| 65 | */ |
| 66 | bch2_extent_normalize(c, bkey_i_to_s(n)); |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 67 | |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 68 | /* |
| 69 | * Since we're not inserting through an extent iterator |
Kent Overstreet | 5dd8c60 | 2024-04-07 18:05:34 -0400 | [diff] [blame] | 70 | * (BTREE_ITER_all_snapshots iterators aren't extent iterators), |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 71 | * we aren't using the extent overwrite path to delete, we're |
| 72 | * just using the normal key deletion path: |
| 73 | */ |
| 74 | if (bkey_deleted(&n->k)) |
| 75 | n->k.size = 0; |
Kent Overstreet | dbda63b | 2023-04-30 19:21:06 -0400 | [diff] [blame] | 76 | return 0; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 77 | } |
| 78 | |
Kent Overstreet | 7642609 | 2019-08-16 09:59:56 -0400 | [diff] [blame] | 79 | static int bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags) |
| 80 | { |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 81 | struct btree_trans *trans = bch2_trans_get(c); |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 82 | enum btree_id id; |
| 83 | int ret = 0; |
| 84 | |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 85 | for (id = 0; id < BTREE_ID_NR; id++) { |
| 86 | if (!btree_type_has_ptrs(id)) |
| 87 | continue; |
| 88 | |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 89 | ret = for_each_btree_key_commit(trans, iter, id, POS_MIN, |
Kent Overstreet | 5dd8c60 | 2024-04-07 18:05:34 -0400 | [diff] [blame] | 90 | BTREE_ITER_prefetch|BTREE_ITER_all_snapshots, k, |
Kent Overstreet | cb52d23e | 2023-11-11 16:31:50 -0500 | [diff] [blame] | 91 | NULL, NULL, BCH_TRANS_COMMIT_no_enospc, |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 92 | bch2_dev_usrdata_drop_key(trans, &iter, k, dev_idx, flags)); |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 93 | if (ret) |
| 94 | break; |
| 95 | } |
| 96 | |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 97 | bch2_trans_put(trans); |
Kent Overstreet | 8933315 | 2022-07-17 00:31:40 -0400 | [diff] [blame] | 98 | |
| 99 | return ret; |
Kent Overstreet | 7642609 | 2019-08-16 09:59:56 -0400 | [diff] [blame] | 100 | } |
| 101 | |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 102 | static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags) |
| 103 | { |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 104 | struct btree_trans *trans; |
Kent Overstreet | 67e0dd8 | 2021-08-30 15:18:31 -0400 | [diff] [blame] | 105 | struct btree_iter iter; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 106 | struct closure cl; |
| 107 | struct btree *b; |
Kent Overstreet | 07a1006 | 2020-12-17 15:08:58 -0500 | [diff] [blame] | 108 | struct bkey_buf k; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 109 | unsigned id; |
| 110 | int ret; |
| 111 | |
| 112 | /* don't handle this yet: */ |
| 113 | if (flags & BCH_FORCE_IF_METADATA_LOST) |
Kent Overstreet | ce3e928 | 2024-02-05 21:44:23 -0500 | [diff] [blame] | 114 | return -BCH_ERR_remove_with_metadata_missing_unimplemented; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 115 | |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 116 | trans = bch2_trans_get(c); |
Kent Overstreet | 07a1006 | 2020-12-17 15:08:58 -0500 | [diff] [blame] | 117 | bch2_bkey_buf_init(&k); |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 118 | closure_init_stack(&cl); |
| 119 | |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 120 | for (id = 0; id < BTREE_ID_NR; id++) { |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 121 | bch2_trans_node_iter_init(trans, &iter, id, POS_MIN, 0, 0, |
Kent Overstreet | 5dd8c60 | 2024-04-07 18:05:34 -0400 | [diff] [blame] | 122 | BTREE_ITER_prefetch); |
Kent Overstreet | d355c6f | 2021-10-19 14:20:50 -0400 | [diff] [blame] | 123 | retry: |
Kent Overstreet | b71717d | 2021-10-19 15:11:45 -0400 | [diff] [blame] | 124 | ret = 0; |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 125 | while (bch2_trans_begin(trans), |
Kent Overstreet | d355c6f | 2021-10-19 14:20:50 -0400 | [diff] [blame] | 126 | (b = bch2_btree_iter_peek_node(&iter)) && |
| 127 | !(ret = PTR_ERR_OR_ZERO(b))) { |
Kent Overstreet | 702ffea | 2023-03-10 16:28:37 -0500 | [diff] [blame] | 128 | if (!bch2_bkey_has_device_c(bkey_i_to_s_c(&b->key), dev_idx)) |
Kent Overstreet | 56767d6 | 2021-10-07 14:59:00 -0400 | [diff] [blame] | 129 | goto next; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 130 | |
Kent Overstreet | 07a1006 | 2020-12-17 15:08:58 -0500 | [diff] [blame] | 131 | bch2_bkey_buf_copy(&k, c, &b->key); |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 132 | |
Kent Overstreet | 07a1006 | 2020-12-17 15:08:58 -0500 | [diff] [blame] | 133 | ret = drop_dev_ptrs(c, bkey_i_to_s(k.k), |
Kent Overstreet | 31ba2cd | 2020-01-03 22:38:14 -0500 | [diff] [blame] | 134 | dev_idx, flags, true); |
Kent Overstreet | ce3e928 | 2024-02-05 21:44:23 -0500 | [diff] [blame] | 135 | if (ret) |
Kent Overstreet | 50dc0f6 | 2021-03-19 20:29:11 -0400 | [diff] [blame] | 136 | break; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 137 | |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 138 | ret = bch2_btree_node_update_key(trans, &iter, b, k.k, 0, false); |
Kent Overstreet | 549d173 | 2022-07-17 23:06:38 -0400 | [diff] [blame] | 139 | if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) { |
Kent Overstreet | 50dc0f6 | 2021-03-19 20:29:11 -0400 | [diff] [blame] | 140 | ret = 0; |
Kent Overstreet | 56767d6 | 2021-10-07 14:59:00 -0400 | [diff] [blame] | 141 | continue; |
Kent Overstreet | 31ba2cd | 2020-01-03 22:38:14 -0500 | [diff] [blame] | 142 | } |
Kent Overstreet | 56767d6 | 2021-10-07 14:59:00 -0400 | [diff] [blame] | 143 | |
Kent Overstreet | cf904c8 | 2023-12-16 22:43:41 -0500 | [diff] [blame] | 144 | bch_err_msg(c, ret, "updating btree node key"); |
| 145 | if (ret) |
Kent Overstreet | 50dc0f6 | 2021-03-19 20:29:11 -0400 | [diff] [blame] | 146 | break; |
Kent Overstreet | 56767d6 | 2021-10-07 14:59:00 -0400 | [diff] [blame] | 147 | next: |
| 148 | bch2_btree_iter_next_node(&iter); |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 149 | } |
Kent Overstreet | 549d173 | 2022-07-17 23:06:38 -0400 | [diff] [blame] | 150 | if (bch2_err_matches(ret, BCH_ERR_transaction_restart)) |
Kent Overstreet | d355c6f | 2021-10-19 14:20:50 -0400 | [diff] [blame] | 151 | goto retry; |
| 152 | |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 153 | bch2_trans_iter_exit(trans, &iter); |
Kent Overstreet | 50dc0f6 | 2021-03-19 20:29:11 -0400 | [diff] [blame] | 154 | |
| 155 | if (ret) |
| 156 | goto err; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 157 | } |
| 158 | |
Kent Overstreet | c096060 | 2022-04-17 17:30:49 -0400 | [diff] [blame] | 159 | bch2_btree_interior_updates_flush(c); |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 160 | ret = 0; |
Kent Overstreet | 424eb88 | 2019-03-25 15:10:15 -0400 | [diff] [blame] | 161 | err: |
Kent Overstreet | 07a1006 | 2020-12-17 15:08:58 -0500 | [diff] [blame] | 162 | bch2_bkey_buf_exit(&k, c); |
Kent Overstreet | 6bd68ec | 2023-09-12 17:16:02 -0400 | [diff] [blame] | 163 | bch2_trans_put(trans); |
Kent Overstreet | 424eb88 | 2019-03-25 15:10:15 -0400 | [diff] [blame] | 164 | |
Kent Overstreet | 549d173 | 2022-07-17 23:06:38 -0400 | [diff] [blame] | 165 | BUG_ON(bch2_err_matches(ret, BCH_ERR_transaction_restart)); |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 166 | |
| 167 | return ret; |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 168 | } |
| 169 | |
| 170 | int bch2_dev_data_drop(struct bch_fs *c, unsigned dev_idx, int flags) |
| 171 | { |
| 172 | return bch2_dev_usrdata_drop(c, dev_idx, flags) ?: |
Kent Overstreet | 31ba2cd | 2020-01-03 22:38:14 -0500 | [diff] [blame] | 173 | bch2_dev_metadata_drop(c, dev_idx, flags); |
Kent Overstreet | 1c6fdbd | 2017-03-16 22:18:50 -0800 | [diff] [blame] | 174 | } |