diff options
-rw-r--r-- | fs/bcachefs/btree_io.c | 11 | ||||
-rw-r--r-- | fs/bcachefs/btree_types.h | 2 |
2 files changed, 11 insertions, 2 deletions
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c index 82dd196d6cdd..4418bc1f55ac 100644 --- a/fs/bcachefs/btree_io.c +++ b/fs/bcachefs/btree_io.c @@ -1291,6 +1291,11 @@ void bch2_btree_complete_write(struct bch_fs *c, struct btree *b, static void btree_node_write_done(struct bch_fs *c, struct btree *b) { struct btree_write *w = btree_prev_write(b); + int failed = atomic_read(&b->nr_replicas_failed); + + if (failed && + ((int) bch2_extent_nr_ptrs(bkey_i_to_s_c_extent(&b->key)) - failed < 1)) + set_btree_node_write_error(b); /* * Before calling bch2_btree_complete_write() - if the write errored, we @@ -1313,9 +1318,9 @@ static void btree_node_write_endio(struct bio *bio) struct closure *cl = !wbio->split ? wbio->cl : NULL; struct bch_dev *ca = wbio->ca; - if (bch2_dev_fatal_io_err_on(bio->bi_error, ca, "btree write") || + if (bch2_dev_nonfatal_io_err_on(bio->bi_error, ca, "btree write") || bch2_meta_write_fault("btree")) - set_btree_node_write_error(b); + atomic_inc(&b->nr_replicas_failed); if (wbio->have_io_ref) percpu_ref_put(&ca->io_ref); @@ -1413,6 +1418,8 @@ void __bch2_btree_node_write(struct bch_fs *c, struct btree *b, BUG_ON(le64_to_cpu(b->data->magic) != bset_magic(c)); BUG_ON(memcmp(&b->data->format, &b->format, sizeof(b->format))); + atomic_set(&b->nr_replicas_failed, 0); + if (lock_type_held == SIX_LOCK_intent) { six_lock_write(&b->lock); __bch2_compact_whiteouts(c, b, COMPACT_WRITTEN); diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index a0f5b579fe2a..708f5c314dcb 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -92,6 +92,8 @@ struct btree { u8 page_order; u8 unpack_fn_len; + atomic_t nr_replicas_failed; + /* * XXX: add a delete sequence number, so when bch2_btree_node_relock() * fails because the lock sequence number has changed - i.e. the |