Commit 48620e51 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Topology repair fixes

 - We were failing to start topology repair, because we hadn't set the
   superblock flag indicating it needed to run
 - set_node_min() forget to update the btree node's key
 - bch2_gc_alloc_reset() didn't reset data type, leading to inserting an
   invalid key that was empty but had nonzero data type
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent 5e05d7ed
...@@ -214,7 +214,7 @@ static int set_node_min(struct bch_fs *c, struct btree *b, struct bpos new_min) ...@@ -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); bch2_btree_node_drop_keys_outside_node(b);
bkey_copy(&b->key, &new->k_i);
return 0; return 0;
} }
...@@ -359,7 +359,7 @@ static int bch2_btree_repair_topology_recurse(struct bch_fs *c, struct btree *b) ...@@ -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 bkey_buf prev_k, cur_k;
struct btree *prev = NULL, *cur = NULL; struct btree *prev = NULL, *cur = NULL;
bool have_child, dropped_children = false; bool have_child, dropped_children = false;
struct printbuf buf; struct printbuf buf = PRINTBUF;
int ret = 0; int ret = 0;
if (!b->c.level) if (!b->c.level)
...@@ -387,7 +387,7 @@ static int bch2_btree_repair_topology_recurse(struct bch_fs *c, struct btree *b) ...@@ -387,7 +387,7 @@ static int bch2_btree_repair_topology_recurse(struct bch_fs *c, struct btree *b)
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(cur_k.k)); bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(cur_k.k));
if (mustfix_fsck_err_on(ret == -EIO, c, 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", " %s",
bch2_btree_ids[b->c.btree_id], bch2_btree_ids[b->c.btree_id],
b->c.level - 1, b->c.level - 1,
...@@ -1498,6 +1498,7 @@ static void bch2_gc_alloc_reset(struct bch_fs *c, bool metadata_only) ...@@ -1498,6 +1498,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_cached ||
g->data_type == BCH_DATA_parity)) g->data_type == BCH_DATA_parity))
continue; continue;
g->data_type = 0;
g->dirty_sectors = 0; g->dirty_sectors = 0;
g->cached_sectors = 0; g->cached_sectors = 0;
} }
...@@ -1735,11 +1736,11 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only) ...@@ -1735,11 +1736,11 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only)
if (BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb) && if (BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb) &&
!test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags) && !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags) &&
c->opts.fix_errors != FSCK_OPT_NO) { 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); ret = bch2_repair_topology(c);
if (ret) if (ret)
goto out; 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); set_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags);
} }
...@@ -1750,6 +1751,7 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only) ...@@ -1750,6 +1751,7 @@ int bch2_gc(struct bch_fs *c, bool initial, bool metadata_only)
!test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags) && !test_bit(BCH_FS_TOPOLOGY_REPAIR_DONE, &c->flags) &&
!test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags)) { !test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags)) {
set_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags); set_bit(BCH_FS_NEED_ANOTHER_GC, &c->flags);
SET_BCH_SB_HAS_TOPOLOGY_ERRORS(c->disk_sb.sb, true);
ret = 0; ret = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment