bcachefs: bch2_extent_ptr_desired_durability()
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 13 Jun 2023 19:12:04 +0000 (15:12 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:10:04 +0000 (17:10 -0400)
This adds a new helper for getting a pointer's durability irrespective
of the device state, and uses it in the the data update path.

This fixes a bug where we do a data update but request 0 replicas to be
allocated, because the replica being rewritten is on a device marked as
failed.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/data_update.c
fs/bcachefs/extents.c
fs/bcachefs/extents.h

index c89ee14f8b6b8b5ce7fcbd5f5e963df65abdcfaf..9f7a30c7ad36195b327f2a6d50cc85e5aa4c51cb 100644 (file)
@@ -474,7 +474,7 @@ int bch2_data_update_init(struct btree_trans *trans,
                        if (crc_is_compressed(p.crc))
                                reserve_sectors += k.k->size;
 
-                       m->op.nr_replicas += bch2_extent_ptr_durability(c, &p);
+                       m->op.nr_replicas += bch2_extent_ptr_desired_durability(c, &p);
                } else if (!p.ptr.cached) {
                        bch2_dev_list_add_dev(&m->op.devs_have, p.ptr.dev);
                }
index e2b126ad2babdf5a3b8fdb8730cffd6453e12d25..7e00550980de3f4c9a8c1eef3079677f8177c502 100644 (file)
@@ -641,9 +641,8 @@ unsigned bch2_bkey_replicas(struct bch_fs *c, struct bkey_s_c k)
        return replicas;
 }
 
-unsigned bch2_extent_ptr_durability(struct bch_fs *c, struct extent_ptr_decoded *p)
+unsigned bch2_extent_ptr_desired_durability(struct bch_fs *c, struct extent_ptr_decoded *p)
 {
-       unsigned durability = 0;
        struct bch_dev *ca;
 
        if (p->ptr.cached)
@@ -651,13 +650,28 @@ unsigned bch2_extent_ptr_durability(struct bch_fs *c, struct extent_ptr_decoded
 
        ca = bch_dev_bkey_exists(c, p->ptr.dev);
 
-       if (ca->mi.state != BCH_MEMBER_STATE_failed)
-               durability = max_t(unsigned, durability, ca->mi.durability);
+       return ca->mi.durability +
+               (p->has_ec
+                ? p->ec.redundancy
+                : 0);
+}
 
-       if (p->has_ec)
-               durability += p->ec.redundancy;
+unsigned bch2_extent_ptr_durability(struct bch_fs *c, struct extent_ptr_decoded *p)
+{
+       struct bch_dev *ca;
 
-       return durability;
+       if (p->ptr.cached)
+               return 0;
+
+       ca = bch_dev_bkey_exists(c, p->ptr.dev);
+
+       if (ca->mi.state == BCH_MEMBER_STATE_failed)
+               return 0;
+
+       return ca->mi.durability +
+               (p->has_ec
+                ? p->ec.redundancy
+                : 0);
 }
 
 unsigned bch2_bkey_durability(struct bch_fs *c, struct bkey_s_c k)
index 31c8140950e0073d615c52bb39a4146e7815c2e4..3ba41e37d8649610e94c56e26477baec8a53c7e6 100644 (file)
@@ -610,6 +610,7 @@ bool bch2_bkey_is_incompressible(struct bkey_s_c);
 unsigned bch2_bkey_sectors_compressed(struct bkey_s_c);
 
 unsigned bch2_bkey_replicas(struct bch_fs *, struct bkey_s_c);
+unsigned bch2_extent_ptr_desired_durability(struct bch_fs *, struct extent_ptr_decoded *);
 unsigned bch2_extent_ptr_durability(struct bch_fs *, struct extent_ptr_decoded *);
 unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c);