diff options
-rw-r--r-- | fs/bcachefs/disk_groups.c | 22 | ||||
-rw-r--r-- | fs/bcachefs/journal_sb.c | 20 | ||||
-rw-r--r-- | fs/bcachefs/replicas.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/sb-members.c | 17 | ||||
-rw-r--r-- | fs/bcachefs/sb-members.h | 2 | ||||
-rw-r--r-- | fs/bcachefs/super-io.c | 19 | ||||
-rw-r--r-- | fs/bcachefs/super-io.h | 9 | ||||
-rw-r--r-- | fs/bcachefs/super.c | 35 |
8 files changed, 62 insertions, 65 deletions
diff --git a/fs/bcachefs/disk_groups.c b/fs/bcachefs/disk_groups.c index b292dbef7992..1bf47a6209dd 100644 --- a/fs/bcachefs/disk_groups.c +++ b/fs/bcachefs/disk_groups.c @@ -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); diff --git a/fs/bcachefs/journal_sb.c b/fs/bcachefs/journal_sb.c index cc41bff86d6b..3c5a95e29463 100644 --- a/fs/bcachefs/journal_sb.c +++ b/fs/bcachefs/journal_sb.c @@ -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; } diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c index dbef41cd8593..a9a694fb0b18 100644 --- a/fs/bcachefs/replicas.c +++ b/fs/bcachefs/replicas.c @@ -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; diff --git a/fs/bcachefs/sb-members.c b/fs/bcachefs/sb-members.c index 16a2b3389525..0be51d082043 100644 --- a/fs/bcachefs/sb-members.c +++ b/fs/bcachefs/sb-members.c @@ -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, diff --git a/fs/bcachefs/sb-members.h b/fs/bcachefs/sb-members.h index 34e1cf6046e3..85d1af6a990c 100644 --- a/fs/bcachefs/sb-members.h +++ b/fs/bcachefs/sb-members.h @@ -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); diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index c9bf342d14aa..16e3a8aa290d 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -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); diff --git a/fs/bcachefs/super-io.h b/fs/bcachefs/super-io.h index d51c0a19586f..817c3d790acd 100644 --- a/fs/bcachefs/super-io.h +++ b/fs/bcachefs/super-io.h @@ -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) diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index 1347270e5045..7ba1ebabc176 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -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); |