]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 98a1bff393 bcachefs: Topology repair fixes
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 7 Apr 2022 21:52:51 +0000 (17:52 -0400)
committerKent Overstreet <kent.overstreet@gmail.com>
Thu, 7 Apr 2022 21:52:51 +0000 (17:52 -0400)
.bcachefs_revision
libbcachefs/alloc_background.c
libbcachefs/alloc_background.h
libbcachefs/btree_cache.c
libbcachefs/btree_gc.c
libbcachefs/btree_update_leaf.c

index 739cb9b9b4538f78a7d29d1191fa5ecf661f3027..1b15e9c3f62910af4e9ca02ea149a041af0aea60 100644 (file)
@@ -1 +1 @@
-d2e08891288b073941b0351dc37fb36b056e2449
+98a1bff3935daf96c2140ef19d3b3d4309797e56
index 6d6798ae9d3dc68645827d8f9893ed87b11c5663..998925154b04c5b11227690b94fa6e7a87c00361 100644 (file)
@@ -346,12 +346,31 @@ int bch2_alloc_v3_invalid(const struct bch_fs *c, struct bkey_s_c k,
 int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k,
                          int rw, struct printbuf *err)
 {
+       struct bkey_s_c_alloc_v4 a = bkey_s_c_to_alloc_v4(k);
+
        if (bkey_val_bytes(k.k) != sizeof(struct bch_alloc_v4)) {
                pr_buf(err, "bad val size (%zu != %zu)",
                       bkey_val_bytes(k.k), sizeof(struct bch_alloc_v4));
                return -EINVAL;
        }
 
+       if (rw == WRITE) {
+               if (a.v->cached_sectors &&
+                   !a.v->dirty_sectors &&
+                   !a.v->io_time[READ]) {
+                       pr_buf(err, "cached bucket with read_time == 0");
+                       return -EINVAL;
+               }
+
+               if (!a.v->dirty_sectors &&
+                   !a.v->cached_sectors &&
+                   !a.v->stripe &&
+                   a.v->data_type) {
+                       pr_buf(err, "empty, but data_type nonzero");
+                       return -EINVAL;
+               }
+       }
+
        return 0;
 }
 
index 9c6a590fa0737ae62f8cb95a356bbeaf580a5d84..11e0bca3e7f296d4d51ee70cd2f0643ee54848a6 100644 (file)
@@ -44,7 +44,6 @@ static inline enum bucket_state bucket_state(struct bch_alloc_v4 a)
                return BUCKET_dirty;
        if (a.cached_sectors)
                return BUCKET_cached;
-       BUG_ON(a.data_type);
        if (BCH_ALLOC_V4_NEED_DISCARD(&a))
                return BUCKET_need_discard;
        if (alloc_gc_gen(a) >= BUCKET_GC_GEN_MAX)
index 8e04129abeac978b2c8e6365dd0ba67765626d1f..72f0587e4da95a8fc22f3a33e5ae34a627c9354d 100644 (file)
@@ -768,31 +768,29 @@ static int lock_node_check_fn(struct six_lock *lock, void *p)
 
 static noinline void btree_bad_header(struct bch_fs *c, struct btree *b)
 {
-       struct printbuf buf1 = PRINTBUF;
-       struct printbuf buf2 = PRINTBUF;
-       struct printbuf buf3 = PRINTBUF;
+       struct printbuf buf = PRINTBUF;
 
        if (!test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags))
                return;
 
