From: Kent Overstreet Date: Fri, 28 Feb 2025 16:37:36 +0000 (-0500) Subject: bcachefs: data_update now checks for extents that can't be moved X-Git-Tag: io_uring-6.15-20250403~68^2~75 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=7bc580816869e31c121eefe26e7eaccd4e3b778b;p=linux-block.git 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: Kent Overstreet --- diff --git a/fs/bcachefs/data_update.c b/fs/bcachefs/data_update.c index 7e484afea551..522574bc4197 100644 --- a/fs/bcachefs/data_update.c +++ b/fs/bcachefs/data_update.c @@ -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)); /* diff --git a/fs/bcachefs/errcode.h b/fs/bcachefs/errcode.h index 0d9a8198e95e..ed4214e9beba 100644 --- a/fs/bcachefs/errcode.h +++ b/fs/bcachefs/errcode.h @@ -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) \