summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-12-31 18:42:48 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2025-01-14 10:45:31 -0500
commit78423deb51ed5acd2ae5e2b7212a14a0da01b39a (patch)
tree2011af372487a429c9214a95ca012cdb96be9539
parent5dd21b27121985cef0642d0cb89cfd749393b727 (diff)
bcachefs: Fix self healing on read error
We were incorrectly checking if there'd been an io error. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/io_read.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/bcachefs/io_read.c b/fs/bcachefs/io_read.c
index 34a3569d085a..8c7b2d3d779d 100644
--- a/fs/bcachefs/io_read.c
+++ b/fs/bcachefs/io_read.c
@@ -91,13 +91,18 @@ static const struct rhashtable_params bch_promote_params = {
.automatic_shrinking = true,
};
+static inline bool have_io_error(struct bch_io_failures *failed)
+{
+ return failed && failed->nr;
+}
+
static inline int should_promote(struct bch_fs *c, struct bkey_s_c k,
struct bpos pos,
struct bch_io_opts opts,
unsigned flags,
struct bch_io_failures *failed)
{
- if (!failed) {
+ if (!have_io_error(failed)) {
BUG_ON(!opts.promote_target);
if (!(flags & BCH_READ_MAY_PROMOTE))
@@ -224,7 +229,7 @@ static struct promote_op *__promote_alloc(struct btree_trans *trans,
struct data_update_opts update_opts = {};
- if (!failed) {
+ if (!have_io_error(failed)) {
update_opts.target = opts.promote_target;
update_opts.extra_replicas = 1;
update_opts.write_flags = BCH_WRITE_ALLOC_NOWAIT|BCH_WRITE_CACHED;
@@ -286,7 +291,7 @@ static struct promote_op *promote_alloc(struct btree_trans *trans,
* if failed != NULL we're not actually doing a promote, we're
* recovering from an io/checksum error
*/
- bool promote_full = (failed ||
+ bool promote_full = (have_io_error(failed) ||
*read_full ||
READ_ONCE(c->opts.promote_whole_extents));
/* data might have to be decompressed in the write path: */
@@ -989,7 +994,7 @@ retry_pick:
bounce = true;
}
- if (orig->opts.promote_target)// || failed)
+ if (orig->opts.promote_target || have_io_error(failed))
promote = promote_alloc(trans, iter, k, &pick, orig->opts, flags,
&rbio, &bounce, &read_full, failed);