-       bch2_bkey_val_to_text(&buf1, c, bkey_i_to_s_c(&b->key));
-       bch2_bpos_to_text(&buf2, b->data->min_key);
-       bch2_bpos_to_text(&buf3, b->data->max_key);
-
-       bch2_fs_inconsistent(c, "btree node header doesn't match ptr\n"
-                            "btree %s level %u\n"
-                            "ptr: %s\n"
-                            "header: btree %s level %llu\n"
-                            "min %s max %s\n",
-                            bch2_btree_ids[b->c.btree_id], b->c.level,
-                            buf1.buf,
-                            bch2_btree_ids[BTREE_NODE_ID(b->data)],
-                            BTREE_NODE_LEVEL(b->data),
-                            buf2.buf, buf3.buf);
-
-       printbuf_exit(&buf3);
-       printbuf_exit(&buf2);
-       printbuf_exit(&buf1);
+       pr_buf(&buf,
+              "btree node header doesn't match ptr\n"
+              "btree %s level %u\n"
+              "ptr: ",
+              bch2_btree_ids[b->c.btree_id], b->c.level);
+       bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
+
+       pr_buf(&buf, "\nheader: btree %s level %llu\n"
+              "min ",
+              bch2_btree_ids[BTREE_NODE_ID(b->data)],
+              BTREE_NODE_LEVEL(b->data));
+       bch2_bpos_to_text(&buf, b->data->min_key);
+
+       pr_buf(&buf, "\nmax ");
+       bch2_bpos_to_text(&buf, b->data->max_key);
+
+       bch2_fs_inconsistent(c, "%s", buf.buf);
+       printbuf_exit(&buf);
 }
 
 static inline void btree_check_header(struct bch_fs *c, struct btree *b)
index e19991796c823808d8e376f16358e36a4efaa074..feaa33f4dec0f46414f3f1873875d522b24f4130 100644 (file)
@@ -214,7 +214,7 @@ static int set_node_min(struct bch_fs *c, struct btree *b, struct bpos new_min)
        }
 
        bch2_btree_node_drop_keys_outside_node(b);
-
+       bkey_copy(&b->key, &new->k_i);
        return 0;
 }
 
@@ -359,7 +359,7 @@ static int bch2_btree_repair_topology_recurse(struct bch_fs *c, struct btree *b)
        struct bkey_buf prev_k, cur_k;
        struct btree *prev = NULL, *cur = NULL;
        bool have_child, dropped_children = false;
-       struct printbuf buf;
+       struct printbuf buf = PRINTBUF;
        int ret = 0;
 
        if (!b->c.level)
@@ -387,7 +387,7 @@ again:
                bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(cur_k.k));
 
                if (mustfix_fsck_err_on(ret == -EIO, c,
-                               "Unreadable btree node at btree %s level %u:\n"
+                               "Topology repair: unreadable btree node at btree %s level %u:\n"
                                "  %s",
                                bch2_btree_ids[b->c.btree_id],
                                b->c.level - 1,
@@ -1501,6 +1501,7 @@ static void bch2_gc_alloc_reset(struct bch_fs *c, bool metadata_only)
                             g->data_type == BCH_DATA_cached ||
                             g->data_type == BCH_DATA_parity))
                                continue;
+                       g->data_type = 0;
                        g->dirty_sectors = 0;
                        g->cached_sectors = 0;
                }
@@ -1738,11 +1739,11 @@ again:
        if (BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb) &&
            !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags) &&
            c->opts.fix_errors != FSCK_OPT_NO) {
-               bch_info(c, "starting topology repair pass");
+               bch_info(c, "Starting topology repair pass");
                ret = bch2_repair_topology(c);
                if (ret)
                        goto out;
-               bch_info(c, "topology repair pass done");
+               bch_info(c, "Topology repair pass done");
 
                set_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags);
        }
@@ -1753,6 +1754,7 @@ again:
            !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags) &&
            !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags)) {
                set_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags);
+               SET_BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb, true);
                ret = 0;
        }
 
index 5427d0bdd1deb076d96b8c9ffbcd61a547866ac6..36e149846aebde85d8718a2852637ccb55b5216a 100644 (file)
@@ -874,7 +874,7 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
                        bch2_bkey_invalid(c, bkey_i_to_s_c(i->k),
                                          i->bkey_type, WRITE, &buf);
 
-                       bch2_fs_fatal_error(c, "%s", buf.buf);
+                       bch2_trans_inconsistent(trans, "%s", buf.buf);
                        printbuf_exit(&buf);
                        return -EINVAL;
                }