From 6c6439650ec913c83d48055da63b8f204075afb7 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Thu, 3 Aug 2023 14:42:37 -0400 Subject: [PATCH] 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: Kent Overstreet --- fs/bcachefs/bkey.c | 38 ++++++++++++++++++++++++++++++-------- fs/bcachefs/bkey.h | 3 ++- fs/bcachefs/btree_cache.c | 15 ++++++--------- fs/bcachefs/btree_io.c | 9 +++++---- 4 files changed, 43 insertions(+), 22 deletions(-) diff --git a/fs/bcachefs/bkey.c b/fs/bcachefs/bkey.c index ee7ba700e75f..b7b77f459724 100644 --- a/fs/bcachefs/bkey.c +++ b/fs/bcachefs/bkey.c @@ -608,12 +608,15 @@ struct bkey_format bch2_bkey_format_done(struct bkey_format_state *s) 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; - if (f->nr_fields != BKEY_NR_FIELDS) - return "incorrect number of fields"; + if (f->nr_fields != BKEY_NR_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 @@ -628,16 +631,35 @@ const char *bch2_bkey_format_validate(struct bkey_format *f) u64 field_offset = le64_to_cpu(f->field_offset[i]); if (packed_max + field_offset < packed_max || - packed_max + field_offset > unpacked_max) - return "field too large"; + packed_max + field_offset > unpacked_max) { + 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]; } - if (f->key_u64s != DIV_ROUND_UP(bits, 64)) - return "incorrect key_u64s"; + if (f->key_u64s != DIV_ROUND_UP(bits, 64)) { + prt_printf(err, "incorrect key_u64s: got %u, should be %u", + f->key_u64s, DIV_ROUND_UP(bits, 64)); + return -BCH_ERR_invalid; + } - return NULL; + return 0; +} + +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])); + } } /* diff --git a/fs/bcachefs/bkey.h b/fs/bcachefs/bkey.h index e81fb3e00c60..644caa2b2b25 100644 --- a/fs/bcachefs/bkey.h +++ b/fs/bcachefs/bkey.h @@ -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); 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 */ diff --git a/fs/bcachefs/btree_cache.c b/fs/bcachefs/btree_cache.c index 346bfaf99460..245ddd92b2d1 100644 --- a/fs/bcachefs/btree_cache.c +++ b/fs/bcachefs/btree_cache.c @@ -1165,7 +1165,6 @@ wait_on_io: void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c, const struct btree *b) { - const struct bkey_format *f = &b->format; struct bset_stats stats; memset(&stats, 0, sizeof(stats)); @@ -1179,9 +1178,13 @@ void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c, prt_printf(out, ":\n" " ptrs: "); bch2_val_to_text(out, c, bkey_i_to_s_c(&b->key)); + prt_newline(out); - prt_printf(out, "\n" - " format: u64s %u fields %u %u %u %u %u\n" + prt_printf(out, + " format: "); + bch2_bkey_format_to_text(out, &b->format); + + prt_printf(out, " unpack fn len: %u\n" " bytes used %zu/%zu (%zu%% full)\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, " nr unpacked keys %u\n" " floats %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->nr.live_u64s * sizeof(u64), btree_bytes(c) - sizeof(struct btree_node), diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c index 7bfb8b8d4cb5..2339395e0bd2 100644 --- a/fs/bcachefs/btree_io.c +++ b/fs/bcachefs/btree_io.c @@ -694,7 +694,6 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca, int write, bool have_retry, bool *saw_error) { unsigned version = le16_to_cpu(i->version); - const char *err; struct printbuf buf1 = PRINTBUF; struct printbuf buf2 = PRINTBUF; int ret = 0; @@ -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, BSET_BIG_ENDIAN(i), write, bn); - err = bch2_bkey_format_validate(&bn->format); - btree_err_on(err, + btree_err_on(bch2_bkey_format_validate(&bn->format, &buf1), 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, BSET_BIG_ENDIAN(i), write,