Commit ffcbec60 authored by Kent Overstreet's avatar Kent Overstreet

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
...@@ -1519,6 +1519,31 @@ int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res, ...@@ -1519,6 +1519,31 @@ int __bch2_disk_reservation_add(struct bch_fs *c, struct disk_reservation *res,
/* Startup/shutdown: */ /* 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) static void bucket_gens_free_rcu(struct rcu_head *rcu)
{ {
struct bucket_gens *buckets = struct bucket_gens *buckets =
...@@ -1530,24 +1555,17 @@ static void bucket_gens_free_rcu(struct rcu_head *rcu) ...@@ -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) 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; struct bucket_gens *bucket_gens = NULL, *old_bucket_gens = NULL;
unsigned long *buckets_nouse = NULL;
bool resize = ca->bucket_gens != NULL; bool resize = ca->bucket_gens != NULL;
int ret; int ret;
BUG_ON(resize && ca->buckets_nouse);
if (!(bucket_gens = kvmalloc(sizeof(struct bucket_gens) + nbuckets, if (!(bucket_gens = kvmalloc(sizeof(struct bucket_gens) + nbuckets,
GFP_KERNEL|__GFP_ZERO))) { GFP_KERNEL|__GFP_ZERO))) {
ret = -BCH_ERR_ENOMEM_bucket_gens; ret = -BCH_ERR_ENOMEM_bucket_gens;
goto err; 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->first_bucket = ca->mi.first_bucket;
bucket_gens->nbuckets = nbuckets; bucket_gens->nbuckets = nbuckets;
...@@ -1565,17 +1583,11 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) ...@@ -1565,17 +1583,11 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
memcpy(bucket_gens->b, memcpy(bucket_gens->b,
old_bucket_gens->b, old_bucket_gens->b,
n); 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); rcu_assign_pointer(ca->bucket_gens, bucket_gens);
bucket_gens = old_bucket_gens; bucket_gens = old_bucket_gens;
swap(ca->buckets_nouse, buckets_nouse);
nbuckets = ca->mi.nbuckets; nbuckets = ca->mi.nbuckets;
if (resize) { if (resize) {
...@@ -1586,7 +1598,6 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets) ...@@ -1586,7 +1598,6 @@ int bch2_dev_buckets_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
ret = 0; ret = 0;
err: err:
kvfree(buckets_nouse);
if (bucket_gens) if (bucket_gens)
call_rcu(&bucket_gens->rcu, bucket_gens_free_rcu); call_rcu(&bucket_gens->rcu, bucket_gens_free_rcu);
......
...@@ -472,6 +472,9 @@ static inline u64 avail_factor(u64 r) ...@@ -472,6 +472,9 @@ static inline u64 avail_factor(u64 r)
return div_u64(r << RESERVE_FACTOR, (1 << RESERVE_FACTOR) + 1); 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); int bch2_dev_buckets_resize(struct bch_fs *, struct bch_dev *, u64);
void bch2_dev_buckets_free(struct bch_dev *); void bch2_dev_buckets_free(struct bch_dev *);
int bch2_dev_buckets_alloc(struct bch_fs *, struct bch_dev *); int bch2_dev_buckets_alloc(struct bch_fs *, struct bch_dev *);
......
...@@ -426,11 +426,6 @@ enum fsck_err_opts { ...@@ -426,11 +426,6 @@ enum fsck_err_opts {
BCH_SB_VERSION_UPGRADE, BCH_VERSION_UPGRADE_compatible, \ BCH_SB_VERSION_UPGRADE, BCH_VERSION_UPGRADE_compatible, \
NULL, "Set superblock to latest version,\n" \ NULL, "Set superblock to latest version,\n" \
"allowing any new features to be used") \ "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, \ x(stdio, u64, \
0, \ 0, \
OPT_UINT(0, S64_MAX), \ OPT_UINT(0, S64_MAX), \
......
...@@ -531,9 +531,7 @@ int bch2_fs_read_write_early(struct bch_fs *c) ...@@ -531,9 +531,7 @@ int bch2_fs_read_write_early(struct bch_fs *c)
static void __bch2_fs_free(struct bch_fs *c) static void __bch2_fs_free(struct bch_fs *c)
{ {
unsigned i; for (unsigned i = 0; i < BCH_TIME_STAT_NR; i++)
for (i = 0; i < BCH_TIME_STAT_NR; i++)
bch2_time_stats_exit(&c->times[i]); bch2_time_stats_exit(&c->times[i]);
bch2_find_btree_nodes_exit(&c->found_btree_nodes); bch2_find_btree_nodes_exit(&c->found_btree_nodes);
...@@ -1189,6 +1187,7 @@ static void bch2_dev_free(struct bch_dev *ca) ...@@ -1189,6 +1187,7 @@ static void bch2_dev_free(struct bch_dev *ca)
if (ca->kobj.state_in_sysfs) if (ca->kobj.state_in_sysfs)
kobject_del(&ca->kobj); kobject_del(&ca->kobj);
kfree(ca->buckets_nouse);
bch2_free_super(&ca->disk_sb); bch2_free_super(&ca->disk_sb);
bch2_dev_journal_exit(ca); bch2_dev_journal_exit(ca);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment