Commit 4e074475 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Clamp replicas_required to replicas



This prevents going emergency read only when the user has specified
replicas_required > replicas.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 04eb5793
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1249,6 +1249,18 @@ static inline struct stdio_redirect *bch2_fs_stdio_redirect(struct bch_fs *c)
	return stdio;
}

static inline unsigned metadata_replicas_required(struct bch_fs *c)
{
	return min(c->opts.metadata_replicas,
		   c->opts.metadata_replicas_required);
}

static inline unsigned data_replicas_required(struct bch_fs *c)
{
	return min(c->opts.data_replicas,
		   c->opts.data_replicas_required);
}

#define BKEY_PADDED_ONSTACK(key, pad)				\
	struct { struct bkey_i key; __u64 key ## _pad[pad]; }

+2 −1
Original line number Diff line number Diff line
@@ -280,7 +280,8 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans,
				      writepoint_ptr(&c->btree_write_point),
				      &devs_have,
				      res->nr_replicas,
				      c->opts.metadata_replicas_required,
				      min(res->nr_replicas,
					  c->opts.metadata_replicas_required),
				      watermark, 0, cl, &wp);
	if (unlikely(ret))
		return ERR_PTR(ret);
+1 −0
Original line number Diff line number Diff line
@@ -1564,6 +1564,7 @@ CLOSURE_CALLBACK(bch2_write)
	BUG_ON(!op->write_point.v);
	BUG_ON(bkey_eq(op->pos, POS_MAX));

	op->nr_replicas_required = min_t(unsigned, op->nr_replicas_required, op->nr_replicas);
	op->start_time = local_clock();
	bch2_keylist_init(&op->insert_keys, op->inline_keys);
	wbio_init(bio)->put_bio = false;
+3 −1
Original line number Diff line number Diff line
@@ -1478,6 +1478,8 @@ static int journal_write_alloc(struct journal *j, struct journal_buf *w)
		c->opts.foreground_target;
	unsigned i, replicas = 0, replicas_want =
		READ_ONCE(c->opts.metadata_replicas);
	unsigned replicas_need = min_t(unsigned, replicas_want,
				       READ_ONCE(c->opts.metadata_replicas_required));

	rcu_read_lock();
retry:
@@ -1526,7 +1528,7 @@ static int journal_write_alloc(struct journal *j, struct journal_buf *w)

	BUG_ON(bkey_val_u64s(&w->key.k) > BCH_REPLICAS_MAX);

	return replicas >= c->opts.metadata_replicas_required ? 0 : -EROFS;
	return replicas >= replicas_need ? 0 : -EROFS;
}

static void journal_buf_realloc(struct journal *j, struct journal_buf *buf)
+1 −1
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ void bch2_journal_space_available(struct journal *j)

	j->can_discard = can_discard;

	if (nr_online < c->opts.metadata_replicas_required) {
	if (nr_online < metadata_replicas_required(c)) {
		ret = JOURNAL_ERR_insufficient_devices;
		goto out;
	}
Loading