Commit 6c643965 authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bkey_format helper improvements

 - add a to_text() method for bkey_format

 - convert bch2_bkey_format_validate() to modern error message style,
   where we pass a printbuf for the error string instead of returning a
   static string
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent dde8cb11
...@@ -608,12 +608,15 @@ struct bkey_format bch2_bkey_format_done(struct bkey_format_state *s) ...@@ -608,12 +608,15 @@ struct bkey_format bch2_bkey_format_done(struct bkey_format_state *s)
return ret; return ret;
} }
const char *bch2_bkey_format_validate(struct bkey_format *f) int bch2_bkey_format_validate(struct bkey_format *f, struct printbuf *err)
{ {
unsigned i, bits = KEY_PACKED_BITS_START; unsigned i, bits = KEY_PACKED_BITS_START;
if (f->nr_fields != BKEY_NR_FIELDS) if (f->nr_fields != BKEY_NR_FIELDS) {
return "incorrect number of fields"; prt_printf(err, "incorrect number of fields: got %u, should be %u",
f->nr_fields, BKEY_NR_FIELDS);
return -BCH_ERR_invalid;
}
/* /*
* Verify that the packed format can't represent fields larger than the * Verify that the packed format can't represent fields larger than the
...@@ -628,16 +631,35 @@ const char *bch2_bkey_format_validate(struct bkey_format *f) ...@@ -628,16 +631,35 @@ const char *bch2_bkey_format_validate(struct bkey_format *f)
u64 field_offset = le64_to_cpu(f->field_offset[i]); u64 field_offset = le64_to_cpu(f->field_offset[i]);
if (packed_max + field_offset < packed_max || if (packed_max + field_offset < packed_max ||
packed_max + field_offset > unpacked_max) packed_max + field_offset > unpacked_max) {
return "field too large"; prt_printf(err, "field %u too large: %llu + %llu > %llu",
i, packed_max, field_offset, unpacked_max);
return -BCH_ERR_invalid;
}
bits += f->bits_per_field[i]; bits += f->bits_per_field[i];
} }
if (f->key_u64s != DIV_ROUND_UP(bits, 64)) if (f->key_u64s != DIV_ROUND_UP(bits, 64)) {
return "incorrect key_u64s"; prt_printf(err, "incorrect key_u64s: got %u, should be %u",
f->key_u64s, DIV_ROUND_UP(bits, 64));
return -BCH_ERR_invalid;
}
return 0;
}
return NULL; void bch2_bkey_format_to_text(struct printbuf *out, const struct bkey_format *f)
{
prt_printf(out, "u64s %u fields ", f->key_u64s);
for (unsigned i = 0; i < ARRAY_SIZE(f->bits_per_field); i++) {
if (i)
prt_str(out, ", ");
prt_printf(out, "%u:%llu",
f->bits_per_field[i],
le64_to_cpu(f->field_offset[i]));
}
} }
/* /*
......
...@@ -769,6 +769,7 @@ static inline void bch2_bkey_format_add_key(struct bkey_format_state *s, const s ...@@ -769,6 +769,7 @@ static inline void bch2_bkey_format_add_key(struct bkey_format_state *s, const s
void bch2_bkey_format_add_pos(struct bkey_format_state *, struct bpos); void bch2_bkey_format_add_pos(struct bkey_format_state *, struct bpos);
struct bkey_format bch2_bkey_format_done(struct bkey_format_state *); struct bkey_format bch2_bkey_format_done(struct bkey_format_state *);
const char *bch2_bkey_format_validate(struct bkey_format *); int bch2_bkey_format_validate(struct bkey_format *, struct printbuf *);
void bch2_bkey_format_to_text(struct printbuf *, const struct bkey_format *);
#endif /* _BCACHEFS_BKEY_H */ #endif /* _BCACHEFS_BKEY_H */
...@@ -1165,7 +1165,6 @@ void bch2_btree_node_evict(struct btree_trans *trans, const struct bkey_i *k) ...@@ -1165,7 +1165,6 @@ void bch2_btree_node_evict(struct btree_trans *trans, const struct bkey_i *k)
void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c, void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c,
const struct btree *b) const struct btree *b)
{ {
const struct bkey_format *f = &b->format;
struct bset_stats stats; struct bset_stats stats;
memset(&stats, 0, sizeof(stats)); memset(&stats, 0, sizeof(stats));
...@@ -1179,9 +1178,13 @@ void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c, ...@@ -1179,9 +1178,13 @@ void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c,
prt_printf(out, ":\n" prt_printf(out, ":\n"
" ptrs: "); " ptrs: ");
bch2_val_to_text(out, c, bkey_i_to_s_c(&b->key)); bch2_val_to_text(out, c, bkey_i_to_s_c(&b->key));
prt_newline(out);
prt_printf(out, "\n" prt_printf(out,
" format: u64s %u fields %u %u %u %u %u\n" " format: ");
bch2_bkey_format_to_text(out, &b->format);
prt_printf(out,
" unpack fn len: %u\n" " unpack fn len: %u\n"
" bytes used %zu/%zu (%zu%% full)\n" " bytes used %zu/%zu (%zu%% full)\n"
" sib u64s: %u, %u (merge threshold %u)\n" " sib u64s: %u, %u (merge threshold %u)\n"
...@@ -1189,12 +1192,6 @@ void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c, ...@@ -1189,12 +1192,6 @@ void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c,
" nr unpacked keys %u\n" " nr unpacked keys %u\n"
" floats %zu\n" " floats %zu\n"
" failed unpacked %zu\n", " failed unpacked %zu\n",
f->key_u64s,
f->bits_per_field[0],
f->bits_per_field[1],
f->bits_per_field[2],
f->bits_per_field[3],
f->bits_per_field[4],
b->unpack_fn_len, b->unpack_fn_len,
b->nr.live_u64s * sizeof(u64), b->nr.live_u64s * sizeof(u64),
btree_bytes(c) - sizeof(struct btree_node), btree_bytes(c) - sizeof(struct btree_node),
......
...@@ -694,7 +694,6 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca, ...@@ -694,7 +694,6 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
int write, bool have_retry, bool *saw_error) int write, bool have_retry, bool *saw_error)
{ {
unsigned version = le16_to_cpu(i->version); unsigned version = le16_to_cpu(i->version);
const char *err;
struct printbuf buf1 = PRINTBUF; struct printbuf buf1 = PRINTBUF;
struct printbuf buf2 = PRINTBUF; struct printbuf buf2 = PRINTBUF;
int ret = 0; int ret = 0;
...@@ -802,10 +801,12 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca, ...@@ -802,10 +801,12 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
compat_btree_node(b->c.level, b->c.btree_id, version, compat_btree_node(b->c.level, b->c.btree_id, version,
BSET_BIG_ENDIAN(i), write, bn); BSET_BIG_ENDIAN(i), write, bn);
err = bch2_bkey_format_validate(&bn->format); btree_err_on(bch2_bkey_format_validate(&bn->format, &buf1),
btree_err_on(err,
BTREE_ERR_BAD_NODE, c, ca, b, i, BTREE_ERR_BAD_NODE, c, ca, b, i,
"invalid bkey format: %s", err); "invalid bkey format: %s\n %s", buf1.buf,
(printbuf_reset(&buf2),
bch2_bkey_format_to_text(&buf2, &bn->format), buf2.buf));
printbuf_reset(&buf1);
compat_bformat(b->c.level, b->c.btree_id, version, compat_bformat(b->c.level, b->c.btree_id, version,
BSET_BIG_ENDIAN(i), write, BSET_BIG_ENDIAN(i), write,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment