]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: Rewrite bch2_bucket_alloc_new_fs()
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 24 Dec 2021 09:22:20 +0000 (04:22 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:19 +0000 (17:09 -0400)
This changes bch2_bucket_alloc_new_fs() to a simple bump allocator that
doesn't need to use the in memory bucket array, part of a larger patch
series to entirely get rid of the in memory bucket array, except for
gc/fsck.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/alloc_background.c
fs/bcachefs/alloc_foreground.c
fs/bcachefs/bcachefs.h
fs/bcachefs/recovery.c
fs/bcachefs/super.c
fs/bcachefs/super.h

index 9f98860da5cc528ad7b713197c9e9e8a1a327aee..e81e05629ffc019233d3f7d1a0394da1cf869067 100644 (file)
@@ -513,6 +513,18 @@ static bool bch2_can_invalidate_bucket(struct bch_dev *ca, size_t b,
            test_bit(b, ca->buckets_nouse))
                return false;
 
+       if (ca->new_fs_bucket_idx) {
+               /*
+                * Device or filesystem is still being initialized, and we
+                * haven't fully marked superblocks & journal:
+                */
+               if (is_superblock_bucket(ca, b))
+                       return false;
+
+               if (b < ca->new_fs_bucket_idx)
+                       return false;
+       }
+
        gc_gen = bucket_gc_gen(bucket(ca, b));
 
        ca->inc_gen_needs_gc            += gc_gen >= BUCKET_GC_GEN_MAX / 2;
index 646d556a5c2461ee1ad6f2e85052cb65dd146d76..e38ee6bf0c464c713ce6e33868acb9990449e23c 100644 (file)
@@ -144,21 +144,15 @@ static void verify_not_stale(struct bch_fs *c, const struct open_buckets *obs)
 /* _only_ for allocating the journal on a new device: */
 long bch2_bucket_alloc_new_fs(struct bch_dev *ca)
 {
-       struct bucket_array *buckets;
-       ssize_t b;
+       while (ca->new_fs_bucket_idx < ca->mi.nbuckets) {
+               u64 b = ca->new_fs_bucket_idx++;
 
-       rcu_read_lock();
-       buckets = bucket_array(ca);
-
-       for (b = buckets->first_bucket; b < buckets->nbuckets; b++)
-               if (is_available_bucket(buckets->b[b].mark) &&
-                   (!ca->buckets_nouse || !test_bit(b, ca->buckets_nouse)) &&
-                   !buckets->b[b].mark.owned_by_allocator)
-                       goto success;
-       b = -1;
-success:
-       rcu_read_unlock();
-       return b;
+               if (!is_superblock_bucket(ca, b) &&
+                   (!ca->buckets_nouse || !test_bit(b, ca->buckets_nouse)))
+                       return b;
+       }
+
+       return -1;
 }
 
 static inline unsigned open_buckets_reserved(enum alloc_reserve reserve)
index f0a8a0cabc650ffbaa9178bb0c5beacfd36ae132..c8c7f6b8ee21f857fb6030ac4aec17e85f7dddc0 100644 (file)
@@ -453,6 +453,7 @@ struct bch_dev {
        struct bch_dev_usage __percpu   *usage_gc;
 
        /* Allocator: */
+       u64                     new_fs_bucket_idx;
        struct task_struct __rcu *alloc_thread;
 
        /*
index 29fe6260ace5ad6c9ecb6d55765edd6a296f5382..bd552a942ac64b2308fffc2d36d7506211fd4c0f 100644 (file)
@@ -1429,6 +1429,8 @@ int bch2_fs_initialize(struct bch_fs *c)
                        percpu_ref_put(&ca->ref);
                        goto err;
                }
+
+               ca->new_fs_bucket_idx = 0;
        }
 
        err = "error creating root snapshot node";
index e1d4fe5a8e496c81bc71eb23eda34e0d203f12df..94429c00e87ad3d06140a2f1bd50eccf4f0b8886 100644 (file)
@@ -1726,6 +1726,8 @@ have_slot:
        if (ret)
                goto err_late;
 
+       ca->new_fs_bucket_idx = 0;
+
        if (ca->mi.state == BCH_MEMBER_STATE_rw) {
                ret = __bch2_dev_read_write(c, ca);
                if (ret)
index b151bffcd3a38a471b8697dfca0029f3dc4bb05a..a5249c54426d7aeb81d40f1134ef95e149eaf485 100644 (file)
@@ -194,6 +194,27 @@ static inline struct bch_devs_mask bch2_online_devs(struct bch_fs *c)
        return devs;
 }
 
+static inline bool is_superblock_bucket(struct bch_dev *ca, u64 b)
+{
+       struct bch_sb_layout *layout = &ca->disk_sb.sb->layout;
+       u64 b_offset    = bucket_to_sector(ca, b);
+       u64 b_end       = bucket_to_sector(ca, b + 1);
+       unsigned i;
+
+       if (!b)
+               return true;
+
+       for (i = 0; i < layout->nr_superblocks; i++) {
+               u64 offset = le64_to_cpu(layout->sb_offset[i]);
+               u64 end = offset + (1 << layout->sb_max_size_bits);
+
+               if (!(offset >= b_end || end <= b_offset))
+                       return true;
+       }
+
+       return false;
+}
+
 struct bch_fs *bch2_dev_to_fs(dev_t);
 struct bch_fs *bch2_uuid_to_fs(__uuid_t);