bcachefs: bch2_bucket_alloc_new_fs() no longer depends on bucket marks
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 24 Dec 2021 09:27:01 +0000 (04:27 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:19 +0000 (17:09 -0400)
Now that bch2_bucket_alloc_new_fs() isn't looking at bucket marks to
decide what buckets are eligible to allocate, we can clean up the
filesystem initialization and device add paths. Previously, we had to
use ancient code to mark superblock/journal buckets in the in memory
bucket marks as we allocated them, and then zero that out and re-do that
marking using the newer transational bucket mark paths. Now, we can
simply delete the in-memory bucket marking.

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

index ccb85850080b63d79a93fe68df8d7c96174f8d29..3fa9f5996fca742e582187dc846c5c8baf9df7e4 100644 (file)
@@ -1056,23 +1056,13 @@ static void mark_metadata_sectors(struct bch_fs *c, struct bch_dev *ca,
        } while (start < end);
 }
 
-void bch2_mark_dev_superblock(struct bch_fs *c, struct bch_dev *ca,
-                             unsigned flags)
+static void bch2_mark_dev_superblock(struct bch_fs *c, struct bch_dev *ca,
+                                    unsigned flags)
 {
        struct bch_sb_layout *layout = &ca->disk_sb.sb->layout;
        unsigned i;
        u64 b;
 
-       /*
-        * This conditional is kind of gross, but we may be called from the
-        * device add path, before the new device has actually been added to the
-        * running filesystem:
-        */
-       if (c) {
-               lockdep_assert_held(&c->sb_lock);
-               percpu_down_read(&c->mark_lock);
-       }
-
        for (i = 0; i < layout->nr_superblocks; i++) {
                u64 offset = le64_to_cpu(layout->sb_offset[i]);
 
@@ -1091,9 +1081,6 @@ void bch2_mark_dev_superblock(struct bch_fs *c, struct bch_dev *ca,
                                          ca->mi.bucket_size,
                                          gc_phase(GC_PHASE_SB), flags);
        }
-
-       if (c)
-               percpu_up_read(&c->mark_lock);
 }
 
 static void bch2_mark_superblocks(struct bch_fs *c)
index 59dfb069e699402eb57bcc62b63626d3b4f2f25d..0665f5941fcc5a6196c4a80b8e7c6f5479055ca6 100644 (file)
@@ -8,7 +8,6 @@ int bch2_gc(struct bch_fs *, bool, bool);
 int bch2_gc_gens(struct bch_fs *);
 void bch2_gc_thread_stop(struct bch_fs *);
 int bch2_gc_thread_start(struct bch_fs *);
-void bch2_mark_dev_superblock(struct bch_fs *, struct bch_dev *, unsigned);
 
 /*
  * For concurrent mark and sweep (with other index updates), we define a total
index 0d9d723c24bb44cd1431399325940f5d21769f6e..63409ddd975a34f14290e3451cd313b98e81a532 100644 (file)
@@ -369,13 +369,6 @@ static void bch2_dev_usage_update(struct bch_fs *c, struct bch_dev *ca,
        struct bch_fs_usage *fs_usage;
        struct bch_dev_usage *u;
 
-       /*
-        * Hack for bch2_fs_initialize path, where we're first marking sb and
-        * journal non-transactionally:
-        */
-       if (!journal_seq && !test_bit(BCH_FS_INITIALIZED, &c->flags))
-               journal_seq = 1;
-
        preempt_disable();
        fs_usage = fs_usage_ptr(c, journal_seq, gc);
        u = dev_usage_ptr(ca, journal_seq, gc);
@@ -536,19 +529,6 @@ static inline void update_cached_sectors_list(struct btree_trans *trans,
        update_replicas_list(trans, &r.e, sectors);
 }
 
-#define do_mark_fn(fn, c, pos, flags, ...)                             \
-({                                                                     \
-       int gc, ret = 0;                                                \
-                                                                       \
-       percpu_rwsem_assert_held(&c->mark_lock);                        \
-                                                                       \
-       for (gc = 0; gc < 2 && !ret; gc++)                              \
-               if (!gc == !(flags & BTREE_TRIGGER_GC) ||               \
-                   (gc && gc_visited(c, pos)))                         \
-                       ret = fn(c, __VA_ARGS__, gc);                   \
-       ret;                                                            \
-})
-
 void bch2_mark_alloc_bucket(struct bch_fs *c, struct bch_dev *ca,
                            size_t b, bool owned_by_allocator)
 {
@@ -659,17 +639,27 @@ static int bch2_mark_alloc(struct btree_trans *trans,
        overflow;                                               \
 })
 
