summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-04-07 17:52:51 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2022-04-07 17:52:51 -0400
commite05755a9fc28c2e757a531c8865773fa63dfea9c (patch)
tree28d7951ca32a6900b16f93fe90508a333043f0be
parent941075cb57b469525df76d15e61abdb42d9c7a1b (diff)
Update bcachefs sources to 98a1bff393 bcachefs: Topology repair fixes
-rw-r--r--.bcachefs_revision2
-rw-r--r--libbcachefs/alloc_background.c19
-rw-r--r--libbcachefs/alloc_background.h1
-rw-r--r--libbcachefs/btree_cache.c40
-rw-r--r--libbcachefs/btree_gc.c12
-rw-r--r--libbcachefs/btree_update_leaf.c2
6 files changed, 47 insertions, 29 deletions
diff --git a/.bcachefs_revision b/.bcachefs_revision
index 739cb9b9..1b15e9c3 100644
--- a/.bcachefs_revision
+++ b/.bcachefs_revision
@@ -1 +1 @@
-d2e08891288b073941b0351dc37fb36b056e2449
+98a1bff3935daf96c2140ef19d3b3d4309797e56
diff --git a/libbcachefs/alloc_background.c b/libbcachefs/alloc_background.c
index 6d6798ae..99892515 100644
--- a/libbcachefs/alloc_background.c
+++ b/libbcachefs/alloc_background.c
@@ -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;
}
diff --git a/libbcachefs/alloc_background.h b/libbcachefs/alloc_background.h
index 9c6a590f..11e0bca3 100644
--- a/libbcachefs/alloc_background.h
+++ b/libbcachefs/alloc_background.h
@@ -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)
diff --git a/libbcachefs/btree_cache.c b/libbcachefs/btree_cache.c
index 8e04129a..72f0587e 100644
--- a/libbcachefs/btree_cache.c
+++ b/libbcachefs/btree_cache.c
@@ -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)
diff --git a/libbcachefs/btree_gc.c b/libbcachefs/btree_gc.c
index e1999179..feaa33f4 100644
--- a/libbcachefs/btree_gc.c
+++ b/libbcachefs/btree_gc.c
@@ -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;
}
diff --git a/libbcachefs/btree_update_leaf.c b/libbcachefs/btree_update_leaf.c
index 5427d0bd..36e14984 100644
--- a/libbcachefs/btree_update_leaf.c
+++ b/libbcachefs/btree_update_leaf.c
@@ -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;
}