Loading fs/bcachefs/alloc_background.c +4 −3 Original line number Diff line number Diff line Loading @@ -2310,7 +2310,8 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca) * We clear the LRU and need_discard btrees first so that we don't race * with bch2_do_invalidates() and bch2_do_discards() */ ret = bch2_btree_delete_range(c, BTREE_ID_lru, start, end, ret = bch2_dev_remove_stripes(c, ca->dev_idx) ?: bch2_btree_delete_range(c, BTREE_ID_lru, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_need_discard, start, end, BTREE_TRIGGER_norun, NULL) ?: Loading @@ -2318,10 +2319,10 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca) BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_backpointers, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_alloc, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_bucket_gens, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_alloc, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_dev_usage_remove(c, ca->dev_idx); bch_err_msg(ca, ret, "removing dev alloc info"); return ret; Loading fs/bcachefs/ec.c +67 −0 Original line number Diff line number Diff line Loading @@ -2169,6 +2169,73 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans, return ERR_PTR(ret); } /* device removal */ static int bch2_invalidate_stripe_to_dev(struct btree_trans *trans, struct bkey_s_c k_a) { struct bch_alloc_v4 a_convert; const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k_a, &a_convert); if (!a->stripe) return 0; if (a->stripe_sectors) { bch_err(trans->c, "trying to invalidate device in stripe when bucket has stripe data"); return -BCH_ERR_invalidate_stripe_to_dev; } struct btree_iter iter; struct bkey_i_stripe *s = bch2_bkey_get_mut_typed(trans, &iter, BTREE_ID_stripes, POS(0, a->stripe), BTREE_ITER_slots, stripe); int ret = PTR_ERR_OR_ZERO(s); if (ret) return ret; struct disk_accounting_pos acc = { .type = BCH_DISK_ACCOUNTING_replicas, }; s64 sectors = 0; for (unsigned i = 0; i < s->v.nr_blocks; i++) sectors -= stripe_blockcount_get(&s->v, i); bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i)); acc.replicas.data_type = BCH_DATA_user; ret = bch2_disk_accounting_mod(trans, &acc, §ors, 1, false); if (ret) goto err; struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(&s->k_i)); bkey_for_each_ptr(ptrs, ptr) if (ptr->dev == k_a.k->p.inode) ptr->dev = BCH_SB_MEMBER_INVALID; sectors = -sectors; bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i)); acc.replicas.data_type = BCH_DATA_user; ret = bch2_disk_accounting_mod(trans, &acc, §ors, 1, false); if (ret) goto err; err: bch2_trans_iter_exit(trans, &iter); return ret; } int bch2_dev_remove_stripes(struct bch_fs *c, unsigned dev_idx) { return bch2_trans_run(c, for_each_btree_key_upto_commit(trans, iter, BTREE_ID_alloc, POS(dev_idx, 0), POS(dev_idx, U64_MAX), BTREE_ITER_intent, k, NULL, NULL, 0, ({ bch2_invalidate_stripe_to_dev(trans, k); }))); } /* startup/shutdown */ static void __bch2_ec_stop(struct bch_fs *c, struct bch_dev *ca) { struct ec_stripe_head *h; Loading fs/bcachefs/ec.h +2 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,8 @@ static inline void ec_stripe_new_put(struct bch_fs *c, struct ec_stripe_new *s, } } int bch2_dev_remove_stripes(struct bch_fs *, unsigned); void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *); void bch2_fs_ec_stop(struct bch_fs *); void bch2_fs_ec_flush(struct bch_fs *); Loading fs/bcachefs/errcode.h +1 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,7 @@ x(EIO, key_type_error) \ x(EIO, no_device_to_read_from) \ x(EIO, missing_indirect_extent) \ x(EIO, invalidate_stripe_to_dev) \ x(BCH_ERR_btree_node_read_err, btree_node_read_err_fixable) \ x(BCH_ERR_btree_node_read_err, btree_node_read_err_want_retry) \ x(BCH_ERR_btree_node_read_err, btree_node_read_err_must_retry) \ Loading Loading
fs/bcachefs/alloc_background.c +4 −3 Original line number Diff line number Diff line Loading @@ -2310,7 +2310,8 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca) * We clear the LRU and need_discard btrees first so that we don't race * with bch2_do_invalidates() and bch2_do_discards() */ ret = bch2_btree_delete_range(c, BTREE_ID_lru, start, end, ret = bch2_dev_remove_stripes(c, ca->dev_idx) ?: bch2_btree_delete_range(c, BTREE_ID_lru, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_need_discard, start, end, BTREE_TRIGGER_norun, NULL) ?: Loading @@ -2318,10 +2319,10 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca) BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_backpointers, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_alloc, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_bucket_gens, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_alloc, start, end, BTREE_TRIGGER_norun, NULL) ?: bch2_dev_usage_remove(c, ca->dev_idx); bch_err_msg(ca, ret, "removing dev alloc info"); return ret; Loading
fs/bcachefs/ec.c +67 −0 Original line number Diff line number Diff line Loading @@ -2169,6 +2169,73 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans, return ERR_PTR(ret); } /* device removal */ static int bch2_invalidate_stripe_to_dev(struct btree_trans *trans, struct bkey_s_c k_a) { struct bch_alloc_v4 a_convert; const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k_a, &a_convert); if (!a->stripe) return 0; if (a->stripe_sectors) { bch_err(trans->c, "trying to invalidate device in stripe when bucket has stripe data"); return -BCH_ERR_invalidate_stripe_to_dev; } struct btree_iter iter; struct bkey_i_stripe *s = bch2_bkey_get_mut_typed(trans, &iter, BTREE_ID_stripes, POS(0, a->stripe), BTREE_ITER_slots, stripe); int ret = PTR_ERR_OR_ZERO(s); if (ret) return ret; struct disk_accounting_pos acc = { .type = BCH_DISK_ACCOUNTING_replicas, }; s64 sectors = 0; for (unsigned i = 0; i < s->v.nr_blocks; i++) sectors -= stripe_blockcount_get(&s->v, i); bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i)); acc.replicas.data_type = BCH_DATA_user; ret = bch2_disk_accounting_mod(trans, &acc, §ors, 1, false); if (ret) goto err; struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(&s->k_i)); bkey_for_each_ptr(ptrs, ptr) if (ptr->dev == k_a.k->p.inode) ptr->dev = BCH_SB_MEMBER_INVALID; sectors = -sectors; bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i)); acc.replicas.data_type = BCH_DATA_user; ret = bch2_disk_accounting_mod(trans, &acc, §ors, 1, false); if (ret) goto err; err: bch2_trans_iter_exit(trans, &iter); return ret; } int bch2_dev_remove_stripes(struct bch_fs *c, unsigned dev_idx) { return bch2_trans_run(c, for_each_btree_key_upto_commit(trans, iter, BTREE_ID_alloc, POS(dev_idx, 0), POS(dev_idx, U64_MAX), BTREE_ITER_intent, k, NULL, NULL, 0, ({ bch2_invalidate_stripe_to_dev(trans, k); }))); } /* startup/shutdown */ static void __bch2_ec_stop(struct bch_fs *c, struct bch_dev *ca) { struct ec_stripe_head *h; Loading
fs/bcachefs/ec.h +2 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,8 @@ static inline void ec_stripe_new_put(struct bch_fs *c, struct ec_stripe_new *s, } } int bch2_dev_remove_stripes(struct bch_fs *, unsigned); void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *); void bch2_fs_ec_stop(struct bch_fs *); void bch2_fs_ec_flush(struct bch_fs *); Loading
fs/bcachefs/errcode.h +1 −0 Original line number Diff line number Diff line Loading @@ -253,6 +253,7 @@ x(EIO, key_type_error) \ x(EIO, no_device_to_read_from) \ x(EIO, missing_indirect_extent) \ x(EIO, invalidate_stripe_to_dev) \ x(BCH_ERR_btree_node_read_err, btree_node_read_err_fixable) \ x(BCH_ERR_btree_node_read_err, btree_node_read_err_want_retry) \ x(BCH_ERR_btree_node_read_err, btree_node_read_err_must_retry) \ Loading