bcachefs: Extent helper improvements
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 10 Mar 2023 21:28:37 +0000 (16:28 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:56 +0000 (17:09 -0400)
 - __bch2_bkey_drop_ptr() -> bch2_bkey_drop_ptr_noerror(), now available
   outside extents.

 - Split bch2_bkey_has_device() and bch2_bkey_has_device_c(), const and
   non const versions

 - bch2_extent_has_ptr() now returns the pointer it found

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

index 26b351d489406bace3e16c9425f5809fa74e2e4a..8332e8a0b05af0f7f32fa898514c5140fa26fb40 100644 (file)
@@ -170,13 +170,13 @@ static int __bch2_data_update_index_update(struct btree_trans *trans,
                i = 0;
                bkey_for_each_ptr_decode(old.k, bch2_bkey_ptrs_c(old), p, entry) {
                        if (((1U << i) & m->data_opts.rewrite_ptrs) &&
-                           bch2_extent_has_ptr(old, p, bkey_i_to_s_c(insert))) {
+                           bch2_extent_has_ptr(old, p, bkey_i_to_s(insert))) {
                                /*
                                 * If we're going to be adding a pointer to the
                                 * same device, we have to drop the old one -
                                 * otherwise, we can just mark it cached:
                                 */
-                               if (bch2_bkey_has_device(bkey_i_to_s_c(&new->k_i), p.ptr.dev))
+                               if (bch2_bkey_has_device_c(bkey_i_to_s_c(&new->k_i), p.ptr.dev))
                                        bch2_bkey_drop_device_noerror(bkey_i_to_s(insert), p.ptr.dev);
                                else
                                        bch2_bkey_mark_dev_cached(bkey_i_to_s(insert), p.ptr.dev);
@@ -188,7 +188,7 @@ static int __bch2_data_update_index_update(struct btree_trans *trans,
                /* Add new ptrs: */
                extent_for_each_ptr_decode(extent_i_to_s(new), p, entry) {
                        const struct bch_extent_ptr *existing_ptr =
-                               bch2_bkey_has_device(bkey_i_to_s_c(insert), p.ptr.dev);
+                               bch2_bkey_has_device_c(bkey_i_to_s_c(insert), p.ptr.dev);
 
                        if (existing_ptr && existing_ptr->cached) {
                                /*
index 62bfde035f78a05202c6a1409c970288ff317fe0..4adbfd4855f772b18673f9f1d7f81526ac87be50 100644 (file)
@@ -959,7 +959,7 @@ static int ec_stripe_update_extent(struct btree_trans *trans,
        bkey_reassemble(n, k);
 
        bch2_bkey_drop_ptrs(bkey_i_to_s(n), ptr, ptr->dev != dev);
-       ec_ptr = (void *) bch2_bkey_has_device(bkey_i_to_s_c(n), dev);
+       ec_ptr = bch2_bkey_has_device(bkey_i_to_s(n), dev);
        BUG_ON(!ec_ptr);
 
        stripe_ptr = (struct bch_extent_stripe_ptr) {
index 38be9bf912648792dcb0ff78703cd92113507374..17e9c434619bd5fa774161db903a206637e76597 100644 (file)
@@ -25,8 +25,6 @@
 #include "trace.h"
 #include "util.h"
 
-static union bch_extent_entry *__bch2_bkey_drop_ptr(struct bkey_s, struct bch_extent_ptr *);
-
 static unsigned bch2_crc_field_size_max[] = {
        [BCH_EXTENT_ENTRY_crc32] = CRC32_SIZE_MAX,
        [BCH_EXTENT_ENTRY_crc64] = CRC64_SIZE_MAX,
@@ -511,7 +509,7 @@ restart_narrow_pointers:
 
        bkey_for_each_ptr_decode(&k->k, ptrs, p, i)
                if (can_narrow_crc(p.crc, n)) {
-                       __bch2_bkey_drop_ptr(bkey_i_to_s(k), &i->ptr);
+                       bch2_bkey_drop_ptr_noerror(bkey_i_to_s(k), &i->ptr);
                        p.ptr.offset += p.crc.offset;
                        p.crc = n;
                        bch2_extent_ptr_decoded_append(k, &p);
@@ -691,7 +689,21 @@ unsigned bch2_bkey_durability(struct bch_fs *c, struct bkey_s_c k)
        unsigned durability = 0;
 
        bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
-               durability += bch2_extent_ptr_durability(c,& p);
+               durability += bch2_extent_ptr_durability(c, &p);
+
+       return durability;
+}
+
+static unsigned bch2_bkey_durability_safe(struct bch_fs *c, struct bkey_s_c k)
+{
+       struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
+       const union bch_extent_entry *entry;
+       struct extent_ptr_decoded p;
+       unsigned durability = 0;
+
+       bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
+               if (p.ptr.dev < c->sb.nr_devices && c->devs[p.ptr.dev])
+                       durability += bch2_extent_ptr_durability(c, &p);
 
        return durability;
 }
@@ -764,8 +776,8 @@ static void extent_entry_drop(struct bkey_s k, union bch_extent_entry *entry)
 /*
  * Returns pointer to the next entry after the one being dropped:
  */
-static union bch_extent_entry *__bch2_bkey_drop_ptr(struct bkey_s k,
-                                          struct bch_extent_ptr *ptr)
+union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s k,
+                                                  struct bch_extent_ptr *ptr)
 {
        struct bkey_ptrs ptrs = bch2_bkey_ptrs(k);
        union bch_extent_entry *entry = to_entry(ptr), *next;
@@ -808,7 +820,7 @@ union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s k,
 {
        bool have_dirty = bch2_bkey_dirty_devs(k.s_c).nr;
        union bch_extent_entry *ret =
-               __bch2_bkey_drop_ptr(k, ptr);
+               bch2_bkey_drop_ptr_noerror(k, ptr);
 
        /*
         * If we deleted all the dirty pointers and there's still cached
@@ -839,14 +851,13 @@ void bch2_bkey_drop_device(struct bkey_s k, unsigned dev)
 
 void bch2_bkey_drop_device_noerror(struct bkey_s k, unsigned dev)
 {
-       struct bch_extent_ptr *ptr = (void *) bch2_bkey_has_device(k.s_c, dev);
+       struct bch_extent_ptr *ptr = bch2_bkey_has_device(k, dev);
 
        if (ptr)
-               __bch2_bkey_drop_ptr(k, ptr);
+               bch2_bkey_drop_ptr_noerror(k, ptr);
 }
 
-const struct bch_extent_ptr *
-bch2_bkey_has_device(struct bkey_s_c k, unsigned dev)
+const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c k, unsigned dev)
 {
        struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
        const struct bch_extent_ptr *ptr;
@@ -921,11 +932,11 @@ bool bch2_extents_match(struct bkey_s_c k1, struct bkey_s_c k2)
        }
 }
 
-bool bch2_extent_has_ptr(struct bkey_s_c k1, struct extent_ptr_decoded p1,
-                        struct bkey_s_c k2)
+struct bch_extent_ptr *
+bch2_extent_has_ptr(struct bkey_s_c k1, struct extent_ptr_decoded p1, struct bkey_s k2)
 {
-       struct bkey_ptrs_c ptrs2 = bch2_bkey_ptrs_c(k2);
-       const union bch_extent_entry *entry2;
+       struct bkey_ptrs ptrs2 = bch2_bkey_ptrs(k2);
+       union bch_extent_entry *entry2;
        struct extent_ptr_decoded p2;
 
        bkey_for_each_ptr_decode(k2.k, ptrs2, p2, entry2)
@@ -933,9 +944,9 @@ bool bch2_extent_has_ptr(struct bkey_s_c k1, struct extent_ptr_decoded p1,
                    p1.ptr.gen          == p2.ptr.gen &&
                    (s64) p1.ptr.offset + p1.crc.offset - bkey_start_offset(k1.k) ==
                    (s64) p2.ptr.offset + p2.crc.offset - bkey_start_offset(k2.k))
-                       return true;
+                       return &entry2->ptr;
 
-       return false;
+       return NULL;
 }
 
 void bch2_extent_ptr_set_cached(struct bkey_s k, struct bch_extent_ptr *ptr)
@@ -991,6 +1002,9 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
        struct bch_dev *ca;
        bool first = true;
 
+       if (c)
+               prt_printf(out, "durability: %u ", bch2_bkey_durability_safe(c, k));
+
        bkey_extent_entry_for_each(ptrs, entry) {
                if (!first)
                        prt_printf(out, " ");
index bac6a1ed2c599a945e915c23b0772c2221887012..9b026ae95932f382d5b6c7aacd34b38d628c059f 100644 (file)
@@ -613,14 +613,21 @@ unsigned bch2_bkey_durability(struct bch_fs *, struct bkey_s_c);
 
 void bch2_bkey_drop_device(struct bkey_s, unsigned);
 void bch2_bkey_drop_device_noerror(struct bkey_s, unsigned);
-const struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s_c, unsigned);
+
+const struct bch_extent_ptr *bch2_bkey_has_device_c(struct bkey_s_c, unsigned);
+
+static inline struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s k, unsigned dev)
+{
+       return (void *) bch2_bkey_has_device_c(k.s_c, dev);
+}
+
 bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned);
 
 void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *);
 
 static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr ptr)
 {
-       EBUG_ON(bch2_bkey_has_device(bkey_i_to_s_c(k), ptr.dev));
+       EBUG_ON(bch2_bkey_has_device(bkey_i_to_s(k), ptr.dev));
 
        switch (k->k.type) {
        case KEY_TYPE_btree_ptr:
@@ -642,6 +649,8 @@ static inline void bch2_bkey_append_ptr(struct bkey_i *k, struct bch_extent_ptr
 
 void bch2_extent_ptr_decoded_append(struct bkey_i *,
                                    struct extent_ptr_decoded *);
+union bch_extent_entry *bch2_bkey_drop_ptr_noerror(struct bkey_s,
+                                                  struct bch_extent_ptr *);
 union bch_extent_entry *bch2_bkey_drop_ptr(struct bkey_s,
                                           struct bch_extent_ptr *);
 
@@ -665,7 +674,8 @@ do {                                                                        \
 bool bch2_bkey_matches_ptr(struct bch_fs *, struct bkey_s_c,
                           struct bch_extent_ptr, u64);
 bool bch2_extents_match(struct bkey_s_c, struct bkey_s_c);
-bool bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s_c);
+struct bch_extent_ptr *
+bch2_extent_has_ptr(struct bkey_s_c, struct extent_ptr_decoded, struct bkey_s);
 
 void bch2_extent_ptr_set_cached(struct bkey_s, struct bch_extent_ptr *);
 
index 3b07982c2330e457ca2e2647d0a206ad43f3985e..410521f11ec25e947ebda4153732995fe32bff1c 100644 (file)
@@ -971,7 +971,7 @@ static bool bch2_journal_writing_to_device(struct journal *j, unsigned dev_idx)
             seq++) {
                struct journal_buf *buf = journal_seq_to_buf(j, seq);
 
-               if (bch2_bkey_has_device(bkey_i_to_s_c(&buf->key), dev_idx))
+               if (bch2_bkey_has_device_c(bkey_i_to_s_c(&buf->key), dev_idx))
                        ret = true;
        }
        spin_unlock(&j->lock);
index 51c26f9857d9d55f7ceae9118be0668e19c86ae7..97b131fd72e6834ecab6385265389007f5f7cfa1 100644 (file)
@@ -1338,8 +1338,7 @@ static void __journal_write_alloc(struct journal *j,
                if (!ca->mi.durability ||
                    ca->mi.state != BCH_MEMBER_STATE_rw ||
                    !ja->nr ||
-                   bch2_bkey_has_device(bkey_i_to_s_c(&w->key),
-                                        ca->dev_idx) ||
+                   bch2_bkey_has_device_c(bkey_i_to_s_c(&w->key), ca->dev_idx) ||
                    sectors > ja->sectors_free)
                        continue;
 
index e3e39127b40a0aa4708735bcc3f2d2d91bf367f3..d93db07f0c8781d9ad35afeeeebb10938e94428d 100644 (file)
@@ -46,7 +46,7 @@ static int bch2_dev_usrdata_drop_key(struct btree_trans *trans,
        struct bkey_i *n;
        int ret;
 
-       if (!bch2_bkey_has_device(k, dev_idx))
+       if (!bch2_bkey_has_device_c(k, dev_idx))
                return 0;
 
        n = bch2_bkey_make_mut(trans, k);
@@ -130,8 +130,7 @@ retry:
                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))
+                       if (!bch2_bkey_has_device_c(bkey_i_to_s_c(&b->key), dev_idx))
                                goto next;
 
                        bch2_bkey_buf_copy(&k, c, &b->key);