-static int __bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
-                                      size_t b, enum bch_data_type data_type,
-                                      unsigned sectors, bool gc)
+void bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
+                              size_t b, enum bch_data_type data_type,
+                              unsigned sectors, struct gc_pos pos,
+                              unsigned flags)
 {
-       struct bucket *g = __bucket(ca, b, gc);
+       struct bucket *g;
        struct bucket_mark old, new;
        bool overflow;
 
+       BUG_ON(!(flags & BTREE_TRIGGER_GC));
        BUG_ON(data_type != BCH_DATA_sb &&
               data_type != BCH_DATA_journal);
 
+       /*
+        * Backup superblock might be past the end of our normal usable space:
+        */
+       if (b >= ca->mi.nbuckets)
+               return;
+
+       percpu_down_read(&c->mark_lock);
+       g = __bucket(ca, b, true);
        old = bucket_cmpxchg(g, new, ({
                new.data_type   = data_type;
                overflow = checked_add(new.dirty_sectors, sectors);
@@ -687,32 +677,8 @@ static int __bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
                bch2_data_types[old.data_type ?: data_type],
                old.dirty_sectors, sectors);
 
-       if (c)
-               bch2_dev_usage_update(c, ca, old, new, 0, gc);
-
-       return 0;
-}
-
-void bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
-                              size_t b, enum bch_data_type type,
-                              unsigned sectors, struct gc_pos pos,
-                              unsigned flags)
-{
-       BUG_ON(type != BCH_DATA_sb &&
-              type != BCH_DATA_journal);
-
-       /*
-        * Backup superblock might be past the end of our normal usable space:
-        */
-       if (b >= ca->mi.nbuckets)
-               return;
-
-       if (likely(c)) {
-               do_mark_fn(__bch2_mark_metadata_bucket, c, pos, flags,
-                          ca, b, type, sectors);
-       } else {
-               __bch2_mark_metadata_bucket(c, ca, b, type, sectors, 0);
-       }
+       bch2_dev_usage_update(c, ca, old, new, 0, true);
+       percpu_up_read(&c->mark_lock);
 }
 
 static s64 ptr_disk_sectors(s64 sectors, struct extent_ptr_decoded p)
index f15d265ef1b64ead79215f58d95f9acda8f1c0a6..020c7b0a3469bbb61f1a8db64b4718c01d577891 100644 (file)
@@ -769,11 +769,8 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
                long b;
 
                if (new_fs) {
-                       if (c)
-                               percpu_down_read(&c->mark_lock);
                        b = bch2_bucket_alloc_new_fs(ca);
                        if (b < 0) {
-                               percpu_up_read(&c->mark_lock);
                                ret = -ENOSPC;
                                goto err;
                        }
@@ -821,14 +818,7 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
                if (c)
                        spin_unlock(&c->journal.lock);
 
-               if (new_fs) {
-                       bch2_mark_metadata_bucket(c, ca, b, BCH_DATA_journal,
-                                                 ca->mi.bucket_size,
-                                                 gc_phase(GC_PHASE_SB),
-                                                 0);
-                       if (c)
-                               percpu_up_read(&c->mark_lock);
-               } else {
+               if (!new_fs) {
                        ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_NOFAIL,
                                bch2_trans_mark_metadata_bucket(&trans, ca,
                                                b, BCH_DATA_journal,
index bd552a942ac64b2308fffc2d36d7506211fd4c0f..9916fad292be6bee3ac8a196cca62bd5d97b98aa 100644 (file)
@@ -1383,9 +1383,6 @@ int bch2_fs_initialize(struct bch_fs *c)
                c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALL);
                bch2_write_super(c);
        }
-
-       for_each_online_member(ca, c, i)
-               bch2_mark_dev_superblock(c, ca, 0);
        mutex_unlock(&c->sb_lock);
 
        set_bit(BCH_FS_ALLOC_READ_DONE, &c->flags);
index 94429c00e87ad3d06140a2f1bd50eccf4f0b8886..75410b5dba140d82f81a834df8558733e0ea44f0 100644 (file)
@@ -1606,8 +1606,6 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
        struct bch_dev *ca = NULL;
        struct bch_sb_field_members *mi;
        struct bch_member dev_mi;
-       struct bucket_array *buckets;
-       struct bucket *g;
        unsigned dev_idx, nr_devices, u64s;
        int ret;
 
@@ -1637,20 +1635,6 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
                return ret;
        }
 
-       /*
-        * We want to allocate journal on the new device before adding the new
-        * device to the filesystem because allocating after we attach requires
-        * spinning up the allocator thread, and the allocator thread requires
-        * doing btree writes, which if the existing devices are RO isn't going
-        * to work
-        *
-        * So we have to mark where the superblocks are, but marking allocated
-        * data normally updates the filesystem usage too, so we have to mark,
-        * allocate the journal, reset all the marks, then remark after we
-        * attach...
-        */
-       bch2_mark_dev_superblock(NULL, ca, 0);
-
        err = "journal alloc failed";
        ret = bch2_dev_journal_alloc(ca);
        if (ret)
@@ -1711,16 +1695,6 @@ have_slot:
 
        bch2_dev_usage_journal_reserve(c);
 
-       /*
-        * Clear marks before marking transactionally in the btree, so that
-        * per-device accounting gets done correctly:
-        */
-       down_read(&ca->bucket_lock);
-       buckets = bucket_array(ca);
-       for_each_bucket(g, buckets)
-               atomic64_set(&g->_mark.v, 0);
-       up_read(&ca->bucket_lock);
-
        err = "error marking superblock";
        ret = bch2_trans_mark_dev_sb(c, ca);
        if (ret)