Skip to content

Commit ad8d1f7

Browse files
author
Kent Overstreet
committed
bcachefs: bch2_dev_remove_stripes()
We can now correctly force-remove a device that has stripes on it; this uses the new BCH_SB_MEMBER_INVALID sentinal value. Signed-off-by: Kent Overstreet <[email protected]>
1 parent 934137b commit ad8d1f7

File tree

4 files changed

+74
-3
lines changed

4 files changed

+74
-3
lines changed

fs/bcachefs/alloc_background.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,18 +2310,19 @@ int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca)
23102310
* We clear the LRU and need_discard btrees first so that we don't race
23112311
* with bch2_do_invalidates() and bch2_do_discards()
23122312
*/
2313-
ret = bch2_btree_delete_range(c, BTREE_ID_lru, start, end,
2313+
ret = bch2_dev_remove_stripes(c, ca->dev_idx) ?:
2314+
bch2_btree_delete_range(c, BTREE_ID_lru, start, end,
23142315
BTREE_TRIGGER_norun, NULL) ?:
23152316
bch2_btree_delete_range(c, BTREE_ID_need_discard, start, end,
23162317
BTREE_TRIGGER_norun, NULL) ?:
23172318
bch2_btree_delete_range(c, BTREE_ID_freespace, start, end,
23182319
BTREE_TRIGGER_norun, NULL) ?:
23192320
bch2_btree_delete_range(c, BTREE_ID_backpointers, start, end,
23202321
BTREE_TRIGGER_norun, NULL) ?:
2321-
bch2_btree_delete_range(c, BTREE_ID_alloc, start, end,
2322-
BTREE_TRIGGER_norun, NULL) ?:
23232322
bch2_btree_delete_range(c, BTREE_ID_bucket_gens, start, end,
23242323
BTREE_TRIGGER_norun, NULL) ?:
2324+
bch2_btree_delete_range(c, BTREE_ID_alloc, start, end,
2325+
BTREE_TRIGGER_norun, NULL) ?:
23252326
bch2_dev_usage_remove(c, ca->dev_idx);
23262327
bch_err_msg(ca, ret, "removing dev alloc info");
23272328
return ret;

fs/bcachefs/ec.c

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,6 +2169,73 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans,
21692169
return ERR_PTR(ret);
21702170
}
21712171

2172+
/* device removal */
2173+
2174+
static int bch2_invalidate_stripe_to_dev(struct btree_trans *trans, struct bkey_s_c k_a)
2175+
{
2176+
struct bch_alloc_v4 a_convert;
2177+
const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k_a, &a_convert);
2178+
2179+
if (!a->stripe)
2180+
return 0;
2181+
2182+
if (a->stripe_sectors) {
2183+
bch_err(trans->c, "trying to invalidate device in stripe when bucket has stripe data");
2184+
return -BCH_ERR_invalidate_stripe_to_dev;
2185+
}
2186+
2187+
struct btree_iter iter;
2188+
struct bkey_i_stripe *s =
2189+
bch2_bkey_get_mut_typed(trans, &iter, BTREE_ID_stripes, POS(0, a->stripe),
2190+
BTREE_ITER_slots, stripe);
2191+
int ret = PTR_ERR_OR_ZERO(s);
2192+
if (ret)
2193+
return ret;
2194+
2195+
struct disk_accounting_pos acc = {
2196+
.type = BCH_DISK_ACCOUNTING_replicas,
2197+
};
2198+
2199+
s64 sectors = 0;
2200+
for (unsigned i = 0; i < s->v.nr_blocks; i++)
2201+
sectors -= stripe_blockcount_get(&s->v, i);
2202+
2203+
bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i));
2204+
acc.replicas.data_type = BCH_DATA_user;
2205+
ret = bch2_disk_accounting_mod(trans, &acc, &sectors, 1, false);
2206+
if (ret)
2207+
goto err;
2208+
2209+
struct bkey_ptrs ptrs = bch2_bkey_ptrs(bkey_i_to_s(&s->k_i));
2210+
bkey_for_each_ptr(ptrs, ptr)
2211+
if (ptr->dev == k_a.k->p.inode)
2212+
ptr->dev = BCH_SB_MEMBER_INVALID;
2213+
2214+
sectors = -sectors;
2215+
2216+
bch2_bkey_to_replicas(&acc.replicas, bkey_i_to_s_c(&s->k_i));
2217+
acc.replicas.data_type = BCH_DATA_user;
2218+
ret = bch2_disk_accounting_mod(trans, &acc, &sectors, 1, false);
2219+
if (ret)
2220+
goto err;
2221+
err:
2222+
bch2_trans_iter_exit(trans, &iter);
2223+
return ret;
2224+
}
2225+
2226+
int bch2_dev_remove_stripes(struct bch_fs *c, unsigned dev_idx)
2227+
{
2228+
return bch2_trans_run(c,
2229+
for_each_btree_key_upto_commit(trans, iter,
2230+
BTREE_ID_alloc, POS(dev_idx, 0), POS(dev_idx, U64_MAX),
2231+
BTREE_ITER_intent, k,
2232+
NULL, NULL, 0, ({
2233+
bch2_invalidate_stripe_to_dev(trans, k);
2234+
})));
2235+
}
2236+
2237+
/* startup/shutdown */
2238+
21722239
static void __bch2_ec_stop(struct bch_fs *c, struct bch_dev *ca)
21732240
{
21742241
struct ec_stripe_head *h;

fs/bcachefs/ec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,8 @@ static inline void ec_stripe_new_put(struct bch_fs *c, struct ec_stripe_new *s,
251251
}
252252
}
253253

254+
int bch2_dev_remove_stripes(struct bch_fs *, unsigned);
255+
254256
void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *);
255257
void bch2_fs_ec_stop(struct bch_fs *);
256258
void bch2_fs_ec_flush(struct bch_fs *);

fs/bcachefs/errcode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@
253253
x(EIO, key_type_error) \
254254
x(EIO, no_device_to_read_from) \
255255
x(EIO, missing_indirect_extent) \
256+
x(EIO, invalidate_stripe_to_dev) \
256257
x(BCH_ERR_btree_node_read_err, btree_node_read_err_fixable) \
257258
x(BCH_ERR_btree_node_read_err, btree_node_read_err_want_retry) \
258259
x(BCH_ERR_btree_node_read_err, btree_node_read_err_must_retry) \

0 commit comments

Comments
 (0)