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

bcachefs: Kill opts.buckets_nouse



Now explicitly allocate and free the buckets_nouse bitmap - this is
going to be used for online fsck.

To go RW when we haven't check allocations, we'll do a much slimmed down
version that just initializes the buckets_nouse bitmaps.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 706833db
Loading
Loading
Loading
Loading
+27 −16
Original line number Diff line number Diff line
@@ -1519,6 +1519,31 @@ int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,

/* Startup/shutdown: */

void bch2_buckets_nouse_free(struct bch_fs *c)
{
	for_each_member_device(c, ca) {
		kvfree_rcu_mightsleep(ca->buckets_nouse);
		ca->buckets_nouse = NULL;
	}
}

int bch2_buckets_nouse_alloc(struct bch_fs *c)
{
	for_each_member_device(c, ca) {
		BUG_ON(ca->buckets_nouse);

		ca->buckets_nouse = kvmalloc(BITS_TO_LONGS(ca->mi.nbuckets) *
					    sizeof(unsigned long),
					    GFP_KERNEL|__GFP_ZERO);
		if (!ca->buckets_nouse) {
			percpu_ref_put(&ca->ref);
			return -BCH_ERR_ENOMEM_buckets_nouse;
		}
	}

	return 0;
}

static void bucket_gens_free_rcu(struct rcu_head *rcu)
{
	struct bucket_gens *buckets =
@@ -1530,24 +1555,17 @@ static void bucket_gens_free_rcu(struct rcu_head *rcu)
int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
{
	struct bucket_gens *bucket_gens = NULL, *old_bucket_gens = NULL;
	unsigned long *buckets_nouse = NULL;
	bool resize = ca->bucket_gens != NULL;
	int ret;

	BUG_ON(resize && ca->buckets_nouse);

	if (!(bucket_gens	= kvmalloc(sizeof(struct bucket_gens) + nbuckets,
					   GFP_KERNEL|__GFP_ZERO))) {
		ret = -BCH_ERR_ENOMEM_bucket_gens;
		goto err;
	}

	if ((c->opts.buckets_nouse &&
	     !(buckets_nouse	= kvmalloc(BITS_TO_LONGS(nbuckets) *
					   sizeof(unsigned long),
					   GFP_KERNEL|__GFP_ZERO)))) {
		ret = -BCH_ERR_ENOMEM_buckets_nouse;
		goto err;
	}

	bucket_gens->first_bucket = ca->mi.first_bucket;
	bucket_gens->nbuckets	= nbuckets;

@@ -1565,17 +1583,11 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
		memcpy(bucket_gens->b,
		       old_bucket_gens->b,
		       n);
		if (buckets_nouse)
			memcpy(buckets_nouse,
			       ca->buckets_nouse,
			       BITS_TO_LONGS(n) * sizeof(unsigned long));
	}

	rcu_assign_pointer(ca->bucket_gens, bucket_gens);
	bucket_gens	= old_bucket_gens;

	swap(ca->buckets_nouse, buckets_nouse);

	nbuckets = ca->mi.nbuckets;

	if (resize) {
@@ -1586,7 +1598,6 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)

	ret = 0;
err:
	kvfree(buckets_nouse);
	if (bucket_gens)
		call_rcu(&bucket_gens->rcu, bucket_gens_free_rcu);

+3 −0
Original line number Diff line number Diff line
@@ -472,6 +472,9 @@ static inline u64 avail_factor(u64 r)
	return div_u64(r << RESERVE_FACTOR, (1 << RESERVE_FACTOR) + 1);
}

void bch2_buckets_nouse_free(struct bch_fs *);
int bch2_buckets_nouse_alloc(struct bch_fs *);

int bch2_dev_buckets_resize(struct bch_fs *, struct bch_dev *, u64);
void bch2_dev_buckets_free(struct bch_dev *);
int bch2_dev_buckets_alloc(struct bch_fs *, struct bch_dev *);
+0 −5
Original line number Diff line number Diff line
@@ -426,11 +426,6 @@ enum fsck_err_opts {
	  BCH_SB_VERSION_UPGRADE,	BCH_VERSION_UPGRADE_compatible,	\
	  NULL,		"Set superblock to latest version,\n"		\
			"allowing any new features to be used")		\
	x(buckets_nouse,		u8,				\
	  0,								\
	  OPT_BOOL(),							\
	  BCH2_NO_SB_OPT,		false,				\
	  NULL,		"Allocate the buckets_nouse bitmap")		\
	x(stdio,			u64,				\
	  0,								\
	  OPT_UINT(0, S64_MAX),						\
+2 −3
Original line number Diff line number Diff line
@@ -531,9 +531,7 @@ int bch2_fs_read_write_early(struct bch_fs *c)

static void __bch2_fs_free(struct bch_fs *c)
{
	unsigned i;

	for (i = 0; i < BCH_TIME_STAT_NR; i++)
	for (unsigned i = 0; i < BCH_TIME_STAT_NR; i++)
		bch2_time_stats_exit(&c->times[i]);

	bch2_find_btree_nodes_exit(&c->found_btree_nodes);
@@ -1189,6 +1187,7 @@ static void bch2_dev_free(struct bch_dev *ca)
	if (ca->kobj.state_in_sysfs)
		kobject_del(&ca->kobj);

	kfree(ca->buckets_nouse);
	bch2_free_super(&ca->disk_sb);
	bch2_dev_journal_exit(ca);