mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-29 09:12:07 +00:00
bcachefs: Plumb bch_validate_flags to sb_field_ops.validate()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
65eaf4e24a
commit
a5c3e265d3
@ -469,9 +469,8 @@ int bch2_rechecksum_bio(struct bch_fs *c, struct bio *bio,
|
|||||||
|
|
||||||
/* BCH_SB_FIELD_crypt: */
|
/* BCH_SB_FIELD_crypt: */
|
||||||
|
|
||||||
static int bch2_sb_crypt_validate(struct bch_sb *sb,
|
static int bch2_sb_crypt_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct bch_sb_field *f,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
struct bch_sb_field_crypt *crypt = field_to_type(f, crypt);
|
struct bch_sb_field_crypt *crypt = field_to_type(f, crypt);
|
||||||
|
|
||||||
|
@ -18,9 +18,8 @@ static int group_cmp(const void *_l, const void *_r)
|
|||||||
strncmp(l->label, r->label, sizeof(l->label));
|
strncmp(l->label, r->label, sizeof(l->label));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_disk_groups_validate(struct bch_sb *sb,
|
static int bch2_sb_disk_groups_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct bch_sb_field *f,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
struct bch_sb_field_disk_groups *groups =
|
struct bch_sb_field_disk_groups *groups =
|
||||||
field_to_type(f, disk_groups);
|
field_to_type(f, disk_groups);
|
||||||
|
@ -16,9 +16,8 @@ static int u64_cmp(const void *_l, const void *_r)
|
|||||||
return cmp_int(*l, *r);
|
return cmp_int(*l, *r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_journal_validate(struct bch_sb *sb,
|
static int bch2_sb_journal_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct bch_sb_field *f,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
struct bch_sb_field_journal *journal = field_to_type(f, journal);
|
struct bch_sb_field_journal *journal = field_to_type(f, journal);
|
||||||
struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
|
struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
|
||||||
@ -99,9 +98,8 @@ static int u64_range_cmp(const void *_l, const void *_r)
|
|||||||
return cmp_int(l->start, r->start);
|
return cmp_int(l->start, r->start);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_journal_v2_validate(struct bch_sb *sb,
|
static int bch2_sb_journal_v2_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct bch_sb_field *f,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2);
|
struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2);
|
||||||
struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
|
struct bch_member m = bch2_sb_member_get(sb, sb->dev_idx);
|
||||||
|
@ -162,9 +162,8 @@ int bch2_blacklist_table_initialize(struct bch_fs *c)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_journal_seq_blacklist_validate(struct bch_sb *sb,
|
static int bch2_sb_journal_seq_blacklist_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct bch_sb_field *f,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
struct bch_sb_field_journal_seq_blacklist *bl =
|
struct bch_sb_field_journal_seq_blacklist *bl =
|
||||||
field_to_type(f, journal_seq_blacklist);
|
field_to_type(f, journal_seq_blacklist);
|
||||||
|
@ -20,7 +20,7 @@ static const char * const bch2_quota_counters[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int bch2_sb_quota_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
static int bch2_sb_quota_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct printbuf *err)
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
{
|
{
|
||||||
struct bch_sb_field_quota *q = field_to_type(f, quota);
|
struct bch_sb_field_quota *q = field_to_type(f, quota);
|
||||||
|
|
||||||
@ -60,8 +60,7 @@ const struct bch_sb_field_ops bch_sb_field_ops_quota = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int bch2_quota_invalid(struct bch_fs *c, struct bkey_s_c k,
|
int bch2_quota_invalid(struct bch_fs *c, struct bkey_s_c k,
|
||||||
enum bch_validate_flags flags,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -860,7 +860,7 @@ static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_replicas_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
static int bch2_sb_replicas_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct printbuf *err)
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
{
|
{
|
||||||
struct bch_sb_field_replicas *sb_r = field_to_type(f, replicas);
|
struct bch_sb_field_replicas *sb_r = field_to_type(f, replicas);
|
||||||
struct bch_replicas_cpu cpu_r;
|
struct bch_replicas_cpu cpu_r;
|
||||||
@ -899,7 +899,7 @@ const struct bch_sb_field_ops bch_sb_field_ops_replicas = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int bch2_sb_replicas_v0_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
static int bch2_sb_replicas_v0_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct printbuf *err)
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
{
|
{
|
||||||
struct bch_sb_field_replicas_v0 *sb_r = field_to_type(f, replicas_v0);
|
struct bch_sb_field_replicas_v0 *sb_r = field_to_type(f, replicas_v0);
|
||||||
struct bch_replicas_cpu cpu_r;
|
struct bch_replicas_cpu cpu_r;
|
||||||
|
@ -266,9 +266,8 @@ void bch2_journal_super_entries_add_common(struct bch_fs *c,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_clean_validate(struct bch_sb *sb,
|
static int bch2_sb_clean_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct bch_sb_field *f,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
struct bch_sb_field_clean *clean = field_to_type(f, clean);
|
struct bch_sb_field_clean *clean = field_to_type(f, clean);
|
||||||
|
|
||||||
|
@ -20,9 +20,8 @@ static size_t bch2_sb_counter_nr_entries(struct bch_sb_field_counters *ctrs)
|
|||||||
return (__le64 *) vstruct_end(&ctrs->field) - &ctrs->d[0];
|
return (__le64 *) vstruct_end(&ctrs->field) - &ctrs->d[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int bch2_sb_counters_validate(struct bch_sb *sb,
|
static int bch2_sb_counters_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct bch_sb_field *f,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
@ -138,7 +138,7 @@ downgrade_entry_next_c(const struct bch_sb_field_downgrade_entry *e)
|
|||||||
_i = downgrade_entry_next_c(_i))
|
_i = downgrade_entry_next_c(_i))
|
||||||
|
|
||||||
static int bch2_sb_downgrade_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
static int bch2_sb_downgrade_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct printbuf *err)
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
{
|
{
|
||||||
struct bch_sb_field_downgrade *e = field_to_type(f, downgrade);
|
struct bch_sb_field_downgrade *e = field_to_type(f, downgrade);
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ static inline unsigned bch2_sb_field_errors_u64s(unsigned nr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_errors_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
static int bch2_sb_errors_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct printbuf *err)
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
{
|
{
|
||||||
struct bch_sb_field_errors *e = field_to_type(f, errors);
|
struct bch_sb_field_errors *e = field_to_type(f, errors);
|
||||||
unsigned i, nr = bch2_sb_field_errors_nr_entries(e);
|
unsigned i, nr = bch2_sb_field_errors_nr_entries(e);
|
||||||
|
@ -261,9 +261,8 @@ static void member_to_text(struct printbuf *out,
|
|||||||
printbuf_indent_sub(out, 2);
|
printbuf_indent_sub(out, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_members_v1_validate(struct bch_sb *sb,
|
static int bch2_sb_members_v1_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct bch_sb_field *f,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
struct bch_sb_field_members_v1 *mi = field_to_type(f, members_v1);
|
struct bch_sb_field_members_v1 *mi = field_to_type(f, members_v1);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -311,9 +310,8 @@ static void bch2_sb_members_v2_to_text(struct printbuf *out, struct bch_sb *sb,
|
|||||||
member_to_text(out, members_v2_get(mi, i), gi, sb, i);
|
member_to_text(out, members_v2_get(mi, i), gi, sb, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_members_v2_validate(struct bch_sb *sb,
|
static int bch2_sb_members_v2_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct bch_sb_field *f,
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
struct printbuf *err)
|
|
||||||
{
|
{
|
||||||
struct bch_sb_field_members_v2 *mi = field_to_type(f, members_v2);
|
struct bch_sb_field_members_v2 *mi = field_to_type(f, members_v2);
|
||||||
size_t mi_bytes = (void *) __bch2_members_v2_get_mut(mi, sb->nr_devices) -
|
size_t mi_bytes = (void *) __bch2_members_v2_get_mut(mi, sb->nr_devices) -
|
||||||
|
@ -76,7 +76,7 @@ const char * const bch2_sb_fields[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int bch2_sb_field_validate(struct bch_sb *, struct bch_sb_field *,
|
static int bch2_sb_field_validate(struct bch_sb *, struct bch_sb_field *,
|
||||||
struct printbuf *);
|
enum bch_validate_flags, struct printbuf *);
|
||||||
|
|
||||||
struct bch_sb_field *bch2_sb_field_get_id(struct bch_sb *sb,
|
struct bch_sb_field *bch2_sb_field_get_id(struct bch_sb *sb,
|
||||||
enum bch_sb_field_type type)
|
enum bch_sb_field_type type)
|
||||||
@ -344,8 +344,8 @@ static int bch2_sb_compatible(struct bch_sb *sb, struct printbuf *out)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
|
static int bch2_sb_validate(struct bch_sb_handle *disk_sb,
|
||||||
int rw)
|
enum bch_validate_flags flags, struct printbuf *out)
|
||||||
{
|
{
|
||||||
struct bch_sb *sb = disk_sb->sb;
|
struct bch_sb *sb = disk_sb->sb;
|
||||||
struct bch_sb_field_members_v1 *mi;
|
struct bch_sb_field_members_v1 *mi;
|
||||||
@ -401,7 +401,7 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
|
|||||||
return -BCH_ERR_invalid_sb_time_precision;
|
return -BCH_ERR_invalid_sb_time_precision;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rw == READ) {
|
if (!flags) {
|
||||||
/*
|
/*
|
||||||
* Been seeing a bug where these are getting inexplicably
|
* Been seeing a bug where these are getting inexplicably
|
||||||
* zeroed, so we're now validating them, but we have to be
|
* zeroed, so we're now validating them, but we have to be
|
||||||
@ -457,7 +457,7 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
|
|||||||
return -BCH_ERR_invalid_sb_members_missing;
|
return -BCH_ERR_invalid_sb_members_missing;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bch2_sb_field_validate(sb, &mi->field, out);
|
ret = bch2_sb_field_validate(sb, &mi->field, flags, out);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -465,12 +465,12 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
|
|||||||
if (le32_to_cpu(f->type) == BCH_SB_FIELD_members_v1)
|
if (le32_to_cpu(f->type) == BCH_SB_FIELD_members_v1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = bch2_sb_field_validate(sb, f, out);
|
ret = bch2_sb_field_validate(sb, f, flags, out);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rw == WRITE &&
|
if ((flags & BCH_VALIDATE_write) &&
|
||||||
bch2_sb_member_get(sb, sb->dev_idx).seq != sb->seq) {
|
bch2_sb_member_get(sb, sb->dev_idx).seq != sb->seq) {
|
||||||
prt_printf(out, "Invalid superblock: member seq %llu != sb seq %llu",
|
prt_printf(out, "Invalid superblock: member seq %llu != sb seq %llu",
|
||||||
le64_to_cpu(bch2_sb_member_get(sb, sb->dev_idx).seq),
|
le64_to_cpu(bch2_sb_member_get(sb, sb->dev_idx).seq),
|
||||||
@ -819,7 +819,7 @@ static int __bch2_read_super(const char *path, struct bch_opts *opts,
|
|||||||
|
|
||||||
sb->have_layout = true;
|
sb->have_layout = true;
|
||||||
|
|
||||||
ret = bch2_sb_validate(sb, &err, READ);
|
ret = bch2_sb_validate(sb, 0, &err);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
bch2_print_opts(opts, KERN_ERR "bcachefs (%s): error validating superblock: %s\n",
|
bch2_print_opts(opts, KERN_ERR "bcachefs (%s): error validating superblock: %s\n",
|
||||||
path, err.buf);
|
path, err.buf);
|
||||||
@ -975,7 +975,7 @@ int bch2_write_super(struct bch_fs *c)
|
|||||||
darray_for_each(online_devices, ca) {
|
darray_for_each(online_devices, ca) {
|
||||||
printbuf_reset(&err);
|
printbuf_reset(&err);
|
||||||
|
|
||||||
ret = bch2_sb_validate(&(*ca)->disk_sb, &err, WRITE);
|
ret = bch2_sb_validate(&(*ca)->disk_sb, BCH_VALIDATE_write, &err);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
bch2_fs_inconsistent(c, "sb invalid before write: %s", err.buf);
|
bch2_fs_inconsistent(c, "sb invalid before write: %s", err.buf);
|
||||||
goto out;
|
goto out;
|
||||||
@ -1161,7 +1161,7 @@ void bch2_sb_upgrade(struct bch_fs *c, unsigned new_version)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_ext_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
static int bch2_sb_ext_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct printbuf *err)
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
{
|
{
|
||||||
if (vstruct_bytes(f) < 88) {
|
if (vstruct_bytes(f) < 88) {
|
||||||
prt_printf(err, "field too small (%zu < %u)", vstruct_bytes(f), 88);
|
prt_printf(err, "field too small (%zu < %u)", vstruct_bytes(f), 88);
|
||||||
@ -1219,14 +1219,14 @@ static const struct bch_sb_field_ops *bch2_sb_field_type_ops(unsigned type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int bch2_sb_field_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
static int bch2_sb_field_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||||
struct printbuf *err)
|
enum bch_validate_flags flags, struct printbuf *err)
|
||||||
{
|
{
|
||||||
unsigned type = le32_to_cpu(f->type);
|
unsigned type = le32_to_cpu(f->type);
|
||||||
struct printbuf field_err = PRINTBUF;
|
struct printbuf field_err = PRINTBUF;
|
||||||
const struct bch_sb_field_ops *ops = bch2_sb_field_type_ops(type);
|
const struct bch_sb_field_ops *ops = bch2_sb_field_type_ops(type);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = ops->validate ? ops->validate(sb, f, &field_err) : 0;
|
ret = ops->validate ? ops->validate(sb, f, flags, &field_err) : 0;
|
||||||
if (ret) {
|
if (ret) {
|
||||||
prt_printf(err, "Invalid superblock section %s: %s",
|
prt_printf(err, "Invalid superblock section %s: %s",
|
||||||
bch2_sb_fields[type], field_err.buf);
|
bch2_sb_fields[type], field_err.buf);
|
||||||
|
@ -51,7 +51,8 @@ void bch2_sb_field_delete(struct bch_sb_handle *, enum bch_sb_field_type);
|
|||||||
extern const char * const bch2_sb_fields[];
|
extern const char * const bch2_sb_fields[];
|
||||||
|
|
||||||
struct bch_sb_field_ops {
|
struct bch_sb_field_ops {
|
||||||
int (*validate)(struct bch_sb *, struct bch_sb_field *, struct printbuf *);
|
int (*validate)(struct bch_sb *, struct bch_sb_field *,
|
||||||
|
enum bch_validate_flags, struct printbuf *);
|
||||||
void (*to_text)(struct printbuf *, struct bch_sb *, struct bch_sb_field *);
|
void (*to_text)(struct printbuf *, struct bch_sb *, struct bch_sb_field *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user