We had no existing mechanism for applying/removing erasure coding to
existing data, nothing is being obsoleted.

Like other IO path options, rebalance now ensures that data is stored
correctly according to the current erasure_code option.

Signed-off-by: Kent Overstreet <[email protected]>
---
 fs/bcachefs/rebalance.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/fs/bcachefs/rebalance.c b/fs/bcachefs/rebalance.c
index 29e12dbf3710..525e4d1716c5 100644
--- a/fs/bcachefs/rebalance.c
+++ b/fs/bcachefs/rebalance.c
@@ -593,9 +593,12 @@ static struct bkey_s_c next_rebalance_extent(struct 
btree_trans *trans,
        data_opts->target               = opts->background_target;
        data_opts->write_flags          |= BCH_WRITE_only_specified_devs;
 
+       struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
+       const union bch_extent_entry *entry;
+       struct extent_ptr_decoded p;
+
        if (r.need_rb & BIT(BCH_REBALANCE_data_replicas)) {
                unsigned durability = bch2_bkey_durability(c, k);
-               struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
                unsigned ptr_bit = 1;
 
                guard(rcu)();
@@ -609,9 +612,6 @@ static struct bkey_s_c next_rebalance_extent(struct 
btree_trans *trans,
 
                        data_opts->extra_replicas = opts->data_replicas - 
durability;
                } else {
-                       const union bch_extent_entry *entry;
-                       struct extent_ptr_decoded p;
-
                        bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
                                unsigned d = bch2_extent_ptr_durability(c, &p);
 
@@ -635,6 +635,22 @@ static struct bkey_s_c next_rebalance_extent(struct 
btree_trans *trans,
                }
        }
 
+       if (r.need_rb & BIT(BCH_REBALANCE_erasure_code)) {
+               if (opts->erasure_code) {
+                       data_opts->extra_replicas = 
min(data_opts->extra_replicas, 1);
+               } else {
+                       unsigned ptr_bit = 1;
+                       bkey_for_each_ptr_decode(k.k, ptrs, p, entry) {
+                               if (p.has_ec) {
+                                       data_opts->kill_ec_ptrs |= ptr_bit;
+                                       data_opts->extra_replicas += 
p.ec.redundancy;
+                               }
+
+                               ptr_bit <<= 1;
+                       }
+               }
+       }
+
        if (!data_opts->rewrite_ptrs &&
            !data_opts->kill_ptrs &&
            !data_opts->kill_ec_ptrs &&
-- 
2.50.1


Reply via email to