Commit 7bc58081 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: data_update now checks for extents that can't be moved



If a device is ro or failed, we might not have anywhere to move a
replica.

Check for this early, before doing the read and attempting to write.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent fba513a9
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
@@ -573,7 +573,6 @@ void bch2_data_update_opts_to_text(struct printbuf *out, struct bch_fs *c,

	prt_str_indented(out, "extra replicas:\t");
	prt_u64(out, data_opts->extra_replicas);
	prt_newline(out);
}

void bch2_data_update_to_text(struct printbuf *out, struct data_update *m)
@@ -707,6 +706,18 @@ int bch2_data_update_bios_init(struct data_update *m, struct bch_fs *c,
	return 0;
}

static bool can_write_extent(struct bch_fs *c,
			     struct bch_devs_list *devs_have,
			     unsigned target)
{
	struct bch_devs_mask devs = target_rw_devs(c, BCH_DATA_user, target);

	darray_for_each(*devs_have, i)
		__clear_bit(*i, devs.d);

	return !bch2_is_zero(&devs, sizeof(devs));
}

int bch2_data_update_init(struct btree_trans *trans,
			  struct btree_iter *iter,
			  struct moving_context *ctxt,
@@ -788,6 +799,20 @@ int bch2_data_update_init(struct btree_trans *trans,
		ptr_bit <<= 1;
	}

	if (!can_write_extent(c, &m->op.devs_have,
			      m->op.flags & BCH_WRITE_only_specified_devs ? m->op.target : 0)) {
		/*
		 * Check if we have rw devices not in devs_have: this can happen
		 * if we're trying to move data on a ro or failed device
		 *
		 * If we can't move it, we need to clear the rebalance_work bit,
		 * if applicable
		 *
		 * Also, copygc should skip ro/failed devices:
		 */
		return -BCH_ERR_data_update_done_no_rw_devs;
	}

	unsigned durability_required = max(0, (int) (io_opts->data_replicas - durability_have));

	/*
+1 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@
	x(BCH_ERR_data_update_done,	data_update_done_no_writes_needed)	\
	x(BCH_ERR_data_update_done,	data_update_done_no_snapshot)		\
	x(BCH_ERR_data_update_done,	data_update_done_no_dev_refs)		\
	x(BCH_ERR_data_update_done,	data_update_done_no_rw_devs)		\
	x(EINVAL,			device_state_not_allowed)		\
	x(EINVAL,			member_info_missing)			\
	x(EINVAL,			mismatched_block_size)			\