Loading fs/bcachefs/buckets.c +133 −116 Original line number Diff line number Diff line Loading @@ -465,21 +465,16 @@ int bch2_update_cached_sectors_list(struct btree_trans *trans, unsigned dev, s64 return bch2_update_replicas_list(trans, &r.e, sectors); } int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree, unsigned level, struct bkey_s_c k, enum btree_iter_update_trigger_flags flags) static int bch2_check_fix_ptr(struct btree_trans *trans, struct bkey_s_c k, struct extent_ptr_decoded p, const union bch_extent_entry *entry, bool *do_update) { struct bch_fs *c = trans->c; struct bkey_ptrs_c ptrs_c = bch2_bkey_ptrs_c(k); const union bch_extent_entry *entry_c; struct extent_ptr_decoded p = { 0 }; bool do_update = false; struct printbuf buf = PRINTBUF; int ret = 0; percpu_down_read(&c->mark_lock); bkey_for_each_ptr_decode(k.k, ptrs_c, p, entry_c) { struct bch_dev *ca = bch2_dev_tryget(c, p.ptr.dev); if (!ca) { if (fsck_err(c, ptr_to_invalid_device, Loading @@ -488,12 +483,12 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, p.ptr.dev, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; continue; *do_update = true; return 0; } struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr); enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry_c); enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry); if (fsck_err_on(!g->gen_valid, c, ptr_to_missing_alloc_key, Loading @@ -508,7 +503,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, g->gen_valid = true; g->gen = p.ptr.gen; } else { do_update = true; *do_update = true; } } Loading @@ -530,7 +525,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, g->dirty_sectors = 0; g->cached_sectors = 0; } else { do_update = true; *do_update = true; } } Loading @@ -543,7 +538,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, p.ptr.gen, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; *do_update = true; if (fsck_err_on(!p.ptr.cached && gen_cmp(p.ptr.gen, g->gen) < 0, c, stale_dirty_ptr, Loading @@ -554,10 +549,10 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, p.ptr.gen, g->gen, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; *do_update = true; if (data_type != BCH_DATA_btree && p.ptr.gen != g->gen) goto next; goto out; if (fsck_err_on(bucket_data_type_mismatch(g->data_type, data_type), c, ptr_bucket_data_type_mismatch, Loading @@ -575,7 +570,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, g->dirty_sectors = 0; g->cached_sectors = 0; } else { do_update = true; *do_update = true; } } Loading @@ -589,7 +584,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, (u64) p.ec.idx, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; *do_update = true; if (fsck_err_on(m && m->alive && !bch2_ptr_matches_stripe_m(m, p), c, ptr_to_incorrect_stripe, Loading @@ -598,10 +593,33 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, (u64) p.ec.idx, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; *do_update = true; } next: out: fsck_err: bch2_dev_put(ca); printbuf_exit(&buf); return ret; } int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree, unsigned level, struct bkey_s_c k, enum btree_iter_update_trigger_flags flags) { struct bch_fs *c = trans->c; struct bkey_ptrs_c ptrs_c = bch2_bkey_ptrs_c(k); const union bch_extent_entry *entry_c; struct extent_ptr_decoded p = { 0 }; bool do_update = false; struct printbuf buf = PRINTBUF; int ret = 0; percpu_down_read(&c->mark_lock); bkey_for_each_ptr_decode(k.k, ptrs_c, p, entry_c) { ret = bch2_check_fix_ptr(trans, k, p, entry_c, &do_update); if (ret) goto err; } if (do_update) { Loading Loading @@ -716,7 +734,6 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, bch2_btree_node_update_key_early(trans, btree, level - 1, k, new); } err: fsck_err: percpu_up_read(&c->mark_lock); printbuf_exit(&buf); return ret; Loading Loading
fs/bcachefs/buckets.c +133 −116 Original line number Diff line number Diff line Loading @@ -465,21 +465,16 @@ int bch2_update_cached_sectors_list(struct btree_trans *trans, unsigned dev, s64 return bch2_update_replicas_list(trans, &r.e, sectors); } int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree, unsigned level, struct bkey_s_c k, enum btree_iter_update_trigger_flags flags) static int bch2_check_fix_ptr(struct btree_trans *trans, struct bkey_s_c k, struct extent_ptr_decoded p, const union bch_extent_entry *entry, bool *do_update) { struct bch_fs *c = trans->c; struct bkey_ptrs_c ptrs_c = bch2_bkey_ptrs_c(k); const union bch_extent_entry *entry_c; struct extent_ptr_decoded p = { 0 }; bool do_update = false; struct printbuf buf = PRINTBUF; int ret = 0; percpu_down_read(&c->mark_lock); bkey_for_each_ptr_decode(k.k, ptrs_c, p, entry_c) { struct bch_dev *ca = bch2_dev_tryget(c, p.ptr.dev); if (!ca) { if (fsck_err(c, ptr_to_invalid_device, Loading @@ -488,12 +483,12 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, p.ptr.dev, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; continue; *do_update = true; return 0; } struct bucket *g = PTR_GC_BUCKET(ca, &p.ptr); enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry_c); enum bch_data_type data_type = bch2_bkey_ptr_data_type(k, p, entry); if (fsck_err_on(!g->gen_valid, c, ptr_to_missing_alloc_key, Loading @@ -508,7 +503,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, g->gen_valid = true; g->gen = p.ptr.gen; } else { do_update = true; *do_update = true; } } Loading @@ -530,7 +525,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, g->dirty_sectors = 0; g->cached_sectors = 0; } else { do_update = true; *do_update = true; } } Loading @@ -543,7 +538,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, p.ptr.gen, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; *do_update = true; if (fsck_err_on(!p.ptr.cached && gen_cmp(p.ptr.gen, g->gen) < 0, c, stale_dirty_ptr, Loading @@ -554,10 +549,10 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, p.ptr.gen, g->gen, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; *do_update = true; if (data_type != BCH_DATA_btree && p.ptr.gen != g->gen) goto next; goto out; if (fsck_err_on(bucket_data_type_mismatch(g->data_type, data_type), c, ptr_bucket_data_type_mismatch, Loading @@ -575,7 +570,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, g->dirty_sectors = 0; g->cached_sectors = 0; } else { do_update = true; *do_update = true; } } Loading @@ -589,7 +584,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, (u64) p.ec.idx, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; *do_update = true; if (fsck_err_on(m && m->alive && !bch2_ptr_matches_stripe_m(m, p), c, ptr_to_incorrect_stripe, Loading @@ -598,10 +593,33 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, (u64) p.ec.idx, (printbuf_reset(&buf), bch2_bkey_val_to_text(&buf, c, k), buf.buf))) do_update = true; *do_update = true; } next: out: fsck_err: bch2_dev_put(ca); printbuf_exit(&buf); return ret; } int bch2_check_fix_ptrs(struct btree_trans *trans, enum btree_id btree, unsigned level, struct bkey_s_c k, enum btree_iter_update_trigger_flags flags) { struct bch_fs *c = trans->c; struct bkey_ptrs_c ptrs_c = bch2_bkey_ptrs_c(k); const union bch_extent_entry *entry_c; struct extent_ptr_decoded p = { 0 }; bool do_update = false; struct printbuf buf = PRINTBUF; int ret = 0; percpu_down_read(&c->mark_lock); bkey_for_each_ptr_decode(k.k, ptrs_c, p, entry_c) { ret = bch2_check_fix_ptr(trans, k, p, entry_c, &do_update); if (ret) goto err; } if (do_update) { Loading Loading @@ -716,7 +734,6 @@ int bch2_check_fix_ptrs(struct btree_trans *trans, bch2_btree_node_update_key_early(trans, btree, level - 1, k, new); } err: fsck_err: percpu_up_read(&c->mark_lock); printbuf_exit(&buf); return ret; Loading