]> www.infradead.org Git - users/hch/misc.git/commitdiff
bcachefs: bch2_sb_member_alloc()
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 1 Sep 2024 22:08:25 +0000 (18:08 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Sep 2024 15:39:48 +0000 (11:39 -0400)
refactoring

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/sb-members.c
fs/bcachefs/sb-members.h
fs/bcachefs/super.c

index 7aa5067e09c512d57b26c9a8e82a3c62ef2a9727..2aad62961938733a29b1057fd278df4003ddb15d 100644 (file)
@@ -474,3 +474,47 @@ unsigned bch2_sb_nr_devices(const struct bch_sb *sb)
                nr += bch2_member_exists((struct bch_sb *) sb, i);
        return nr;
 }
+
+int bch2_sb_member_alloc(struct bch_fs *c)
+{
+       unsigned dev_idx = c->sb.nr_devices;
+       if (dev_idx < BCH_SB_MEMBERS_MAX)
+               goto have_slot;
+
+       int best = -1;
+       u64 best_last_mount = 0;
+       for (dev_idx = 0; dev_idx < BCH_SB_MEMBERS_MAX; dev_idx++) {
+               /* eventually BCH_SB_MEMBERS_MAX will be raised */
+               if (dev_idx == BCH_SB_MEMBER_INVALID)
+                       continue;
+
+               struct bch_member m = bch2_sb_member_get(c->disk_sb.sb, dev_idx);
+               if (bch2_member_alive(&m))
+                       continue;
+
+               u64 last_mount = le64_to_cpu(m.last_mount);
+               if (best < 0 || last_mount < best_last_mount) {
+                       best = dev_idx;
+                       best_last_mount = last_mount;
+               }
+       }
+       if (best >= 0) {
+               dev_idx = best;
+               goto have_slot;
+       }
+
+       return -BCH_ERR_ENOSPC_sb_members;
+have_slot:
+       unsigned nr_devices = max_t(unsigned, dev_idx + 1, c->sb.nr_devices);
+
+       struct bch_sb_field_members_v2 *mi = bch2_sb_field_get(c->disk_sb.sb, members_v2);
+       unsigned u64s = DIV_ROUND_UP(sizeof(struct bch_sb_field_members_v2) +
+                                    le16_to_cpu(mi->member_bytes) * nr_devices, sizeof(u64));
+
+       mi = bch2_sb_field_resize(&c->disk_sb, members_v2, u64s);
+       if (!mi)
+               return -BCH_ERR_ENOSPC_sb_members;
+
+       c->disk_sb.sb->nr_devices = nr_devices;
+       return dev_idx;
+}
index f307f28576037c807108031a8cf3047eef27cbe7..1a21d1f15a9c87a1d04985f11a2cff0870323f66 100644 (file)
@@ -354,4 +354,6 @@ static inline bool bch2_dev_btree_bitmap_marked_sectors(struct bch_dev *ca, u64
 bool bch2_dev_btree_bitmap_marked(struct bch_fs *, struct bkey_s_c);
 void bch2_dev_btree_bitmap_mark(struct bch_fs *, struct bkey_s_c);
 
+int bch2_sb_member_alloc(struct bch_fs *);
+
 #endif /* _BCACHEFS_SB_MEMBERS_H */
index 7dba46e97fbd2b529bf3d31ee09831f0cd66597c..1c949389d88fac516059eb69ea4d4bb972108bb1 100644 (file)
@@ -1703,9 +1703,6 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
        struct bch_opts opts = bch2_opts_empty();
        struct bch_sb_handle sb;
        struct bch_dev *ca = NULL;
-       struct bch_sb_field_members_v2 *mi;
-       struct bch_member dev_mi;
-       unsigned dev_idx, nr_devices, u64s;
        struct printbuf errbuf = PRINTBUF;
        struct printbuf label = PRINTBUF;
        int ret;
@@ -1715,7 +1712,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
        if (ret)
                goto err;
 
-       dev_mi = bch2_sb_member_get(sb.sb, sb.sb->dev_idx);
+       struct bch_member dev_mi = bch2_sb_member_get(sb.sb, sb.sb->dev_idx);
 
        if (BCH_MEMBER_GROUP(&dev_mi)) {
                bch2_disk_path_to_text_sb(&label, sb.sb, BCH_MEMBER_GROUP(&dev_mi) - 1);
@@ -1753,55 +1750,19 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
                goto err_unlock;
 
        if (dynamic_fault("bcachefs:add:no_slot"))
-               goto no_slot;
-
-       if (c->sb.nr_devices < BCH_SB_MEMBERS_MAX) {
-               dev_idx = c->sb.nr_devices;
-               goto have_slot;
-       }
-
-       int best = -1;
-       u64 best_last_mount = 0;
-       for (dev_idx = 0; dev_idx < BCH_SB_MEMBERS_MAX; dev_idx++) {
-               struct bch_member m = bch2_sb_member_get(c->disk_sb.sb, dev_idx);
-               if (bch2_member_alive(&m))
-                       continue;
-
-               u64 last_mount = le64_to_cpu(m.last_mount);
-               if (best < 0 || last_mount < best_last_mount) {
-                       best = dev_idx;
-                       best_last_mount = last_mount;
-               }
-       }
-       if (best >= 0) {
-               dev_idx = best;
-               goto have_slot;
-       }
-no_slot:
-       ret = -BCH_ERR_ENOSPC_sb_members;
-       bch_err_msg(c, ret, "setting up new superblock");
-       goto err_unlock;
-
-have_slot:
-       nr_devices = max_t(unsigned, dev_idx + 1, c->sb.nr_devices);
-
-       mi = bch2_sb_field_get(c->disk_sb.sb, members_v2);
-       u64s = DIV_ROUND_UP(sizeof(struct bch_sb_field_members_v2) +
-                           le16_to_cpu(mi->member_bytes) * nr_devices, sizeof(u64));
+               goto err_unlock;
 
-       mi = bch2_sb_field_resize(&c->disk_sb, members_v2, u64s);
-       if (!mi) {
-               ret = -BCH_ERR_ENOSPC_sb_members;
+       ret = bch2_sb_member_alloc(c);
+       if (ret < 0) {
                bch_err_msg(c, ret, "setting up new superblock");
                goto err_unlock;
        }
-       struct bch_member *m = bch2_members_v2_get_mut(c->disk_sb.sb, dev_idx);
+       unsigned dev_idx = ret;
 
        /* success: */
 
-       *m = dev_mi;
-       m->last_mount = cpu_to_le64(ktime_get_real_seconds());
-       c->disk_sb.sb->nr_devices       = nr_devices;
+       dev_mi.last_mount = cpu_to_le64(ktime_get_real_seconds());
+       *bch2_members_v2_get_mut(c->disk_sb.sb, dev_idx) = dev_mi;
 
        ca->disk_sb.sb->dev_idx = dev_idx;
        bch2_dev_attach(c, ca, dev_idx);