bcachefs: Plumb bch_validate_flags to sb_field_ops.validate()

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2024-05-08 18:49:14 -04:00
parent 65eaf4e24a
commit a5c3e265d3
13 changed files with 38 additions and 47 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}; };

View File

@ -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);

View File

@ -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);

View File

@ -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) -

View File

@ -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 @@ got_super:
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);

View File

@ -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 *);
}; };