bcachefs: Kill opts.buckets_nouse
authorKent Overstreet <kent.overstreet@linux.dev>
Sat, 6 Apr 2024 04:07:46 +0000 (00:07 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:22 +0000 (17:29 -0400)
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: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/buckets.c
fs/bcachefs/buckets.h
fs/bcachefs/opts.h
fs/bcachefs/super.c

index 1f810cfb3541300b5095858a3ef9d09c39428302..525c72c0277c963dbc6ec5b7d47e0aa2e88bbd80 100644 (file)
@@ -1519,6 +1519,31 @@ recalculate:
 
 /* 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);
 
index f328ddb82dd97cf41db529696f2baacd56fb0e90..f352d88d9b8e5ee5ee26402abe3cdaedc1d7fda6 100644 (file)
@@ -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 *);
index 74f4d92849bb6ed626b2ec3a7684a68692ff2738..25530e0bb2f386c48a3ab86a29ed4c56a5df4d5c 100644 (file)
@@ -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),                                         \
index 72dde1f1a3e67802b9c164138f94b2181922adf8..1cbb2b3f474051f76310b5dfd2558e45e57fef62 100644 (file)
@@ -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);