bcachefs: Assorted ec fixes
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 29 Oct 2021 20:29:13 +0000 (16:29 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:15 +0000 (17:09 -0400)
- The backpointer that ec_stripe_update_ptrs() uses now needs to include
  the snapshot ID, which means we have to change where we add the
  backpointer to after getting the snapshot ID for the new extents

- ec_stripe_update_ptrs() needs to be calling bch2_trans_begin()

- improve error message in bch2_mark_stripe()

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/btree_gc.c
fs/bcachefs/buckets.c
fs/bcachefs/ec.c
fs/bcachefs/ec.h
fs/bcachefs/io.c
fs/bcachefs/move.c

index 4fc882b15d936a5a068f6ff5d3fe3e9b9aa847b9..2d9e5c91c9d0030a75280b0678a8c29854023d7f 100644 (file)
@@ -699,6 +699,7 @@ static int bch2_gc_mark_key(struct bch_fs *c, enum btree_id btree_id,
                BTREE_TRIGGER_INSERT|
                BTREE_TRIGGER_GC|
                (initial ? BTREE_TRIGGER_NOATOMIC : 0);
+       char buf[200];
        int ret = 0;
 
        if (initial) {
@@ -717,8 +718,9 @@ static int bch2_gc_mark_key(struct bch_fs *c, enum btree_id btree_id,
 
                if (test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags) ||
                    fsck_err_on(!bch2_bkey_replicas_marked(c, *k), c,
-                               "superblock not marked as containing replicas (type %u)",
-                               k->k->type)) {
+                               "superblock not marked as containing replicas\n"
+                               "  while marking %s",
+                               (bch2_bkey_val_to_text(&PBUF(buf), c, *k), buf))) {
                        ret = bch2_mark_bkey_replicas(c, *k);
                        if (ret) {
                                bch_err(c, "error marking bkey replicas: %i", ret);
index 48687a70411e1d5128752e8bc8a6844e4c6a624c..4cd44a50beab7be49e209684bdfc6b9f0b59ff58 100644 (file)
@@ -1007,8 +1007,13 @@ static int bch2_mark_stripe(struct bch_fs *c,
        BUG_ON(gc && old_s);
 
        if (!m || (old_s && !m->alive)) {
-               bch_err_ratelimited(c, "error marking nonexistent stripe %zu",
-                                   idx);
+               char buf1[200], buf2[200];
+
+               bch2_bkey_val_to_text(&PBUF(buf1), c, old);
+               bch2_bkey_val_to_text(&PBUF(buf2), c, new);
+               bch_err_ratelimited(c, "error marking nonexistent stripe %zu while marking\n"
+                                   "old %s\n"
+                                   "new %s", idx, buf1, buf2);
                bch2_inconsistent_error(c);
                return -1;
        }
index 7dfa052e9765d67635e95519f681df227bfc6216..ed4a73345e3ad809652cd2490e6bac9bc0e834e1 100644 (file)
@@ -837,8 +837,9 @@ static int ec_stripe_update_ptrs(struct bch_fs *c,
        bch2_trans_iter_init(&trans, &iter, BTREE_ID_extents,
                             bkey_start_pos(pos),
                             BTREE_ITER_INTENT);
-
-       while ((k = bch2_btree_iter_peek(&iter)).k &&
+retry:
+       while (bch2_trans_begin(&trans),
+              (k = bch2_btree_iter_peek(&iter)).k &&
               !(ret = bkey_err(k)) &&
               bkey_cmp(bkey_start_pos(k.k), pos->p) < 0) {
                struct bch_extent_ptr *ptr, *ec_ptr = NULL;
@@ -874,11 +875,11 @@ static int ec_stripe_update_ptrs(struct bch_fs *c,
                                        BTREE_INSERT_NOFAIL);
                if (!ret)
                        bch2_btree_iter_set_pos(&iter, next_pos);
-               if (ret == -EINTR)
-                       ret = 0;
                if (ret)
                        break;
        }
+       if (ret == -EINTR)
+               goto retry;
        bch2_trans_iter_exit(&trans, &iter);
 
        bch2_trans_exit(&trans);
@@ -1069,16 +1070,14 @@ void *bch2_writepoint_ec_buf(struct bch_fs *c, struct write_point *wp)
        return ob->ec->new_stripe.data[ob->ec_idx] + (offset << 9);
 }
 
-void bch2_ec_add_backpointer(struct bch_fs *c, struct write_point *wp,
-                            struct bpos pos, unsigned sectors)
+void bch2_ob_add_backpointer(struct bch_fs *c, struct open_bucket *ob,
+                            struct bkey *k)
 {
-       struct open_bucket *ob = ec_open_bucket(c, &wp->ptrs);
-       struct ec_stripe_new *ec;
+       struct ec_stripe_new *ec = ob->ec;
 
-       if (!ob)
+       if (!ec)
                return;
 
-       ec = ob->ec;
        mutex_lock(&ec->lock);
 
        if (bch2_keylist_realloc(&ec->keys, ec->inline_keys,
@@ -1088,8 +1087,8 @@ void bch2_ec_add_backpointer(struct bch_fs *c, struct write_point *wp,
        }
 
        bkey_init(&ec->keys.top->k);
-       ec->keys.top->k.p       = pos;
-       bch2_key_resize(&ec->keys.top->k, sectors);
+       ec->keys.top->k.p       = k->p;
+       ec->keys.top->k.size    = k->size;
        bch2_keylist_push(&ec->keys);
 
        mutex_unlock(&ec->lock);
index e79626b59509a3082ecef7f06acba9afbabeb21f..eb16e140e2c814e3cda734ff3c99b57131032332 100644 (file)
@@ -193,8 +193,8 @@ struct ec_stripe_head {
 int bch2_ec_read_extent(struct bch_fs *, struct bch_read_bio *);
 
 void *bch2_writepoint_ec_buf(struct bch_fs *, struct write_point *);
-void bch2_ec_add_backpointer(struct bch_fs *, struct write_point *,
-                            struct bpos, unsigned);
+void bch2_ob_add_backpointer(struct bch_fs *, struct open_bucket *,
+                            struct bkey *);
 
 void bch2_ec_bucket_written(struct bch_fs *, struct open_bucket *);
 void bch2_ec_bucket_cancel(struct bch_fs *, struct open_bucket *);
index 772fdeb722c7c2c14348b300e46c19b74a4b2647..bf04b61ae8828b474162bec349c5ded08d5e21d6 100644 (file)
@@ -470,6 +470,7 @@ static int bch2_write_index_default(struct bch_write_op *op)
 {
        struct bch_fs *c = op->c;
        struct bkey_buf sk;
+       struct open_bucket *ec_ob = ec_open_bucket(c, &op->open_buckets);
        struct keylist *keys = &op->insert_keys;
        struct bkey_i *k = bch2_keylist_front(keys);
        struct btree_trans trans;
@@ -513,6 +514,9 @@ static int bch2_write_index_default(struct bch_write_op *op)
                if (ret)
                        break;
 
+               if (ec_ob)
+                       bch2_ob_add_backpointer(c, ec_ob, &sk.k->k);
+
                if (bkey_cmp(iter.pos, k->k.p) >= 0)
                        bch2_keylist_pop_front(&op->insert_keys);
                else
@@ -950,7 +954,6 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp,
        struct bio *src = &op->wbio.bio, *dst = src;
        struct bvec_iter saved_iter;
        void *ec_buf;
-       struct bpos ec_pos = op->pos;
        unsigned total_output = 0, total_input = 0;
        bool bounce = false;
        bool page_alloc_failed = false;
@@ -1120,9 +1123,6 @@ static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp,
 
        dst->bi_iter.bi_size = total_output;
 do_write:
-       /* might have done a realloc... */
-       bch2_ec_add_backpointer(c, wp, ec_pos, total_input >> 9);
-
        *_dst = dst;
        return more;
 csum_err:
index 5f50b66fe2063de94536b31a8b252235e95e176e..2f260360b08987eab26b51d90ca748bfae1c5415 100644 (file)
@@ -8,6 +8,7 @@
 #include "btree_update_interior.h"
 #include "buckets.h"
 #include "disk_groups.h"
+#include "ec.h"
 #include "inode.h"
 #include "io.h"
 #include "journal_reclaim.h"
@@ -135,6 +136,7 @@ int bch2_migrate_index_update(struct bch_write_op *op)
        struct btree_iter iter;
        struct migrate_write *m =
                container_of(op, struct migrate_write, op);
+       struct open_bucket *ec_ob = ec_open_bucket(c, &op->open_buckets);
        struct keylist *keys = &op->insert_keys;
        struct bkey_buf _new, _insert;
        int ret = 0;
@@ -252,6 +254,8 @@ int bch2_migrate_index_update(struct bch_write_op *op)
                if (!ret) {
                        bch2_btree_iter_set_pos(&iter, next_pos);
                        atomic_long_inc(&c->extent_migrate_done);
+                       if (ec_ob)
+                               bch2_ob_add_backpointer(c, ec_ob, &insert->k);
                }
 err:
                if (ret == -EINTR)