]> www.infradead.org Git - linux.git/commitdiff
bcachefs: Add new helper to retrieve bch_member from sb
authorHunter Shaffer <huntershaffer182456@gmail.com>
Mon, 25 Sep 2023 03:55:37 +0000 (23:55 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:10:15 +0000 (17:10 -0400)
Prep work for introducing bch_sb_field_members_v2 - introduce new
helpers that will check for members_v2 if it exists, otherwise using v1

Signed-off-by: Hunter Shaffer <huntershaffer182456@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/disk_groups.c
fs/bcachefs/journal_sb.c
fs/bcachefs/replicas.c
fs/bcachefs/sb-members.c
fs/bcachefs/sb-members.h
fs/bcachefs/super-io.c
fs/bcachefs/super-io.h
fs/bcachefs/super.c

index b292dbef799211ca71bf132152c9d9d5ff464d70..1bf47a6209ddc3bdac7829df36c54a2cc31b891f 100644 (file)
@@ -25,19 +25,18 @@ static int bch2_sb_disk_groups_validate(struct bch_sb *sb,
        struct bch_sb_field_disk_groups *groups =
                field_to_type(f, disk_groups);
        struct bch_disk_group *g, *sorted = NULL;
-       struct bch_sb_field_members *mi = bch2_sb_get_members(sb);
        unsigned nr_groups = disk_groups_nr(groups);
        unsigned i, len;
        int ret = 0;
 
        for (i = 0; i < sb->nr_devices; i++) {
-               struct bch_member *m = mi->members + i;
+               struct bch_member m = bch2_sb_member_get(sb, i);
                unsigned group_id;
 
-               if (!BCH_MEMBER_GROUP(m))
+               if (!BCH_MEMBER_GROUP(&m))
                        continue;
 
-               group_id = BCH_MEMBER_GROUP(m) - 1;
+               group_id = BCH_MEMBER_GROUP(&m) - 1;
 
                if (group_id >= nr_groups) {
                        prt_printf(err, "disk %u has invalid label %u (have %u)",
@@ -152,14 +151,12 @@ const struct bch_sb_field_ops bch_sb_field_ops_disk_groups = {
 
 int bch2_sb_disk_groups_to_cpu(struct bch_fs *c)
 {
-       struct bch_sb_field_members *mi;
        struct bch_sb_field_disk_groups *groups;
        struct bch_disk_groups_cpu *cpu_g, *old_g;
        unsigned i, g, nr_groups;
 
        lockdep_assert_held(&c->sb_lock);
 
-       mi              = bch2_sb_get_members(c->disk_sb.sb);
        groups          = bch2_sb_get_disk_groups(c->disk_sb.sb);
        nr_groups       = disk_groups_nr(groups);
 
@@ -182,13 +179,13 @@ int bch2_sb_disk_groups_to_cpu(struct bch_fs *c)
        }
 
        for (i = 0; i < c->disk_sb.sb->nr_devices; i++) {
-               struct bch_member *m = mi->members + i;
+               struct bch_member m = bch2_sb_member_get(c->disk_sb.sb, i);
                struct bch_disk_group_cpu *dst;
 
-               if (!bch2_member_exists(m))
+               if (!bch2_member_exists(&m))
                        continue;
 
-               g = BCH_MEMBER_GROUP(m);
+               g = BCH_MEMBER_GROUP(&m);
                while (g) {
                        dst = &cpu_g->entries[g - 1];
                        __set_bit(i, dst->devs.d);
@@ -528,12 +525,11 @@ void bch2_opt_target_to_text(struct printbuf *out,
 
                        rcu_read_unlock();
                } else {
-                       struct bch_sb_field_members *mi = bch2_sb_get_members(sb);
-                       struct bch_member *m = mi->members + t.dev;
+                       struct bch_member m = bch2_sb_member_get(sb, t.dev);
 
-                       if (bch2_dev_exists(sb, mi, t.dev)) {
+                       if (bch2_dev_exists(sb, t.dev)) {
                                prt_printf(out, "Device ");
-                               pr_uuid(out, m->uuid.b);
+                               pr_uuid(out, m.uuid.b);
                                prt_printf(out, " (%u)", t.dev);
                        } else {
                                prt_printf(out, "Bad device %u", t.dev);
index cc41bff86d6bbc049be49f3f05e751af9dd528d5..3c5a95e29463367db9fbbbffedad49a68e74f2e8 100644 (file)
@@ -21,7 +21,7 @@ static int bch2_sb_journal_validate(struct bch_sb *sb,
                                    struct printbuf *err)
 {
        struct bch_sb_field_journal *journal = field_to_type(f, journal);
-       struct bch_member *m = bch2_sb_get_members(sb)->members + sb->dev_idx;
+       struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
        int ret = -BCH_ERR_invalid_sb_journal;
        unsigned nr;
        unsigned i;
@@ -45,15 +45,15 @@ static int bch2_sb_journal_validate(struct bch_sb *sb,
                goto err;
        }
 
-       if (b[0] < le16_to_cpu(m->first_bucket)) {
+       if (b[0] < le16_to_cpu(m.first_bucket)) {
                prt_printf(err, "journal bucket %llu before first bucket %u",
-                      b[0], le16_to_cpu(m->first_bucket));
+                      b[0], le16_to_cpu(m.first_bucket));
                goto err;
        }
 
-       if (b[nr - 1] >= le64_to_cpu(m->nbuckets)) {
+       if (b[nr - 1] >= le64_to_cpu(m.nbuckets)) {
                prt_printf(err, "journal bucket %llu past end of device (nbuckets %llu)",
-                      b[nr - 1], le64_to_cpu(m->nbuckets));
+                      b[nr - 1], le64_to_cpu(m.nbuckets));
                goto err;
        }
 
@@ -104,7 +104,7 @@ static int bch2_sb_journal_v2_validate(struct bch_sb *sb,
                                    struct printbuf *err)
 {
        struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2);
-       struct bch_member *m = bch2_sb_get_members(sb)->members + sb->dev_idx;
+       struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
        int ret = -BCH_ERR_invalid_sb_journal;
        unsigned nr;
        unsigned i;
@@ -130,15 +130,15 @@ static int bch2_sb_journal_v2_validate(struct bch_sb *sb,
                goto err;
        }
 
-       if (b[0].start < le16_to_cpu(m->first_bucket)) {
+       if (b[0].start < le16_to_cpu(m.first_bucket)) {
                prt_printf(err, "journal bucket %llu before first bucket %u",
-                      b[0].start, le16_to_cpu(m->first_bucket));
+                      b[0].start, le16_to_cpu(m.first_bucket));
                goto err;
        }
 
-       if (b[nr - 1].end > le64_to_cpu(m->nbuckets)) {
+       if (b[nr - 1].end > le64_to_cpu(m.nbuckets)) {
                prt_printf(err, "journal bucket %llu past end of device (nbuckets %llu)",
-                      b[nr - 1].end - 1, le64_to_cpu(m->nbuckets));
+                      b[nr - 1].end - 1, le64_to_cpu(m.nbuckets));
                goto err;
        }
 
index dbef41cd8593709bdd25f94866c9f796c1cbd086..a9a694fb0b18e7e588351820cddecc83b43f6d38 100644 (file)
@@ -805,7 +805,6 @@ static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
                                      struct bch_sb *sb,
                                      struct printbuf *err)
 {
-       struct bch_sb_field_members *mi = bch2_sb_get_members(sb);
        unsigned i, j;
 
        sort_cmp_size(cpu_r->entries,
@@ -837,7 +836,7 @@ static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
                }
 
                for (j = 0; j < e->nr_devs; j++)
-                       if (!bch2_dev_exists(sb, mi, e->devs[j])) {
+                       if (!bch2_dev_exists(sb, e->devs[j])) {
                                prt_printf(err, "invalid device %u in entry ", e->devs[j]);
                                bch2_replicas_entry_to_text(err, e);
                                return -BCH_ERR_invalid_sb_replicas;
index 16a2b33895254efede8ecab59dcae24a2cf36d64..0be51d082043c29267c95b09ef3b866f6f93fef6 100644 (file)
@@ -7,6 +7,23 @@
 #include "super-io.h"
 
 /* Code for bch_sb_field_members: */
+static struct bch_member *members_v1_get_mut(struct bch_sb_field_members *mi, int i)
+{
+       return mi->members + i;
+}
+
+static struct bch_member members_v1_get(struct bch_sb_field_members *mi, int i)
+{
+       struct bch_member ret, *p = members_v1_get_mut(mi, i);
+       memset(&ret, 0, sizeof(ret));
+       memcpy(&ret, p, min_t(size_t, sizeof(struct bch_member), sizeof(ret))); return ret;
+}
+
+struct bch_member bch2_sb_member_get(struct bch_sb *sb, int i)
+{
+       struct bch_sb_field_members *mi1 = bch2_sb_get_members(sb);
+       return members_v1_get(mi1, i);
+}
 
 static int bch2_sb_members_validate(struct bch_sb *sb,
                                    struct bch_sb_field *f,
index 34e1cf6046e35d12d5c97bf8bb8c588ac3fe8065..85d1af6a990c2932ce005c6ff73f734ec57f8dda 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _BCACHEFS_SB_MEMBERS_H
 #define _BCACHEFS_SB_MEMBERS_H
 
+struct bch_member bch2_sb_member_get(struct bch_sb *sb, int i);
+
 static inline bool bch2_dev_is_online(struct bch_dev *ca)
 {
        return !percpu_ref_is_zero(&ca->io_ref);
index c9bf342d14aa694e494f5a04e754a68c625ec58b..16e3a8aa290dd3af0f006126a95e5aa2def38d12 100644 (file)
@@ -485,7 +485,6 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
 static void bch2_sb_update(struct bch_fs *c)
 {
        struct bch_sb *src = c->disk_sb.sb;
-       struct bch_sb_field_members *mi = bch2_sb_get_members(src);
        struct bch_dev *ca;
        unsigned i;
 
@@ -511,8 +510,10 @@ static void bch2_sb_update(struct bch_fs *c)
        c->sb.features          = le64_to_cpu(src->features[0]);
        c->sb.compat            = le64_to_cpu(src->compat[0]);
 
-       for_each_member_device(ca, c, i)
-               ca->mi = bch2_mi_to_cpu(mi->members + i);
+       for_each_member_device(ca, c, i) {
+               struct bch_member m = bch2_sb_member_get(src, i);
+               ca->mi = bch2_mi_to_cpu(&m);
+       }
 }
 
 static int __copy_super(struct bch_sb_handle *dst_handle, struct bch_sb *src)
@@ -1125,7 +1126,6 @@ void bch2_sb_layout_to_text(struct printbuf *out, struct bch_sb_layout *l)
 void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb,
                     bool print_layout, unsigned fields)
 {
-       struct bch_sb_field_members *mi;
        struct bch_sb_field *f;
        u64 fields_have = 0;
        unsigned nr_devices = 0;
@@ -1133,15 +1133,8 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb,
        if (!out->nr_tabstops)
                printbuf_tabstop_push(out, 44);
 
-       mi = bch2_sb_get_members(sb);
-       if (mi) {
-               struct bch_member *m;
-
-               for (m = mi->members;
-                    m < mi->members + sb->nr_devices;
-                    m++)
-                       nr_devices += bch2_member_exists(m);
-       }
+       for (int i = 0; i < sb->nr_devices; i++)
+               nr_devices += bch2_dev_exists(sb, i);
 
        prt_printf(out, "External UUID:");
        prt_tab(out);
index d51c0a19586fc09ac328d2c0292ccdfc12a85840..817c3d790acde50c2cc5c08c5f71a2270be7581c 100644 (file)
@@ -6,6 +6,7 @@
 #include "eytzinger.h"
 #include "super_types.h"
 #include "super.h"
+#include "sb-members.h"
 
 #include <asm/byteorder.h>
 
@@ -97,11 +98,13 @@ static inline bool bch2_member_exists(struct bch_member *m)
 }
 
 static inline bool bch2_dev_exists(struct bch_sb *sb,
-                                  struct bch_sb_field_members *mi,
                                   unsigned dev)
 {
-       return dev < sb->nr_devices &&
-               bch2_member_exists(&mi->members[dev]);
+       if (dev < sb->nr_devices) {
+       struct bch_member m = bch2_sb_member_get(sb, dev);
+               return bch2_member_exists(&m);
+       }
+       return false;
 }
 
 static inline struct bch_member_cpu bch2_mi_to_cpu(struct bch_member *mi)
index 1347270e5045dce80566e3c8fdb98a88bee11c94..7ba1ebabc1762b9eac7fc833e6558101b106a338 100644 (file)
@@ -49,6 +49,7 @@
 #include "recovery.h"
 #include "replicas.h"
 #include "sb-clean.h"
+#include "sb-members.h"
 #include "snapshot.h"
 #include "subvolume.h"
 #include "super.h"
@@ -662,7 +663,6 @@ err:
 
 static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
 {
-       struct bch_sb_field_members *mi;
        struct bch_fs *c;
        struct printbuf name = PRINTBUF;
        unsigned i, iter_size;
@@ -858,9 +858,8 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
        if (ret)
                goto err;
 
-       mi = bch2_sb_get_members(c->disk_sb.sb);
        for (i = 0; i < c->sb.nr_devices; i++)
-               if (bch2_dev_exists(c->disk_sb.sb, mi, i) &&
+               if (bch2_dev_exists(c->disk_sb.sb, i) &&
                    bch2_dev_alloc(c, i)) {
                        ret = -EEXIST;
                        goto err;
@@ -997,16 +996,12 @@ err:
 
 static int bch2_dev_may_add(struct bch_sb *sb, struct bch_fs *c)
 {
-       struct bch_sb_field_members *sb_mi;
-
-       sb_mi = bch2_sb_get_members(sb);
-       if (!sb_mi)
-               return -BCH_ERR_member_info_missing;
+       struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
 
        if (le16_to_cpu(sb->block_size) != block_sectors(c))
                return -BCH_ERR_mismatched_block_size;
 
-       if (le16_to_cpu(sb_mi->members[sb->dev_idx].bucket_size) <
+       if (le16_to_cpu(m.bucket_size) <
            BCH_SB_BTREE_NODE_SIZE(c->disk_sb.sb))
                return -BCH_ERR_bucket_size_too_small;
 
@@ -1017,12 +1012,11 @@ static int bch2_dev_in_fs(struct bch_sb *fs, struct bch_sb *sb)
 {
        struct bch_sb *newest =
                le64_to_cpu(fs->seq) > le64_to_cpu(sb->seq) ? fs : sb;
-       struct bch_sb_field_members *mi = bch2_sb_get_members(newest);
 
        if (!uuid_equal(&fs->uuid, &sb->uuid))
                return -BCH_ERR_device_not_a_member_of_filesystem;
 
-       if (!bch2_dev_exists(newest, mi, sb->dev_idx))
+       if (!bch2_dev_exists(newest, sb->dev_idx))
                return -BCH_ERR_device_has_been_removed;
 
        if (fs->block_size != sb->block_size)
@@ -1192,15 +1186,14 @@ static void bch2_dev_attach(struct bch_fs *c, struct bch_dev *ca,
 
 static int bch2_dev_alloc(struct bch_fs *c, unsigned dev_idx)
 {
-       struct bch_member *member =
-               bch2_sb_get_members(c->disk_sb.sb)->members + dev_idx;
+       struct bch_member member = bch2_sb_member_get(c->disk_sb.sb, dev_idx);
        struct bch_dev *ca = NULL;
        int ret = 0;
 
        if (bch2_fs_init_fault("dev_alloc"))
                goto err;
 
-       ca = __bch2_dev_alloc(c, member);
+       ca = __bch2_dev_alloc(c, &member);
        if (!ca)
                goto err;
 
@@ -1335,7 +1328,6 @@ bool bch2_dev_state_allowed(struct bch_fs *c, struct bch_dev *ca,
 
 static bool bch2_fs_may_start(struct bch_fs *c)
 {
-       struct bch_sb_field_members *mi;
        struct bch_dev *ca;
        unsigned i, flags = 0;
 
@@ -1348,10 +1340,9 @@ static bool bch2_fs_may_start(struct bch_fs *c)
        if (!c->opts.degraded &&
            !c->opts.very_degraded) {
                mutex_lock(&c->sb_lock);
-               mi = bch2_sb_get_members(c->disk_sb.sb);
 
                for (i = 0; i < c->disk_sb.sb->nr_devices; i++) {
-                       if (!bch2_dev_exists(c->disk_sb.sb, mi, i))
+                       if (!bch2_dev_exists(c->disk_sb.sb, i))
                                continue;
 
                        ca = bch_dev_locked(c, i);
@@ -1588,7 +1579,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
                goto err;
        }
 
-       dev_mi = bch2_sb_get_members(sb.sb)->members[sb.sb->dev_idx];
+       dev_mi = bch2_sb_member_get(sb.sb, sb.sb->dev_idx);
 
        if (BCH_MEMBER_GROUP(&dev_mi)) {
                bch2_disk_path_to_text(&label, sb.sb, BCH_MEMBER_GROUP(&dev_mi) - 1);
@@ -1644,9 +1635,8 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
        if (dynamic_fault("bcachefs:add:no_slot"))
                goto no_slot;
 
-       mi = bch2_sb_get_members(c->disk_sb.sb);
        for (dev_idx = 0; dev_idx < BCH_SB_MEMBERS_MAX; dev_idx++)
-               if (!bch2_dev_exists(c->disk_sb.sb, mi, dev_idx))
+               if (!bch2_dev_exists(c->disk_sb.sb, dev_idx))
                        goto have_slot;
 no_slot:
        ret = -BCH_ERR_ENOSPC_sb_members;
@@ -1875,7 +1865,6 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices,
 {
        struct bch_sb_handle *sb = NULL;
        struct bch_fs *c = NULL;
-       struct bch_sb_field_members *mi;
        unsigned i, best_sb = 0;
        struct printbuf errbuf = PRINTBUF;
        int ret = 0;
@@ -1906,12 +1895,10 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices,
                    le64_to_cpu(sb[best_sb].sb->seq))
                        best_sb = i;
 
-       mi = bch2_sb_get_members(sb[best_sb].sb);
-
        i = 0;
        while (i < nr_devices) {
                if (i != best_sb &&
-                   !bch2_dev_exists(sb[best_sb].sb, mi, sb[i].sb->dev_idx)) {
+                   !bch2_dev_exists(sb[best_sb].sb, sb[i].sb->dev_idx)) {
                        pr_info("%pg has been removed, skipping", sb[i].bdev);
                        bch2_free_super(&sb[i]);
                        array_remove_item(sb, nr_devices, i);