summaryrefslogtreecommitdiff
path: root/fs/bcachefs/btree_io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2020-07-03 16:32:00 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:42 -0400
commitfff899b1d90089a3c77a20dbe48bd44a00161a6b (patch)
tree79b43640f5b39659c8ca538267539d8724714a16 /fs/bcachefs/btree_io.c
parent306d40df7d27c99a8ec63fc730747a77959c4358 (diff)
bcachefs: Mark btree nodes as needing rewrite when not all replicas are RW
This fixes a bug where recovery fails when one of the devices is read only. Also - consolidate the "must rewrite this node to insert it" behind a new btree node flag. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_io.c')
-rw-r--r--fs/bcachefs/btree_io.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c
index cb9abca07059..d5240598e7d3 100644
--- a/fs/bcachefs/btree_io.c
+++ b/fs/bcachefs/btree_io.c
@@ -917,6 +917,7 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
struct sort_iter *iter;
struct btree_node *sorted;
struct bkey_packed *k;
+ struct bch_extent_ptr *ptr;
struct bset *i;
bool used_mempool, blacklisted;
unsigned u64s;
@@ -971,8 +972,10 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
bset_encrypt(c, i, b->written << 9);
if (btree_node_is_extents(b) &&
- !BTREE_NODE_NEW_EXTENT_OVERWRITE(b->data))
+ !BTREE_NODE_NEW_EXTENT_OVERWRITE(b->data)) {
set_btree_node_old_extent_overwrite(b);
+ set_btree_node_need_rewrite(b);
+ }
sectors = vstruct_sectors(b->data, c->block_bits);
} else {
@@ -1098,6 +1101,13 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct btree *b, bool have_retry
set_needs_whiteout(btree_bset_first(b), true);
btree_node_reset_sib_u64s(b);
+
+ bkey_for_each_ptr(bch2_bkey_ptrs(bkey_i_to_s(&b->key)), ptr) {
+ struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
+
+ if (ca->mi.state != BCH_MEMBER_STATE_RW)
+ set_btree_node_need_rewrite(b);
+ }
out:
mempool_free(iter, &c->fill_iter);
return retry_read;