bcachefs: bch2_bkey_packed_to_binary_text()
authorKent Overstreet <kent.overstreet@gmail.com>
Sun, 14 Aug 2022 18:44:17 +0000 (14:44 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:38 +0000 (17:09 -0400)
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: Kent Overstreet <kent.overstreet@gmail.com>
fs/bcachefs/bkey.c
fs/bcachefs/bkey.h
fs/bcachefs/util.c
fs/bcachefs/util.h

index a1115abf83bb2757b493e539e673ff2b48da232a..52af6f370eb9c5ed47046a2f3ed61c24b9e86585 100644 (file)
@@ -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 *,
                              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 (bit < 64) {
-                       if (done && !(done % 8))
-                               *out++ = ' ';
-                       *out++ = *p & (1ULL << (63 - bit)) ? '1' : '0';
-                       bit++;
-                       done++;
-                       if (done == nr_bits) {
-                               *out++ = '\0';
-                               return;
-                       }
+               unsigned next_key_bits = nr_key_bits;
+
+               if (nr_key_bits < 64) {
+                       v >>= 64 - nr_key_bits;
+                       next_key_bits = 0;
+               } else {
+                       next_key_bits -= 64;
                }
 
+               bch2_prt_u64_binary(out, v, min(word_bits, nr_key_bits));
+
+               if (!next_key_bits)
+                       break;
+
+               prt_char(out, ' ');
+
                p = next_word(p);
-               bit = 0;
+               v = *p;
+               word_bits = 64;
+               nr_key_bits = next_key_bits;
        }
 }
 
 #ifdef CONFIG_BCACHEFS_DEBUG
 
 static void bch2_bkey_pack_verify(const struct bkey_packed *packed,
-                                const struct bkey *unpacked,
-                                const struct bkey_format *format)
+                                 const struct bkey *unpacked,
+                                 const struct bkey_format *format)
 {
        struct bkey tmp;
 
@@ -57,23 +73,35 @@ static void bch2_bkey_pack_verify(const struct bkey_packed *packed,
        tmp = __bch2_bkey_unpack_key(format, packed);
 
        if (memcmp(&tmp, unpacked, sizeof(struct bkey))) {
-               struct printbuf buf1 = PRINTBUF;
-               struct printbuf buf2 = PRINTBUF;
-               char buf3[160], buf4[160];
+               struct printbuf buf = PRINTBUF;
 
-               bch2_bkey_to_text(&buf1, unpacked);
-               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",
+               prt_printf(&buf, "keys differ: format u64s %u fields %u %u %u %u %u\n",
                      format->key_u64s,
                      format->bits_per_field[0],
                      format->bits_per_field[1],
                      format->bits_per_field[2],
                      format->bits_per_field[3],
-                     format->bits_per_field[4],
-                     buf1.buf, buf2.buf, buf3, buf4);
+                     format->bits_per_field[4]);
+
+               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);
        }
 }
 
index 8e9405f89537755380505428b92888d6217bd6be..2e7e6b6b4af7109ddcf34a1474a0fd396153b41f 100644 (file)
@@ -20,7 +20,9 @@
 #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 */
 struct bkey_s_c {
index cb07ef2ceb5975fa625cf79ea1e1ef4928440c90..61cd44c5a6b4a0af73a9189ea8810d16f83c2261 100644 (file)
@@ -238,6 +238,12 @@ bool bch2_is_zero(const void *_p, size_t n)
        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: */
 
 #ifndef CONFIG_BCACHEFS_NO_LATENCY_ACCT
index d5b19b1b2020e56f0788139d27655f3feaa3186f..192d8b53f2ca42139a4d2df267128b8870cb1156 100644 (file)
@@ -380,6 +380,8 @@ bool bch2_is_zero(const void *, size_t);
 
 u64 bch2_read_flag_list(char *, const char * const[]);
 
+void bch2_prt_u64_binary(struct printbuf *, u64, unsigned);
+
 #define NR_QUANTILES   15
 #define QUANTILE_IDX(i)        inorder_to_eytzinger0(i, NR_QUANTILES)
 #define QUANTILE_FIRST eytzinger0_first(NR_QUANTILES)