Commit bbe682c7 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Ensure devices are always correctly initialized



We can't mark device superblocks or allocate journal on a device that
isn't online.

That means we may need to do this on every mount, because we may have
formatted a new filesystem and then done the first mount
(bch2_fs_initialize()) in degraded mode.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent d0261559
Loading
Loading
Loading
Loading
+24 −8
Original line number Diff line number Diff line
@@ -1825,16 +1825,16 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
			bch2_data_types[type],
			bch2_data_types[type]);
		ret = -EIO;
		goto out;
		goto err;
	}

	if (a->v.data_type	!= type ||
	    a->v.dirty_sectors	!= sectors) {
		a->v.data_type		= type;
		a->v.dirty_sectors	= sectors;

		ret = bch2_trans_update(trans, &iter, &a->k_i, 0);
	if (ret)
		goto out;
out:
	}
err:
	bch2_trans_iter_exit(trans, &iter);
	return ret;
}
@@ -1929,6 +1929,22 @@ int bch2_trans_mark_dev_sb(struct bch_fs *c, struct bch_dev *ca)
	return ret;
}

int bch2_trans_mark_dev_sbs(struct bch_fs *c)
{
	struct bch_dev *ca;
	unsigned i;

	for_each_online_member(ca, c, i) {
		int ret = bch2_trans_mark_dev_sb(c, ca);
		if (ret) {
			percpu_ref_put(&ca->ref);
			return ret;
		}
	}

	return 0;
}

/* Disk reservations: */

#define SECTORS_CACHE	1024
+1 −0
Original line number Diff line number Diff line
@@ -345,6 +345,7 @@ int bch2_trans_fs_usage_apply(struct btree_trans *, struct replicas_delta_list *
int bch2_trans_mark_metadata_bucket(struct btree_trans *, struct bch_dev *,
				    size_t, enum bch_data_type, unsigned);
int bch2_trans_mark_dev_sb(struct bch_fs *, struct bch_dev *);
int bch2_trans_mark_dev_sbs(struct bch_fs *);

static inline bool is_superblock_bucket(struct bch_dev *ca, u64 b)
{
+19 −0
Original line number Diff line number Diff line
@@ -1019,6 +1019,25 @@ int bch2_dev_journal_alloc(struct bch_dev *ca)
	return ret;
}

int bch2_fs_journal_alloc(struct bch_fs *c)
{
	struct bch_dev *ca;
	unsigned i;

	for_each_online_member(ca, c, i) {
		if (ca->journal.nr)
			continue;

		int ret = bch2_dev_journal_alloc(ca);
		if (ret) {
			percpu_ref_put(&ca->io_ref);
			return ret;
		}
	}

	return 0;
}

/* startup/shutdown: */

static bool bch2_journal_writing_to_device(struct journal *j, unsigned dev_idx)
+1 −0
Original line number Diff line number Diff line
@@ -534,6 +534,7 @@ bool bch2_journal_seq_pins_to_text(struct printbuf *, struct journal *, u64 *);
int bch2_set_nr_journal_buckets(struct bch_fs *, struct bch_dev *,
				unsigned nr);
int bch2_dev_journal_alloc(struct bch_dev *);
int bch2_fs_journal_alloc(struct bch_fs *);

void bch2_dev_journal_stop(struct journal *, struct bch_dev *);

+9 −15
Original line number Diff line number Diff line
@@ -946,16 +946,12 @@ int bch2_fs_initialize(struct bch_fs *c)
	for (i = 0; i < BTREE_ID_NR; i++)
		bch2_btree_root_alloc(c, i);

	for_each_online_member(ca, c, i)
	for_each_member_device(ca, c, i)
		bch2_dev_usage_init(ca);

	for_each_online_member(ca, c, i) {
		ret = bch2_dev_journal_alloc(ca);
		if (ret) {
			percpu_ref_put(&ca->io_ref);
	ret = bch2_fs_journal_alloc(c);
	if (ret)
		goto err;
		}
	}

	/*
	 * journal_res_get() will crash if called before this has
@@ -973,15 +969,13 @@ int bch2_fs_initialize(struct bch_fs *c)
	 * btree updates
	 */
	bch_verbose(c, "marking superblocks");
	for_each_member_device(ca, c, i) {
		ret = bch2_trans_mark_dev_sb(c, ca);
		if (ret) {
			percpu_ref_put(&ca->ref);
	ret = bch2_trans_mark_dev_sbs(c);
	bch_err_msg(c, ret, "marking superblocks");
	if (ret)
		goto err;
		}

	for_each_online_member(ca, c, i)
		ca->new_fs_bucket_idx = 0;
	}

	ret = bch2_fs_freespace_init(c);
	if (ret)
Loading