diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2025-04-22 20:38:50 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-04-28 22:42:22 -0400 |
commit | c0ffe4f20cbf843f08573d9f7cc6ab3c191f1cc5 (patch) | |
tree | 427b73a7f05e524f5bd46c9a3f3fd363722d4e12 | |
parent | 8756e1ec5914c4d0d05688911ac7152bee073ff1 (diff) |
bcachefs: bch2_mark_btree_validate_failure()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/extents.c | 31 | ||||
-rw-r--r-- | fs/bcachefs/extents.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/extents_types.h | 1 |
3 files changed, 28 insertions, 5 deletions
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c index 7ae8b8ca8495..18506061361a 100644 --- a/fs/bcachefs/extents.c +++ b/fs/bcachefs/extents.c @@ -56,6 +56,14 @@ void bch2_io_failures_to_text(struct printbuf *out, for (struct bch_dev_io_failures *f = failed->devs; f < failed->devs + failed->nr; f++) { + unsigned errflags = + ((!!f->failed_io) << 0) | + ((!!f->failed_csum_nr) << 1) | + ((!!f->failed_ec) << 2); + + if (!errflags) + continue; + bch2_printbuf_make_room(out, 1024); rcu_read_lock(); out->atomic++; @@ -69,11 +77,6 @@ void bch2_io_failures_to_text(struct printbuf *out, prt_char(out, ' '); - unsigned errflags = - ((!!f->failed_io) << 0) | - ((!!f->failed_csum_nr) << 1) | - ((!!f->failed_ec) << 2); - if (is_power_of_2(errflags)) { prt_bitflags(out, error_types, errflags); prt_str(out, " error"); @@ -119,6 +122,22 @@ void bch2_mark_io_failure(struct bch_io_failures *failed, f->failed_csum_nr++; } +void bch2_mark_btree_validate_failure(struct bch_io_failures *failed, + unsigned dev) +{ + struct bch_dev_io_failures *f = bch2_dev_io_failures(failed, dev); + + if (!f) { + BUG_ON(failed->nr >= ARRAY_SIZE(failed->devs)); + + f = &failed->devs[failed->nr++]; + memset(f, 0, sizeof(*f)); + f->dev = dev; + } + + f->failed_btree_validate = true; +} + static inline u64 dev_latency(struct bch_dev *ca) { return ca ? atomic64_read(&ca->cur_latency[READ]) : S64_MAX; @@ -219,6 +238,7 @@ int bch2_bkey_pick_read_device(struct bch_fs *c, struct bkey_s_c k, if (ca && ca->mi.state != BCH_MEMBER_STATE_failed) { have_io_errors |= f->failed_io; + have_io_errors |= f->failed_btree_validate; have_io_errors |= f->failed_ec; } have_csum_errors |= !!f->failed_csum_nr; @@ -226,6 +246,7 @@ int bch2_bkey_pick_read_device(struct bch_fs *c, struct bkey_s_c k, if (p.has_ec && (f->failed_io || f->failed_csum_nr)) p.do_ec_reconstruct = true; else if (f->failed_io || + f->failed_btree_validate || f->failed_csum_nr > c->opts.checksum_err_retry_nr) continue; } diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h index d7aab3b50db9..f25be08d3528 100644 --- a/fs/bcachefs/extents.h +++ b/fs/bcachefs/extents.h @@ -405,6 +405,7 @@ struct bch_dev_io_failures *bch2_dev_io_failures(struct bch_io_failures *, unsigned); void bch2_mark_io_failure(struct bch_io_failures *, struct extent_ptr_decoded *, bool); +void bch2_mark_btree_validate_failure(struct bch_io_failures *, unsigned); int bch2_bkey_pick_read_device(struct bch_fs *, struct bkey_s_c, struct bch_io_failures *, struct extent_ptr_decoded *, int); diff --git a/fs/bcachefs/extents_types.h b/fs/bcachefs/extents_types.h index e51529dca4c2..b23ce4a373c0 100644 --- a/fs/bcachefs/extents_types.h +++ b/fs/bcachefs/extents_types.h @@ -34,6 +34,7 @@ struct bch_io_failures { u8 dev; unsigned failed_csum_nr:6, failed_io:1, + failed_btree_validate:1, failed_ec:1; } devs[BCH_REPLICAS_MAX + 1]; }; |