diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/backpointers.c | 72 |
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; } |