bcachefs: bch2_version_compatible()
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 29 Jun 2023 00:27:07 +0000 (20:27 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:10:05 +0000 (17:10 -0400)
This adds a new helper for checking if an on-disk version is compatible
with the running version of bcachefs - prep work for introducing
major:minor version numbers.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs_format.h
fs/bcachefs/btree_io.c
fs/bcachefs/journal_io.c
fs/bcachefs/super-io.c
fs/bcachefs/super-io.h

index 158cefb87684f030aefcd01910786cc7800a04ed..4401d27675edfedee82c3cda34d651ad35d70172 100644 (file)
@@ -1574,8 +1574,6 @@ struct bch_sb_field_journal_seq_blacklist {
  * One common version number for all on disk data structures - superblock, btree
  * nodes, journal entries
  */
-#define BCH_JSET_VERSION_OLD                   2
-#define BCH_BSET_VERSION_OLD                   3
 
 #define BCH_METADATA_VERSIONS()                                \
        x(bkey_renumber,                10)             \
index 990c2fa2811483d2e83d29a09b0f502b1f0f039f..9985ecd7265ddf173b34a9abafa1c8b30ea7e6d8 100644 (file)
@@ -699,11 +699,9 @@ static int validate_bset(struct bch_fs *c, struct bch_dev *ca,
        struct printbuf buf2 = PRINTBUF;
        int ret = 0;
 
-       btree_err_on((version != BCH_BSET_VERSION_OLD &&
-                     version < bcachefs_metadata_version_min) ||
-                    version >= bcachefs_metadata_version_max,
+       btree_err_on(!bch2_version_compatible(version),
                     BTREE_ERR_INCOMPATIBLE, c, ca, b, i,
-                    "unsupported bset version");
+                    "unsupported bset version %u", version);
 
        if (btree_err_on(version < c->sb.version_min,
                         BTREE_ERR_FIXABLE, c, NULL, b, i,
@@ -2019,9 +2017,7 @@ do_write:
        BUG_ON(BSET_BIG_ENDIAN(i) != CPU_BIG_ENDIAN);
        BUG_ON(i->seq != b->data->keys.seq);
 
-       i->version = c->sb.version < bcachefs_metadata_version_bkey_renumber
-               ? cpu_to_le16(BCH_BSET_VERSION_OLD)
-               : cpu_to_le16(c->sb.version);
+       i->version = cpu_to_le16(c->sb.version);
        SET_BSET_OFFSET(i, b->written);
        SET_BSET_CSUM_TYPE(i, bch2_meta_checksum_type(c));
 
index 7d0dd1b1d5cfc801fd987e1492480650dd294bde..a084c6d0fe23f8520bc38df0de7ded9d7f6972ee 100644 (file)
@@ -745,14 +745,10 @@ static int jset_validate(struct bch_fs *c,
                return JOURNAL_ENTRY_NONE;
 
        version = le32_to_cpu(jset->version);
-       if (journal_entry_err_on((version != BCH_JSET_VERSION_OLD &&
-                                 version < bcachefs_metadata_version_min) ||
-                                version >= bcachefs_metadata_version_max,
-                                c, jset, NULL,
-                       "%s sector %llu seq %llu: unknown journal entry version %u",
+       if (journal_entry_err_on(!bch2_version_compatible(version), c, jset, NULL,
+                       "%s sector %llu seq %llu: incompatible journal entry version %u",
                        ca ? ca->name : c->name,
-                       sector, le64_to_cpu(jset->seq),
-                       version)) {
+                       sector, le64_to_cpu(jset->seq), version)) {
                /* don't try to continue: */
                return -EINVAL;
        }
@@ -796,14 +792,10 @@ static int jset_validate_early(struct bch_fs *c,
                return JOURNAL_ENTRY_NONE;
 
        version = le32_to_cpu(jset->version);
-       if (journal_entry_err_on((version != BCH_JSET_VERSION_OLD &&
-                                 version < bcachefs_metadata_version_min) ||
-                                version >= bcachefs_metadata_version_max,
-                                c, jset, NULL,
+       if (journal_entry_err_on(!bch2_version_compatible(version), c, jset, NULL,
                        "%s sector %llu seq %llu: unknown journal entry version %u",
                        ca ? ca->name : c->name,
-                       sector, le64_to_cpu(jset->seq),
-                       version)) {
+                       sector, le64_to_cpu(jset->seq), version)) {
                /* don't try to continue: */
                return -EINVAL;
        }
@@ -1755,9 +1747,7 @@ void bch2_journal_write(struct closure *cl)
        }
 
        jset->magic             = cpu_to_le64(jset_magic(c));
-       jset->version           = c->sb.version < bcachefs_metadata_version_bkey_renumber
-               ? cpu_to_le32(BCH_JSET_VERSION_OLD)
-               : cpu_to_le32(c->sb.version);
+       jset->version           = cpu_to_le32(c->sb.version);
 
        SET_JSET_BIG_ENDIAN(jset, CPU_BIG_ENDIAN);
        SET_JSET_CSUM_TYPE(jset, bch2_meta_checksum_type(c));
index 2237b1b94bbcdf010c312db5d025762dd195812d..55a6c64de09c93ea508bef875a61df9356c30e12 100644 (file)
@@ -269,40 +269,58 @@ static int validate_sb_layout(struct bch_sb_layout *layout, struct printbuf *out
        return 0;
 }
 
-static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
-                           int rw)
+static int bch2_sb_compatible(struct bch_sb *sb, struct printbuf *out)
 {
-       struct bch_sb *sb = disk_sb->sb;
-       struct bch_sb_field *f;
-       struct bch_sb_field_members *mi;
-       enum bch_opt_id opt_id;
-       u32 version, version_min;
-       u16 block_size;
-       int ret;
-
-       version         = le16_to_cpu(sb->version);
-       version_min     = version >= bcachefs_metadata_version_bkey_renumber
-               ? le16_to_cpu(sb->version_min)
-               : version;
-
-       if (version    >= bcachefs_metadata_version_max) {
-               prt_printf(out, "Unsupported superblock version %u (min %u, max %u)",
-                      version, bcachefs_metadata_version_min, bcachefs_metadata_version_max);
+       u16 version             = le16_to_cpu(sb->version);
+       u16 version_min         = le16_to_cpu(sb->version_min);
+
+       if (!bch2_version_compatible(version)) {
+               prt_str(out, "Unsupported superblock version ");
+               bch2_version_to_text(out, version);
+               prt_str(out, " (min ");
+               bch2_version_to_text(out, bcachefs_metadata_version_min);
+               prt_str(out, ", max ");
+               bch2_version_to_text(out, bcachefs_metadata_version_current);
+               prt_str(out, ")");
                return -BCH_ERR_invalid_sb_version;
        }
 
-       if (version_min < bcachefs_metadata_version_min) {
-               prt_printf(out, "Unsupported superblock version %u (min %u, max %u)",
-                      version_min, bcachefs_metadata_version_min, bcachefs_metadata_version_max);
+       if (!bch2_version_compatible(version_min)) {
+               prt_str(out, "Unsupported superblock version_min ");
+               bch2_version_to_text(out, version_min);
+               prt_str(out, " (min ");
+               bch2_version_to_text(out, bcachefs_metadata_version_min);
+               prt_str(out, ", max ");
+               bch2_version_to_text(out, bcachefs_metadata_version_current);
+               prt_str(out, ")");
                return -BCH_ERR_invalid_sb_version;
        }
 
        if (version_min > version) {
-               prt_printf(out, "Bad minimum version %u, greater than version field %u",
-                      version_min, version);
+               prt_str(out, "Bad minimum version ");
+               bch2_version_to_text(out, version_min);
+               prt_str(out, ", greater than version field ");
+               bch2_version_to_text(out, version);
                return -BCH_ERR_invalid_sb_version;
        }
 
+       return 0;
+}
+
+static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
+                           int rw)
+{
+       struct bch_sb *sb = disk_sb->sb;
+       struct bch_sb_field *f;
+       struct bch_sb_field_members *mi;
+       enum bch_opt_id opt_id;
+       u16 block_size;
+       int ret;
+
+       ret = bch2_sb_compatible(sb, out);
+       if (ret)
+               return ret;
+
        if (sb->features[1] ||
            (le64_to_cpu(sb->features[0]) & (~0ULL << BCH_FEATURE_NR))) {
                prt_printf(out, "Filesystem has incompatible features");
@@ -350,7 +368,7 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
        if (rw == READ) {
                /*
                 * Been seeing a bug where these are getting inexplicably
-                * zeroed, so we'r now validating them, but we have to be
+                * zeroed, so we're now validating them, but we have to be
                 * careful not to preven people's filesystems from mounting:
                 */
                if (!BCH_SB_JOURNAL_FLUSH_DELAY(sb))
@@ -531,7 +549,6 @@ int bch2_sb_from_fs(struct bch_fs *c, struct bch_dev *ca)
 static int read_one_super(struct bch_sb_handle *sb, u64 offset, struct printbuf *err)
 {
        struct bch_csum csum;
-       u32 version, version_min;
        size_t bytes;
        int ret;
 reread:
@@ -551,22 +568,9 @@ reread:
                return -BCH_ERR_invalid_sb_magic;
        }
 
-       version         = le16_to_cpu(sb->sb->version);
-       version_min     = version >= bcachefs_metadata_version_bkey_renumber
-               ? le16_to_cpu(sb->sb->version_min)
-               : version;
-
-       if (version    >= bcachefs_metadata_version_max) {
-               prt_printf(err, "Unsupported superblock version %u (min %u, max %u)",
-                      version, bcachefs_metadata_version_min, bcachefs_metadata_version_max);
-               return -BCH_ERR_invalid_sb_version;
-       }
-
-       if (version_min < bcachefs_metadata_version_min) {
-               prt_printf(err, "Unsupported superblock version %u (min %u, max %u)",
-                      version_min, bcachefs_metadata_version_min, bcachefs_metadata_version_max);
-               return -BCH_ERR_invalid_sb_version;
-       }
+       ret = bch2_sb_compatible(sb->sb, err);
+       if (ret)
+               return ret;
 
        bytes = vstruct_bytes(sb->sb);
 
index 4a193add3447e16e032897199b8dac1265aced90..cda71ec845a526132a08d0d03894b1c3e31ccb94 100644 (file)
@@ -9,6 +9,12 @@
 
 #include <asm/byteorder.h>
 
+static inline bool bch2_version_compatible(u16 version)
+{
+       return version <= bcachefs_metadata_version_current &&
+               version >= bcachefs_metadata_version_min;
+}
+
 void bch2_version_to_text(struct printbuf *, unsigned);
 
 struct bch_sb_field *bch2_sb_field_get(struct bch_sb *, enum bch_sb_field_type);