summaryrefslogtreecommitdiff
path: root/fs/bcachefs/btree_io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2017-04-03 06:32:02 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2017-04-15 23:13:35 -0800
commit542fcc8798a7f8f4e94bea5278beeab74da84fe8 (patch)
tree82637659dce95e4ebe6e597d8a5a03540287659a /fs/bcachefs/btree_io.c
parent846600a41b7853588796a5403b07347d36c5a65c (diff)
replicated btree write error workaroundlacriatch-fix
Diffstat (limited to 'fs/bcachefs/btree_io.c')
-rw-r--r--fs/bcachefs/btree_io.c11
1 files changed, 9 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);