summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/bcachefs/bcachefs_format.h2
-rw-r--r--fs/bcachefs/checksum.c5
-rw-r--r--fs/bcachefs/journal.c13
-rw-r--r--fs/bcachefs/super-io.c43
-rw-r--r--fs/bcachefs/super-io.h44
-rw-r--r--fs/bcachefs/super.c12
6 files changed, 63 insertions, 56 deletions
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
index dbb02742c47b..d70e2e32449e 100644
--- a/fs/bcachefs/bcachefs_format.h
+++ b/fs/bcachefs/bcachefs_format.h
@@ -821,7 +821,7 @@ struct bch_sb_field {
__le32 type;
};
-enum bch_sb_field_types {
+enum bch_sb_field_type {
BCH_SB_FIELD_journal = 0,
BCH_SB_FIELD_members = 1,
BCH_SB_FIELD_crypt = 2,
diff --git a/fs/bcachefs/checksum.c b/fs/bcachefs/checksum.c
index dae52d497b1a..004cc8292749 100644
--- a/fs/bcachefs/checksum.c
+++ b/fs/bcachefs/checksum.c
@@ -539,15 +539,12 @@ int bch_enable_encryption(struct cache_set *c, bool keyed)
if (ret)
goto err;
- crypt = container_of_or_null(bch_fs_sb_field_resize(c, NULL,
- sizeof(*crypt) / sizeof(u64)),
- struct bch_sb_field_crypt, field);
+ crypt = bch_fs_sb_resize_crypt(c, sizeof(*crypt) / sizeof(u64));
if (!crypt) {
ret = -ENOMEM; /* XXX this technically could be -ENOSPC */
goto err;
}
- crypt->field.type = BCH_SB_FIELD_crypt;
crypt->key = key;
/* write superblock */
diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c
index 72505e5b45fb..de2f155be6aa 100644
--- a/fs/bcachefs/journal.c
+++ b/fs/bcachefs/journal.c
@@ -545,8 +545,7 @@ static int journal_entry_validate(struct cache_set *c,
return BCH_FSCK_UNKNOWN_VERSION;
}
- if (mustfix_fsck_err_on(bytes > bucket_sectors_left << 9 ||
- bytes > c->journal.entry_size_max, c,
+ if (mustfix_fsck_err_on(bytes > bucket_sectors_left << 9, c,
"journal entry too big (%zu bytes), sector %lluu",
bytes, sector)) {
/* XXX: note we might have missing journal entries */
@@ -1540,7 +1539,6 @@ static int bch_set_nr_journal_buckets(struct cache_set *c, struct cache *ca,
struct journal *j = &c->journal;
struct journal_device *ja = &ca->journal;
struct bch_sb_field_journal *journal_buckets;
- struct bch_sb_field *f;
struct disk_reservation disk_res = { 0, 0 };
struct closure cl;
u64 *new_bucket_seq = NULL, *new_buckets = NULL;
@@ -1572,13 +1570,10 @@ static int bch_set_nr_journal_buckets(struct cache_set *c, struct cache *ca,
if (!new_buckets || !new_bucket_seq)
goto err;
- journal_buckets = bch_sb_get_journal(ca->disk_sb.sb);
- f = bch_dev_sb_field_resize(&ca->disk_sb, &journal_buckets->field, nr +
- sizeof(*journal_buckets) / sizeof(u64));
- if (!f)
+ journal_buckets = bch_sb_resize_journal(&ca->disk_sb,
+ nr + sizeof(*journal_buckets) / sizeof(u64));
+ if (!journal_buckets)
goto err;
- f->type = BCH_SB_FIELD_journal;
- journal_buckets = container_of(f, struct bch_sb_field_journal, field);
spin_lock(&j->lock);
memcpy(new_buckets, ja->buckets, ja->nr * sizeof(u64));
diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c
index 6c3fc703a772..f316f176e20d 100644
--- a/fs/bcachefs/super-io.c
+++ b/fs/bcachefs/super-io.c
@@ -18,7 +18,7 @@ static inline void __bch_sb_layout_size_assert(void)
}
struct bch_sb_field *bch_sb_field_get(struct bch_sb *sb,
- enum bch_sb_field_types type)
+ enum bch_sb_field_type type)
{
struct bch_sb_field *f;
@@ -75,7 +75,7 @@ static int __bch_super_realloc(struct bcache_superblock *sb, unsigned order)
return 0;
}
-int bch_dev_sb_realloc(struct bcache_superblock *sb, unsigned u64s)
+static int bch_sb_realloc(struct bcache_superblock *sb, unsigned u64s)
{
u64 new_bytes = __vstruct_bytes(struct bch_sb, u64s);
u64 max_bytes = 512 << sb->sb->layout.sb_max_size_bits;
@@ -141,13 +141,29 @@ static struct bch_sb_field *__bch_sb_field_resize(struct bch_sb *sb,
le32_add_cpu(&sb->u64s, u64s - old_u64s);
return f;
+}
+
+struct bch_sb_field *bch_sb_field_resize(struct bcache_superblock *sb,
+ enum bch_sb_field_type type,
+ unsigned u64s)
+{
+ struct bch_sb_field *f = bch_sb_field_get(sb->sb, type);
+ ssize_t old_u64s = f ? le32_to_cpu(f->u64s) : 0;
+ ssize_t d = -old_u64s + u64s;
+ if (bch_sb_realloc(sb, le32_to_cpu(sb->sb->u64s) + d))
+ return NULL;
+
+ f = __bch_sb_field_resize(sb->sb, f, u64s);
+ f->type = type;
+ return f;
}
struct bch_sb_field *bch_fs_sb_field_resize(struct cache_set *c,
- struct bch_sb_field *f,
+ enum bch_sb_field_type type,
unsigned u64s)
{
+ struct bch_sb_field *f = bch_sb_field_get(c->disk_sb, type);
ssize_t old_u64s = f ? le32_to_cpu(f->u64s) : 0;
ssize_t d = -old_u64s + u64s;
struct cache *ca;
@@ -161,26 +177,15 @@ struct bch_sb_field *bch_fs_sb_field_resize(struct cache_set *c,
for_each_cache(ca, c, i) {
struct bcache_superblock *sb = &ca->disk_sb;
- if (bch_dev_sb_realloc(sb, le32_to_cpu(sb->sb->u64s) + d)) {
+ if (bch_sb_realloc(sb, le32_to_cpu(sb->sb->u64s) + d)) {
percpu_ref_put(&ca->ref);
return NULL;
}
}
- return __bch_sb_field_resize(c->disk_sb, f, u64s);
-}
-
-struct bch_sb_field *bch_dev_sb_field_resize(struct bcache_superblock *sb,
- struct bch_sb_field *f,
- unsigned u64s)
-{
- ssize_t old_u64s = f ? le32_to_cpu(f->u64s) : 0;
- ssize_t d = -old_u64s + u64s;
-
- if (bch_dev_sb_realloc(sb, le32_to_cpu(sb->sb->u64s) + d))
- return NULL;
-
- return __bch_sb_field_resize(sb->sb, f, u64s);
+ f = __bch_sb_field_resize(c->disk_sb, f, u64s);
+ f->type = type;
+ return f;
}
static const char *validate_sb_layout(struct bch_sb_layout *layout)
@@ -589,7 +594,7 @@ int bch_sb_from_cache_set(struct cache_set *c, struct cache *ca)
unsigned u64s = le32_to_cpu(src->u64s) + journal_u64s;
int ret;
- ret = bch_dev_sb_realloc(&ca->disk_sb, u64s);
+ ret = bch_sb_realloc(&ca->disk_sb, u64s);
if (ret)
return ret;
diff --git a/fs/bcachefs/super-io.h b/fs/bcachefs/super-io.h
index c810aec193fb..ae1e8b9dc304 100644
--- a/fs/bcachefs/super-io.h
+++ b/fs/bcachefs/super-io.h
@@ -6,16 +6,35 @@
#include <asm/byteorder.h>
-struct bch_sb_field *bch_sb_field_get(struct bch_sb *, enum bch_sb_field_types);
-
-#define BCH_SB_FIELD_TYPE(_name) \
-static inline struct bch_sb_field_##_name * \
-bch_sb_get_##_name(struct bch_sb *sb) \
-{ \
- struct bch_sb_field *f = \
- bch_sb_field_get(sb, BCH_SB_FIELD_##_name); \
- \
- return container_of_or_null(f, struct bch_sb_field_##_name, field);\
+struct bch_sb_field *bch_sb_field_get(struct bch_sb *, enum bch_sb_field_type);
+struct bch_sb_field *bch_sb_field_resize(struct bcache_superblock *,
+ enum bch_sb_field_type, unsigned);
+struct bch_sb_field *bch_fs_sb_field_resize(struct cache_set *,
+ enum bch_sb_field_type, unsigned);
+
+#define field_to_type(_f, _name) \
+ container_of_or_null(_f, struct bch_sb_field_##_name, field)
+
+#define BCH_SB_FIELD_TYPE(_name) \
+static inline struct bch_sb_field_##_name * \
+bch_sb_get_##_name(struct bch_sb *sb) \
+{ \
+ return field_to_type(bch_sb_field_get(sb, \
+ BCH_SB_FIELD_##_name), _name); \
+} \
+ \
+static inline struct bch_sb_field_##_name * \
+bch_sb_resize_##_name(struct bcache_superblock *sb, unsigned u64s) \
+{ \
+ return field_to_type(bch_sb_field_resize(sb, \
+ BCH_SB_FIELD_##_name, u64s), _name); \
+} \
+ \
+static inline struct bch_sb_field_##_name * \
+bch_fs_sb_resize_##_name(struct cache_set *c, unsigned u64s) \
+{ \
+ return field_to_type(bch_fs_sb_field_resize(c, \
+ BCH_SB_FIELD_##_name, u64s), _name); \
}
BCH_SB_FIELD_TYPE(journal);
@@ -85,11 +104,6 @@ int bch_fs_mi_update(struct cache_set *, struct bch_member *, unsigned);
int bch_sb_to_cache_set(struct cache_set *, struct bch_sb *);
int bch_sb_from_cache_set(struct cache_set *, struct cache *);
-struct bch_sb_field *bch_fs_sb_field_resize(struct cache_set *,
- struct bch_sb_field *, unsigned);
-struct bch_sb_field *bch_dev_sb_field_resize(struct bcache_superblock *,
- struct bch_sb_field *, unsigned);
-
void bch_free_super(struct bcache_superblock *);
int bch_super_realloc(struct bcache_superblock *, unsigned);
diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c
index 9bb5f8e393ac..cc3731e3f368 100644
--- a/fs/bcachefs/super.c
+++ b/fs/bcachefs/super.c
@@ -1512,7 +1512,6 @@ int bch_dev_add(struct cache_set *c, const char *path)
struct bcache_superblock sb;
const char *err;
struct cache *ca;
- struct bch_sb_field *f;
struct bch_sb_field_members *mi, *dev_mi;
struct bch_member saved_mi;
unsigned dev_idx, nr_devices, u64s;
@@ -1571,17 +1570,14 @@ have_slot:
sizeof(struct bch_member) * nr_devices) / sizeof(u64);
err = "no space in superblock for member info";
- f = bch_fs_sb_field_resize(c, &mi->field, u64s);
- if (!f)
+ mi = bch_fs_sb_resize_members(c, u64s);
+ if (!mi)
goto err_unlock;
- mi = container_of(f, struct bch_sb_field_members, field);
-
- f = bch_dev_sb_field_resize(&sb, &dev_mi->field, u64s);
- if (!f)
+ dev_mi = bch_sb_resize_members(&sb, u64s);
+ if (!dev_mi)
goto err_unlock;
- dev_mi = container_of(f, struct bch_sb_field_members, field);
memcpy(dev_mi, mi, u64s * sizeof(u64));
dev_mi->members[dev_idx] = saved_mi;