]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to c68fda3e8f bcachefs: Fix btree node read error path
authorKent Overstreet <kent.overstreet@gmail.com>
Tue, 7 Jun 2022 06:16:44 +0000 (02:16 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Tue, 7 Jun 2022 06:16:44 +0000 (02:16 -0400)
.bcachefs_revision
libbcachefs/btree_io.c
libbcachefs/recovery.c
libbcachefs/recovery.h

index 5eb25511a179d6ca3a75f1c27f9a7e46f3566dc1..0e58a6ddb8695df4fe869f7437779a97e9f0be69 100644 (file)
@@ -1 +1 @@
-600598598b7c6d2069a374a14ad4925f39a30faa
+c68fda3e8f4106f1e1881e650f702d5bc2d301cb
index 4629617bfa0e99258a3d3c2b58ca179bab17416f..a04d48aecd141b32eae14073cf6ad52ec179b74e 100644 (file)
@@ -1488,23 +1488,32 @@ void bch2_btree_node_read(struct bch_fs *c, struct btree *b,
        struct btree_read_bio *rb;
        struct bch_dev *ca;
        struct bio *bio;
-       struct printbuf buf = PRINTBUF;
        int ret;
 
-       btree_pos_to_text(&buf, c, b);
        trace_btree_read(c, b);
 
        if (bch2_verify_all_btree_replicas &&
            !btree_node_read_all_replicas(c, b, sync))
-               goto out;
+               return;
 
        ret = bch2_bkey_pick_read_device(c, bkey_i_to_s_c(&b->key),
                                         NULL, &pick);
-       if (bch2_fs_fatal_err_on(ret <= 0, c,
-                       "btree node read error: no device to read from\n"
-                       " at %s", buf.buf)) {
+
+       if (ret <= 0) {
+               struct printbuf buf = PRINTBUF;
+
+               pr_buf(&buf, "btree node read error: no device to read from\n at ");
+               btree_pos_to_text(&buf, c, b);
+               bch_err(c, "%s", buf.buf);
+
+               if (test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags))
+                       bch2_fatal_error(c);
+
                set_btree_node_read_error(b);
-               goto out;
+               clear_btree_node_read_in_flight(b);
+               wake_up_bit(&b->flags, BTREE_NODE_read_in_flight);
+               printbuf_exit(&buf);
+               return;
        }
 
        ca = bch_dev_bkey_exists(c, pick.ptr.dev);
@@ -1546,8 +1555,6 @@ void bch2_btree_node_read(struct bch_fs *c, struct btree *b,
                else
                        queue_work(c->io_complete_wq, &rb->work);
        }
-out:
-       printbuf_exit(&buf);
 }
 
 int bch2_btree_root_read(struct bch_fs *c, enum btree_id id,
index 04afe2453b0bc54756edb98dd767272fd82eecd6..1f14c0b6d56c91399fb9e9805c6ff43fce53f0e5 100644 (file)
@@ -153,21 +153,17 @@ static void journal_iters_fix(struct bch_fs *c)
 {
        struct journal_keys *keys = &c->journal_keys;
        /* The key we just inserted is immediately before the gap: */
-       struct journal_key *n = &keys->d[keys->gap - 1];
        size_t gap_end = keys->gap + (keys->size - keys->nr);
        struct btree_and_journal_iter *iter;
 
        /*
-        * If an iterator points one after the key we just inserted,
-        * and the key we just inserted compares > the iterator's position,
-        * decrement the iterator so it points at the key we just inserted:
+        * If an iterator points one after the key we just inserted, decrement
+        * the iterator so it points at the key we just inserted - if the
+        * decrement was unnecessary, bch2_btree_and_journal_iter_peek() will
+        * handle that:
         */
        list_for_each_entry(iter, &c->journal_iters, journal.list)
-               if (iter->journal.idx == gap_end &&
-                   iter->last &&
-                   iter->b->c.btree_id == n->btree_id &&
-                   iter->b->c.level    == n->level &&
-                   bpos_cmp(n->k->k.p, iter->unpacked.p) > 0)
+               if (iter->journal.idx == gap_end)
                        iter->journal.idx = keys->gap - 1;
 }
 
@@ -297,30 +293,30 @@ void bch2_journal_key_overwritten(struct bch_fs *c, enum btree_id btree,
                keys->d[idx].overwritten = true;
 }
 
-static struct bkey_i *bch2_journal_iter_peek(struct journal_iter *iter)
+static void bch2_journal_iter_advance(struct journal_iter *iter)
+{
+       if (iter->idx < iter->keys->size) {
+               iter->idx++;
+               if (iter->idx == iter->keys->gap)
+                       iter->idx += iter->keys->size - iter->keys->nr;
+       }
+}
+
+struct bkey_s_c bch2_journal_iter_peek(struct journal_iter *iter)
 {
        struct journal_key *k = iter->keys->d + iter->idx;
 
-       while (k < iter->keys->d + iter->keys->nr &&
+       while (k < iter->keys->d + iter->keys->size &&
               k->btree_id      == iter->btree_id &&
               k->level         == iter->level) {
                if (!k->overwritten)
-                       return k->k;
+                       return bkey_i_to_s_c(k->k);
 
-               iter->idx++;
+               bch2_journal_iter_advance(iter);
                k = iter->keys->d + iter->idx;
        }
 
-       return NULL;
-}
-
-static void bch2_journal_iter_advance(struct journal_iter *iter)
-{
-       if (iter->idx < iter->keys->size) {
-               iter->idx++;
-               if (iter->idx == iter->keys->gap)
-                       iter->idx += iter->keys->size - iter->keys->nr;
-       }
+       return bkey_s_c_null;
 }
 
 static void bch2_journal_iter_exit(struct journal_iter *iter)
@@ -352,71 +348,49 @@ static void bch2_journal_iter_advance_btree(struct btree_and_journal_iter *iter)
 
 void bch2_btree_and_journal_iter_advance(struct btree_and_journal_iter *iter)
 {
-       switch (iter->last) {
-       case none:
-               break;
-       case btree:
-               bch2_journal_iter_advance_btree(iter);
-               break;
-       case journal:
-               bch2_journal_iter_advance(&iter->journal);
-               break;
-       }
-
-       iter->last = none;
+       if (!bpos_cmp(iter->pos, SPOS_MAX))
+               iter->at_end = true;
+       else
+               iter->pos = bpos_successor(iter->pos);
 }
 
 struct bkey_s_c bch2_btree_and_journal_iter_peek(struct btree_and_journal_iter *iter)
 {
-       struct bkey_s_c ret;
+       struct bkey_s_c btree_k, journal_k, ret;
+again:
+       if (iter->at_end)
+               return bkey_s_c_null;
 
-       while (1) {
-               struct bkey_s_c btree_k         =
-                       bch2_journal_iter_peek_btree(iter);
-               struct bkey_s_c journal_k       =
-                       bkey_i_to_s_c(bch2_journal_iter_peek(&iter->journal));
-
-               if (btree_k.k && journal_k.k) {
-                       int cmp = bpos_cmp(btree_k.k->p, journal_k.k->p);
+       while ((btree_k = bch2_journal_iter_peek_btree(iter)).k &&
+              bpos_cmp(btree_k.k->p, iter->pos) < 0)
+               bch2_journal_iter_advance_btree(iter);
 
-                       if (!cmp)
-                               bch2_journal_iter_advance_btree(iter);
+       while ((journal_k = bch2_journal_iter_peek(&iter->journal)).k &&
+              bpos_cmp(journal_k.k->p, iter->pos) < 0)
+               bch2_journal_iter_advance(&iter->journal);
 
-                       iter->last = cmp < 0 ? btree : journal;
-               } else if (btree_k.k) {
-                       iter->last = btree;
-               } else if (journal_k.k) {
-                       iter->last = journal;
-               } else {
-                       iter->last = none;
-                       return bkey_s_c_null;
-               }
+       ret = journal_k.k &&
+               (!btree_k.k || bpos_cmp(journal_k.k->p, btree_k.k->p) <= 0)
+               ? journal_k
+               : btree_k;
 
-               ret = iter->last == journal ? journal_k : btree_k;
+       if (ret.k && iter->b && bpos_cmp(ret.k->p, iter->b->data->max_key) > 0)
+               ret = bkey_s_c_null;
 
-               if (iter->b &&
-                   bpos_cmp(ret.k->p, iter->b->data->max_key) > 0) {
-                       iter->journal.idx = iter->journal.keys->nr;
-                       iter->last = none;
-                       return bkey_s_c_null;
+       if (ret.k) {
+               iter->pos = ret.k->p;
+               if (bkey_deleted(ret.k)) {
+                       bch2_btree_and_journal_iter_advance(iter);
+                       goto again;
                }
-
-               if (!bkey_deleted(ret.k))
-                       break;
-
-               bch2_btree_and_journal_iter_advance(iter);
+       } else {
+               iter->pos = SPOS_MAX;
+               iter->at_end = true;
        }
 
        return ret;
 }
 
-struct bkey_s_c bch2_btree_and_journal_iter_next(struct btree_and_journal_iter *iter)
-{
-       bch2_btree_and_journal_iter_advance(iter);
-
-       return bch2_btree_and_journal_iter_peek(iter);
-}
-
 void bch2_btree_and_journal_iter_exit(struct btree_and_journal_iter *iter)
 {
        bch2_journal_iter_exit(&iter->journal);
@@ -434,6 +408,8 @@ void __bch2_btree_and_journal_iter_init_node_iter(struct btree_and_journal_iter
        iter->node_iter = node_iter;
        bch2_journal_iter_init(c, &iter->journal, b->c.btree_id, b->c.level, pos);
        INIT_LIST_HEAD(&iter->journal.list);
+       iter->pos = b->data->min_key;
+       iter->at_end = false;
 }
 
 /*
@@ -1169,9 +1145,6 @@ use_clean:
                blacklist_seq = journal_seq = le64_to_cpu(clean->journal_seq) + 1;
        }
 
-       if (c->opts.read_journal_only)
-               goto out;
-
        if (c->opts.reconstruct_alloc) {
                c->sb.compat &= ~(1ULL << BCH_COMPAT_alloc_info);
                drop_alloc_keys(&c->journal_keys);
@@ -1202,6 +1175,13 @@ use_clean:
                }
        }
 
+       /*
+        * note: cmd_list_journal needs the blacklist table fully up to date so
+        * it can asterisk ignored journal entries:
+        */
+       if (c->opts.read_journal_only)
+               goto out;
+
        ret = bch2_fs_journal_start(&c->journal, journal_seq);
        if (ret)
                goto err;
index 52db06b29310f5f9449914bab965d2d2427b959d..8c0348e8b84cf00de92fcfebc588a64957d2253a 100644 (file)
@@ -20,12 +20,8 @@ struct btree_and_journal_iter {
        struct bkey             unpacked;
 
        struct journal_iter     journal;
-
-       enum last_key_returned {
-               none,
-               btree,
-               journal,
-       }                       last;
+       struct bpos             pos;
+       bool                    at_end;
 };
 
 struct bkey_i *bch2_journal_keys_peek_upto(struct bch_fs *, enum btree_id,
@@ -44,7 +40,6 @@ void bch2_journal_key_overwritten(struct bch_fs *, enum btree_id,
 
 void bch2_btree_and_journal_iter_advance(struct btree_and_journal_iter *);
 struct bkey_s_c bch2_btree_and_journal_iter_peek(struct btree_and_journal_iter *);
-struct bkey_s_c bch2_btree_and_journal_iter_next(struct btree_and_journal_iter *);
 
 void bch2_btree_and_journal_iter_exit(struct btree_and_journal_iter *);
 void __bch2_btree_and_journal_iter_init_node_iter(struct btree_and_journal_iter *,