bcachefs: Standardize helpers for printing enum strs with bounds checks
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 12 Apr 2024 19:17:00 +0000 (15:17 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 14 Apr 2024 02:48:17 +0000 (22:48 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs_format.h
fs/bcachefs/buckets.h
fs/bcachefs/checksum.c
fs/bcachefs/checksum.h
fs/bcachefs/compress.h
fs/bcachefs/ec.c
fs/bcachefs/extents.c
fs/bcachefs/journal_io.c
fs/bcachefs/opts.c
fs/bcachefs/opts.h

index 364ae42022af1750f9887d3f16c566a676b30776..9480f1b44f07178af222fa9ebec4d8957b6584cd 100644 (file)
@@ -1314,7 +1314,7 @@ static inline __u64 __bset_magic(struct bch_sb *sb)
        x(write_buffer_keys,    11)             \
        x(datetime,             12)
 
-enum {
+enum bch_jset_entry_type {
 #define x(f, nr)       BCH_JSET_ENTRY_##f      = nr,
        BCH_JSET_ENTRY_TYPES()
 #undef x
@@ -1360,7 +1360,7 @@ struct jset_entry_blacklist_v2 {
        x(inodes,               1)              \
        x(key_version,          2)
 
-enum {
+enum bch_fs_usage_type {
 #define x(f, nr)       BCH_FS_USAGE_##f        = nr,
        BCH_FS_USAGE_TYPES()
 #undef x
index 00aaf4bb513974a6b9c0353ea9445f92671c32eb..f9af5adabe83638eea7ffd15ea2f730085f81cc1 100644 (file)
@@ -395,14 +395,6 @@ static inline const char *bch2_data_type_str(enum bch_data_type type)
                : "(invalid data type)";
 }
 
-static inline void bch2_prt_data_type(struct printbuf *out, enum bch_data_type type)
-{
-       if (type < BCH_DATA_NR)
-               prt_str(out, __bch2_data_types[type]);
-       else
-               prt_printf(out, "(invalid data type %u)", type);
-}
-
 /* disk reservations: */
 
 static inline void bch2_disk_reservation_put(struct bch_fs *c,
index 4701457f6381ca820e17a12707009c272ed5b4ac..7ed779b411f61e4e3f05a703ce9e091474237939 100644 (file)
@@ -429,15 +429,20 @@ int bch2_rechecksum_bio(struct bch_fs *c, struct bio *bio,
                                extent_nonce(version, crc_old), bio);
 
        if (bch2_crc_cmp(merged, crc_old.csum) && !c->opts.no_data_io) {
-               bch_err(c, "checksum error in %s() (memory corruption or bug?)\n"
-                       "expected %0llx:%0llx got %0llx:%0llx (old type %s new type %s)",
-                       __func__,
-                       crc_old.csum.hi,
-                       crc_old.csum.lo,
-                       merged.hi,
-                       merged.lo,
-                       bch2_csum_types[crc_old.csum_type],
-                       bch2_csum_types[new_csum_type]);
+               struct printbuf buf = PRINTBUF;
+               prt_printf(&buf, "checksum error in %s() (memory corruption or bug?)\n"
+                          "expected %0llx:%0llx got %0llx:%0llx (old type ",
+                          __func__,
+                          crc_old.csum.hi,
+                          crc_old.csum.lo,
+                          merged.hi,
+                          merged.lo);
+               bch2_prt_csum_type(&buf, crc_old.csum_type);
+               prt_str(&buf, " new type ");
+               bch2_prt_csum_type(&buf, new_csum_type);
+               prt_str(&buf, ")");
+               bch_err(c, "%s", buf.buf);
+               printbuf_exit(&buf);
                return -EIO;
        }
 
index 1b8c2c1016dc6347ce12ef3161d4723835dfa56e..e40499fde9a4019fc75d62f825e9e5583caf803b 100644 (file)
@@ -61,11 +61,12 @@ static inline void bch2_csum_err_msg(struct printbuf *out,
                                     struct bch_csum expected,
                                     struct bch_csum got)
 {
-       prt_printf(out, "checksum error: got ");
+       prt_str(out, "checksum error, type ");
+       bch2_prt_csum_type(out, type);
+       prt_str(out, ": got ");
        bch2_csum_to_text(out, type, got);
        prt_str(out, " should be ");
        bch2_csum_to_text(out, type, expected);
-       prt_printf(out, " type %s", bch2_csum_types[type]);
 }
 
 int bch2_chacha_encrypt_key(struct bch_key *, struct nonce, void *, size_t);
index 58c2eb45570ff022764720f9beb10ecfa2926367..607fd5e232c902dbb39f3dac84ea2e214e6b106c 100644 (file)
@@ -47,14 +47,6 @@ static inline enum bch_compression_type bch2_compression_opt_to_type(unsigned v)
        return __bch2_compression_opt_to_type[bch2_compression_decode(v).type];
 }
 
-static inline void bch2_prt_compression_type(struct printbuf *out, enum bch_compression_type type)
-{
-       if (type < BCH_COMPRESSION_TYPE_NR)
-               prt_str(out, __bch2_compression_types[type]);
-       else
-               prt_printf(out, "(invalid compression type %u)", type);
-}
-
 int bch2_bio_uncompress_inplace(struct bch_fs *, struct bio *,
                                struct bch_extent_crc_unpacked *);
 int bch2_bio_uncompress(struct bch_fs *, struct bio *, struct bio *,
index c0b2b2f180e014da5e2252e1fdd50e9ac8081aa0..556a217108d32ef35890da0463751afc688186f3 100644 (file)
@@ -138,13 +138,13 @@ void bch2_stripe_to_text(struct printbuf *out, struct bch_fs *c,
 
        unsigned nr_data = s.nr_blocks - s.nr_redundant;
 
-       prt_printf(out, "algo %u sectors %u blocks %u:%u csum %u gran %u",
+       prt_printf(out, "algo %u sectors %u blocks %u:%u csum ",
                   s.algorithm,
                   le16_to_cpu(s.sectors),
                   nr_data,
-                  s.nr_redundant,
-                  s.csum_type,
-                  1U << s.csum_granularity_bits);
+                  s.nr_redundant);
+       bch2_prt_csum_type(out, s.csum_type);
+       prt_printf(out, " gran %u", 1U << s.csum_granularity_bits);
 
        for (unsigned i = 0; i < s.nr_blocks; i++) {
                const struct bch_extent_ptr *ptr = sp->ptrs + i;
@@ -611,10 +611,8 @@ static void ec_validate_checksums(struct bch_fs *c, struct ec_stripe_buf *buf)
                                struct printbuf err = PRINTBUF;
                                struct bch_dev *ca = bch_dev_bkey_exists(c, v->ptrs[i].dev);
 
-                               prt_printf(&err, "stripe checksum error: expected %0llx:%0llx got %0llx:%0llx (type %s)\n",
-                                          want.hi, want.lo,
-                                          got.hi, got.lo,
-                                          bch2_csum_types[v->csum_type]);
+                               prt_str(&err, "stripe ");
+                               bch2_csum_err_msg(&err, v->csum_type, want, got);
                                prt_printf(&err, "  for %ps at %u of\n  ", (void *) _RET_IP_, i);
                                bch2_bkey_val_to_text(&err, c, bkey_i_to_s_c(&buf->key));
                                bch_err_ratelimited(ca, "%s", err.buf);
index 36d12d2adb81e80207f63b7066f59f71a3c89f7c..1a331e539204852d4db9e7620df0282abe262f1e 100644 (file)
@@ -1030,11 +1030,12 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
                        struct bch_extent_crc_unpacked crc =
                                bch2_extent_crc_unpack(k.k, entry_to_crc(entry));
 
-                       prt_printf(out, "crc: c_size %u size %u offset %u nonce %u csum %s compress ",
+                       prt_printf(out, "crc: c_size %u size %u offset %u nonce %u csum ",
                               crc.compressed_size,
                               crc.uncompressed_size,
-                              crc.offset, crc.nonce,
-                              bch2_csum_types[crc.csum_type]);
+                              crc.offset, crc.nonce);
+                       bch2_prt_csum_type(out, crc.csum_type);
+                       prt_str(out, " compress ");
                        bch2_prt_compression_type(out, crc.compression_type);
                        break;
                }
index 725fcf46f6312c267c2a7c05f1eaa6aed5fb83e7..9aa28b52ab926c567f49e0bb68b9c6791fb326e5 100644 (file)
@@ -247,7 +247,7 @@ static void journal_entry_err_msg(struct printbuf *out,
 
        if (entry) {
                prt_str(out, " type=");
-               prt_str(out, bch2_jset_entry_types[entry->type]);
+               bch2_prt_jset_entry_type(out, entry->type);
        }
 
        if (!jset) {
@@ -403,7 +403,8 @@ static void journal_entry_btree_keys_to_text(struct printbuf *out, struct bch_fs
        jset_entry_for_each_key(entry, k) {
                if (!first) {
                        prt_newline(out);
-                       prt_printf(out, "%s: ", bch2_jset_entry_types[entry->type]);
+                       bch2_prt_jset_entry_type(out, entry->type);
+                       prt_str(out, ": ");
                }
                prt_printf(out, "btree=%s l=%u ", bch2_btree_id_str(entry->btree_id), entry->level);
                bch2_bkey_val_to_text(out, c, bkey_i_to_s_c(k));
@@ -563,9 +564,9 @@ static void journal_entry_usage_to_text(struct printbuf *out, struct bch_fs *c,
        struct jset_entry_usage *u =
                container_of(entry, struct jset_entry_usage, entry);
 
-       prt_printf(out, "type=%s v=%llu",
-              bch2_fs_usage_types[u->entry.btree_id],
-              le64_to_cpu(u->v));
+       prt_str(out, "type=");
+       bch2_prt_fs_usage_type(out, u->entry.btree_id);
+       prt_printf(out, " v=%llu", le64_to_cpu(u->v));
 }
 
 static int journal_entry_data_usage_validate(struct bch_fs *c,
@@ -827,11 +828,11 @@ int bch2_journal_entry_validate(struct bch_fs *c,
 void bch2_journal_entry_to_text(struct printbuf *out, struct bch_fs *c,
                                struct jset_entry *entry)
 {
+       bch2_prt_jset_entry_type(out, entry->type);
+
        if (entry->type < BCH_JSET_ENTRY_NR) {
-               prt_printf(out, "%s: ", bch2_jset_entry_types[entry->type]);
+               prt_str(out, ": ");
                bch2_jset_entry_ops[entry->type].to_text(out, c, entry);
-       } else {
-               prt_printf(out, "(unknown type %u)", entry->type);
        }
 }
 
index e1800c4119b5fbaf8ebbfcdaef996e1dd9c35ca8..bb068fd724656cf8307d14022ca537f918b65747 100644 (file)
@@ -43,7 +43,7 @@ const char * const __bch2_btree_ids[] = {
        NULL
 };
 
-const char * const bch2_csum_types[] = {
+static const char * const __bch2_csum_types[] = {
        BCH_CSUM_TYPES()
        NULL
 };
@@ -53,7 +53,7 @@ const char * const bch2_csum_opts[] = {
        NULL
 };
 
-const char * const __bch2_compression_types[] = {
+static const char * const __bch2_compression_types[] = {
        BCH_COMPRESSION_TYPES()
        NULL
 };
@@ -83,18 +83,39 @@ const char * const bch2_member_states[] = {
        NULL
 };
 
-const char * const bch2_jset_entry_types[] = {
+static const char * const __bch2_jset_entry_types[] = {
        BCH_JSET_ENTRY_TYPES()
        NULL
 };
 
-const char * const bch2_fs_usage_types[] = {
+static const char * const __bch2_fs_usage_types[] = {
        BCH_FS_USAGE_TYPES()
        NULL
 };
 
 #undef x
 
+static void prt_str_opt_boundscheck(struct printbuf *out, const char * const opts[],
+                                   unsigned nr, const char *type, unsigned idx)
+{
+       if (idx < nr)
+               prt_str(out, opts[idx]);
+       else
+               prt_printf(out, "(unknown %s %u)", type, idx);
+}
+
+#define PRT_STR_OPT_BOUNDSCHECKED(name, type)                                  \
+void bch2_prt_##name(struct printbuf *out, type t)                             \
+{                                                                              \
+       prt_str_opt_boundscheck(out, __bch2_##name##s, ARRAY_SIZE(__bch2_##name##s) - 1, #name, t);\
+}
+
+PRT_STR_OPT_BOUNDSCHECKED(jset_entry_type,     enum bch_jset_entry_type);
+PRT_STR_OPT_BOUNDSCHECKED(fs_usage_type,       enum bch_fs_usage_type);
+PRT_STR_OPT_BOUNDSCHECKED(data_type,           enum bch_data_type);
+PRT_STR_OPT_BOUNDSCHECKED(csum_type,           enum bch_csum_type);
+PRT_STR_OPT_BOUNDSCHECKED(compression_type,    enum bch_compression_type);
+
 static int bch2_opt_fix_errors_parse(struct bch_fs *c, const char *val, u64 *res,
                                     struct printbuf *err)
 {
index 1ac4135cca1c3dccc71a75a0d062ee30df33111c..84e452835a17d84d36c4d0f3906501578bf702d3 100644 (file)
@@ -16,18 +16,20 @@ extern const char * const bch2_version_upgrade_opts[];
 extern const char * const bch2_sb_features[];
 extern const char * const bch2_sb_compat[];
 extern const char * const __bch2_btree_ids[];
-extern const char * const bch2_csum_types[];
 extern const char * const bch2_csum_opts[];
-extern const char * const __bch2_compression_types[];
 extern const char * const bch2_compression_opts[];
 extern const char * const bch2_str_hash_types[];
 extern const char * const bch2_str_hash_opts[];
 extern const char * const __bch2_data_types[];
 extern const char * const bch2_member_states[];
-extern const char * const bch2_jset_entry_types[];
-extern const char * const bch2_fs_usage_types[];
 extern const char * const bch2_d_types[];
 
+void bch2_prt_jset_entry_type(struct printbuf *,       enum bch_jset_entry_type);
+void bch2_prt_fs_usage_type(struct printbuf *,         enum bch_fs_usage_type);
+void bch2_prt_data_type(struct printbuf *,             enum bch_data_type);
+void bch2_prt_csum_type(struct printbuf *,             enum bch_csum_type);
+void bch2_prt_compression_type(struct printbuf *,      enum bch_compression_type);
+
 static inline const char *bch2_d_type_str(unsigned d_type)
 {
        return (d_type < BCH_DT_MAX ? bch2_d_types[d_type] : NULL) ?: "(bad d_type)";