summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/backpointers.c72
1 files changed, 9 insertions, 63 deletions
diff --git a/fs/bcachefs/backpointers.c b/fs/bcachefs/backpointers.c
index afdfe991e4dd..bd26ab3e6812 100644
--- a/fs/bcachefs/backpointers.c
+++ b/fs/bcachefs/backpointers.c
@@ -872,27 +872,13 @@ static int check_bucket_backpointers_to_extents(struct btree_trans *, struct bch
static int check_bucket_backpointer_mismatch(struct btree_trans *trans, struct bkey_s_c alloc_k,
bool *had_mismatch,
- struct bkey_buf *last_flushed,
- struct bpos *last_pos,
- unsigned *nr_iters)
+ struct bkey_buf *last_flushed)
{
struct bch_fs *c = trans->c;
struct bch_alloc_v4 a_convert;
const struct bch_alloc_v4 *a = bch2_alloc_to_v4(alloc_k, &a_convert);
bool need_commit = false;
- if (!bpos_eq(*last_pos, alloc_k.k->p))
- *nr_iters = 0;
-
- *last_pos = alloc_k.k->p;
- *nr_iters += 1;
-
- if (*nr_iters > 2) {
- bch_err(c, "%s: looping at %llu:%llu", __func__,
- last_pos->inode, last_pos->offset);
- return 0;
- }
-
*had_mismatch = false;
if (a->data_type == BCH_DATA_sb ||
@@ -951,52 +937,19 @@ static int check_bucket_backpointer_mismatch(struct btree_trans *trans, struct b
if (sectors[ALLOC_dirty] != a->dirty_sectors ||
sectors[ALLOC_cached] != a->cached_sectors ||
sectors[ALLOC_stripe] != a->stripe_sectors) {
+ if (c->sb.version_upgrade_complete >= bcachefs_metadata_version_backpointer_bucket_gen) {
+ ret = bch2_backpointers_maybe_flush(trans, alloc_k, last_flushed);
+ if (ret)
+ return ret;
+ }
+
if (sectors[ALLOC_dirty] > a->dirty_sectors ||
sectors[ALLOC_cached] > a->cached_sectors ||
sectors[ALLOC_stripe] > a->stripe_sectors) {
- if (*nr_iters > 1) {
- ret = 0;
-
- CLASS(printbuf, buf)();
- bch2_log_msg_start(c, &buf);
-
- prt_printf(&buf, "backpointer sectors > bucket sectors, but found no bad backpointers\n"
- "bucket %llu:%llu data type %s, counters\n",
- alloc_k.k->p.inode,
- alloc_k.k->p.offset,
- __bch2_data_types[a->data_type]);
- if (sectors[ALLOC_dirty] > a->dirty_sectors)
- prt_printf(&buf, "dirty: %u > %u\n",
- sectors[ALLOC_dirty], a->dirty_sectors);
- if (sectors[ALLOC_cached] > a->cached_sectors)
- prt_printf(&buf, "cached: %u > %u\n",
- sectors[ALLOC_cached], a->cached_sectors);
- if (sectors[ALLOC_stripe] > a->stripe_sectors)
- prt_printf(&buf, "stripe: %u > %u\n",
- sectors[ALLOC_stripe], a->stripe_sectors);
-
- for_each_btree_key_max_norestart(trans, iter, BTREE_ID_backpointers,
- bucket_pos_to_bp_start(ca, alloc_k.k->p),
- bucket_pos_to_bp_end(ca, alloc_k.k->p), 0, bp_k, ret) {
- bch2_bkey_val_to_text(&buf, c, bp_k);
- prt_newline(&buf);
- }
- bch2_trans_iter_exit(trans, &iter);
-
- bch2_print_str(c, KERN_ERR, buf.buf);
- return ret;
- }
-
return check_bucket_backpointers_to_extents(trans, ca, alloc_k.k->p) ?:
bch_err_throw(c, transaction_restart_nested);
}
- if (c->sb.version_upgrade_complete >= bcachefs_metadata_version_backpointer_bucket_gen) {
- ret = bch2_backpointers_maybe_flush(trans, alloc_k, last_flushed);
- if (ret)
- return ret;
- }
-
bool empty = (sectors[ALLOC_dirty] +
sectors[ALLOC_stripe] +
sectors[ALLOC_cached]) == 0;
@@ -1148,8 +1101,6 @@ int bch2_check_extents_to_backpointers(struct bch_fs *c)
CLASS(btree_trans, trans)(c);
struct extents_to_bp_state s = { .bp_start = POS_MIN };
- struct bpos last_pos = POS_MIN;
- unsigned nr_iters = 0;
bch2_bkey_buf_init(&s.last_flushed);
bkey_init(&s.last_flushed.k->k);
@@ -1158,8 +1109,7 @@ int bch2_check_extents_to_backpointers(struct bch_fs *c)
POS_MIN, BTREE_ITER_prefetch, k, ({
bool had_mismatch;
bch2_fs_going_ro(c) ?:
- check_bucket_backpointer_mismatch(trans, k, &had_mismatch, &s.last_flushed,
- &last_pos, &nr_iters);
+ check_bucket_backpointer_mismatch(trans, k, &had_mismatch, &s.last_flushed);
}));
if (ret)
goto err;
@@ -1228,11 +1178,7 @@ static int check_bucket_backpointer_pos_mismatch(struct btree_trans *trans,
if (ret)
return ret;
- struct bpos last_pos = POS_MIN;
- unsigned nr_iters = 0;
- ret = check_bucket_backpointer_mismatch(trans, k, had_mismatch,
- last_flushed,
- &last_pos, &nr_iters);
+ ret = check_bucket_backpointer_mismatch(trans, k, had_mismatch, last_flushed);
bch2_trans_iter_exit(trans, &alloc_iter);
return ret;
}