Commit d0b50524 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: bch2_bkey_packed_to_binary_text()

For debugging the eytzinger search tree code, and low level bkey packing
code, it can be helpful to see things in binary: this patch improves our
helpers for doing so.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent f0d2e9f2
...@@ -19,33 +19,49 @@ const struct bkey_format bch2_bkey_format_current = BKEY_FORMAT_CURRENT; ...@@ -19,33 +19,49 @@ const struct bkey_format bch2_bkey_format_current = BKEY_FORMAT_CURRENT;
struct bkey __bch2_bkey_unpack_key(const struct bkey_format *, struct bkey __bch2_bkey_unpack_key(const struct bkey_format *,
const struct bkey_packed *); const struct bkey_packed *);
void bch2_to_binary(char *out, const u64 *p, unsigned nr_bits) void bch2_bkey_packed_to_binary_text(struct printbuf *out,
const struct bkey_format *f,
const struct bkey_packed *k)
{ {
unsigned bit = high_bit_offset, done = 0; const u64 *p = high_word(f, k);
unsigned word_bits = 64 - high_bit_offset;
unsigned nr_key_bits = bkey_format_key_bits(f) + high_bit_offset;
u64 v = *p & (~0ULL >> high_bit_offset);
if (!nr_key_bits) {
prt_str(out, "(empty)");
return;
}
while (1) { while (1) {
while (bit < 64) { unsigned next_key_bits = nr_key_bits;
if (done && !(done % 8))
*out++ = ' '; if (nr_key_bits < 64) {
*out++ = *p & (1ULL << (63 - bit)) ? '1' : '0'; v >>= 64 - nr_key_bits;
bit++; next_key_bits = 0;
done++; } else {
if (done == nr_bits) { next_key_bits -= 64;
*out++ = '\0';
return;
}
} }
bch2_prt_u64_binary(out, v, min(word_bits, nr_key_bits));
if (!next_key_bits)
break;
prt_char(out, ' ');
p = next_word(p); p = next_word(p);
bit = 0; v = *p;
word_bits = 64;
nr_key_bits = next_key_bits;
} }
} }
#ifdef CONFIG_BCACHEFS_DEBUG #ifdef CONFIG_BCACHEFS_DEBUG
static void bch2_bkey_pack_verify(const struct bkey_packed *packed, static void bch2_bkey_pack_verify(const struct bkey_packed *packed,
const struct bkey *unpacked, const struct bkey *unpacked,
const struct bkey_format *format) const struct bkey_format *format)
{ {
struct bkey tmp; struct bkey tmp;
...@@ -57,23 +73,35 @@ static void bch2_bkey_pack_verify(const struct bkey_packed *packed, ...@@ -57,23 +73,35 @@ static void bch2_bkey_pack_verify(const struct bkey_packed *packed,
tmp = __bch2_bkey_unpack_key(format, packed); tmp = __bch2_bkey_unpack_key(format, packed);
if (memcmp(&tmp, unpacked, sizeof(struct bkey))) { if (memcmp(&tmp, unpacked, sizeof(struct bkey))) {
struct printbuf buf1 = PRINTBUF; struct printbuf buf = PRINTBUF;
struct printbuf buf2 = PRINTBUF;
char buf3[160], buf4[160];
bch2_bkey_to_text(&buf1, unpacked); prt_printf(&buf, "keys differ: format u64s %u fields %u %u %u %u %u\n",
bch2_bkey_to_text(&buf2, &tmp);
bch2_to_binary(buf3, (void *) unpacked, 80);
bch2_to_binary(buf4, high_word(format, packed), 80);
panic("keys differ: format u64s %u fields %u %u %u %u %u\n%s\n%s\n%s\n%s\n",
format->key_u64s, format->key_u64s,
format->bits_per_field[0], format->bits_per_field[0],
format->bits_per_field[1], format->bits_per_field[1],
format->bits_per_field[2], format->bits_per_field[2],
format->bits_per_field[3], format->bits_per_field[3],
format->bits_per_field[4], format->bits_per_field[4]);
buf1.buf, buf2.buf, buf3, buf4);
prt_printf(&buf, "compiled unpack: ");
bch2_bkey_to_text(&buf, unpacked);
prt_newline(&buf);
prt_printf(&buf, "c unpack: ");
bch2_bkey_to_text(&buf, &tmp);
prt_newline(&buf);
prt_printf(&buf, "compiled unpack: ");
bch2_bkey_packed_to_binary_text(&buf, &bch2_bkey_format_current,
(struct bkey_packed *) unpacked);
prt_newline(&buf);
prt_printf(&buf, "c unpack: ");
bch2_bkey_packed_to_binary_text(&buf, &bch2_bkey_format_current,
(struct bkey_packed *) &tmp);
prt_newline(&buf);
panic("%s", buf.buf);
} }
} }
......
...@@ -20,7 +20,9 @@ ...@@ -20,7 +20,9 @@
#endif #endif
#endif #endif
void bch2_to_binary(char *, const u64 *, unsigned); void bch2_bkey_packed_to_binary_text(struct printbuf *,
const struct bkey_format *,
const struct bkey_packed *);
/* bkey with split value, const */ /* bkey with split value, const */
struct bkey_s_c { struct bkey_s_c {
......
...@@ -238,6 +238,12 @@ bool bch2_is_zero(const void *_p, size_t n) ...@@ -238,6 +238,12 @@ bool bch2_is_zero(const void *_p, size_t n)
return true; return true;
} }
void bch2_prt_u64_binary(struct printbuf *out, u64 v, unsigned nr_bits)
{
while (nr_bits)
prt_char(out, '0' + ((v >> --nr_bits) & 1));
}
/* time stats: */ /* time stats: */
#ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT #ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT
......
...@@ -380,6 +380,8 @@ bool bch2_is_zero(const void *, size_t); ...@@ -380,6 +380,8 @@ bool bch2_is_zero(const void *, size_t);
u64 bch2_read_flag_list(char *, const char * const[]); u64 bch2_read_flag_list(char *, const char * const[]);
void bch2_prt_u64_binary(struct printbuf *, u64, unsigned);
#define NR_QUANTILES 15 #define NR_QUANTILES 15
#define QUANTILE_IDX(i) inorder_to_eytzinger0(i, NR_QUANTILES) #define QUANTILE_IDX(i) inorder_to_eytzinger0(i, NR_QUANTILES)
#define QUANTILE_FIRST eytzinger0_first(NR_QUANTILES) #define QUANTILE_FIRST eytzinger0_first(NR_QUANTILES)
......
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