diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-04-09 15:15:36 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2022-04-17 15:44:31 -0400 |
commit | 6adf13a45513dcc2c2a8cafe292157ddbcc6a42c (patch) | |
tree | ca049f0c46a0902f09816bd182eaba64d70085e7 /fs/bcachefs/super.c | |
parent | af31e5417aee386eae1bd5ab9bf4e51af6b5f015 (diff) |
bcachefs: Minor device removal fixes
- We weren't clearing the LRU btree
- bch2_alloc_read() runs before bch2_check_alloc_key() deletes alloc
keys for devices/buckets that don't exists, so it needs to check for
that
- bch2_check_lrus() needs to check that buckets exists
- improve some error messages
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/super.c')
-rw-r--r-- | fs/bcachefs/super.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index aba679c6f30f..1401cb576fa2 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -1420,11 +1420,17 @@ static int bch2_dev_remove_alloc(struct bch_fs *c, struct bch_dev *ca) struct bpos end = POS(ca->dev_idx, U64_MAX); int ret; - ret = bch2_btree_delete_range(c, BTREE_ID_alloc, start, end, + /* + * 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, + BTREE_TRIGGER_NORUN, NULL) ?: + bch2_btree_delete_range(c, BTREE_ID_need_discard, start, end, BTREE_TRIGGER_NORUN, NULL) ?: bch2_btree_delete_range(c, BTREE_ID_freespace, start, end, BTREE_TRIGGER_NORUN, NULL) ?: - bch2_btree_delete_range(c, BTREE_ID_need_discard, start, end, + bch2_btree_delete_range(c, BTREE_ID_alloc, start, end, BTREE_TRIGGER_NORUN, NULL); if (ret) bch_err(c, "error %i removing dev alloc info", ret); @@ -1459,19 +1465,19 @@ int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags) goto err; } - ret = bch2_journal_flush_device_pins(&c->journal, ca->dev_idx); + ret = bch2_dev_remove_alloc(c, ca); if (ret) { - bch_err(ca, "Remove failed: error %i flushing journal", ret); + bch_err(ca, "Remove failed, error deleting alloc info"); goto err; } - ret = bch2_dev_remove_alloc(c, ca); + ret = bch2_journal_flush_device_pins(&c->journal, ca->dev_idx); if (ret) { - bch_err(ca, "Remove failed, error deleting alloc info"); + bch_err(ca, "Remove failed: error %i flushing journal", ret); goto err; } - ret = bch2_journal_error(&c->journal); + ret = bch2_journal_flush(&c->journal); if (ret) { bch_err(ca, "Remove failed, journal error"); goto err; |