summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2017-12-30 03:35:53 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2018-05-22 00:44:18 -0400
commit4ea4b5a26b0d1200e8b419ea3c9ea2d2bde709c1 (patch)
tree56fd59bd50a6d217965ce41e7b79a8a2964d5077
parent63d9b3a02aed31f920636cb6a85381a8ce1a25f4 (diff)
bcachefs: fixes for evacuate
-rw-r--r--fs/bcachefs/migrate.c9
-rw-r--r--fs/bcachefs/super.c18
2 files changed, 20 insertions, 7 deletions
diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c
index 328316a10887..2bddb1b14fb9 100644
--- a/fs/bcachefs/migrate.c
+++ b/fs/bcachefs/migrate.c
@@ -36,8 +36,6 @@ static int bch2_dev_usrdata_migrate(struct bch_fs *c, struct bch_dev *ca,
unsigned pass = 0;
int ret = 0;
- BUG_ON(ca->mi.state == BCH_MEMBER_STATE_RW);
-
if (!(bch2_dev_has_data(c, ca) & (1 << BCH_DATA_USER)))
return 0;
@@ -106,8 +104,6 @@ static int bch2_move_btree_off(struct bch_fs *c, struct bch_dev *ca,
struct btree *b;
int ret;
- BUG_ON(ca->mi.state == BCH_MEMBER_STATE_RW);
-
for_each_btree_node(&iter, c, id, POS_MIN, BTREE_ITER_PREFETCH, b) {
struct bkey_s_c_extent e = bkey_i_to_s_c_extent(&b->key);
@@ -188,8 +184,6 @@ static int bch2_dev_metadata_migrate(struct bch_fs *c, struct bch_dev *ca,
unsigned i;
int ret = 0;
- BUG_ON(ca->mi.state == BCH_MEMBER_STATE_RW);
-
if (!(bch2_dev_has_data(c, ca) &
((1 << BCH_DATA_JOURNAL)|
(1 << BCH_DATA_BTREE))))
@@ -211,6 +205,9 @@ err:
int bch2_dev_data_migrate(struct bch_fs *c, struct bch_dev *ca, int flags)
{
+ BUG_ON(ca->mi.state == BCH_MEMBER_STATE_RW &&
+ bch2_dev_is_online(ca));
+
return bch2_dev_usrdata_migrate(c, ca, flags) ?:
bch2_dev_metadata_migrate(c, ca, flags);
}
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index bdf398680663..246236a9e0e5 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -1586,6 +1586,12 @@ int bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca, int flags)
{
mutex_lock(&c->state_lock);
+ if (!bch2_dev_is_online(ca)) {
+ bch_err(ca, "Already offline");
+ mutex_unlock(&c->state_lock);
+ return 0;
+ }
+
if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_FAILED, flags)) {
bch_err(ca, "Cannot offline required disk");
mutex_unlock(&c->state_lock);
@@ -1618,9 +1624,19 @@ int bch2_dev_evacuate(struct bch_fs *c, struct bch_dev *ca)
goto err;
}
+ ret = bch2_journal_flush_device(&c->journal, ca->dev_idx);
+ if (ret) {
+ bch_err(ca, "Migrate failed: error %i flushing journal", ret);
+ goto err;
+ }
+
data = bch2_dev_has_data(c, ca);
if (data) {
- bch_err(ca, "Migrate error: data still present (%x)", data);
+ char buf[100];
+
+ bch2_scnprint_flag_list(buf, sizeof(buf),
+ bch2_data_types, data);
+ bch_err(ca, "Migrate failed, still has data (%s)", buf);
ret = -EINVAL;
goto err;
}