From d4b1cd59311689658f3c1df44e1105aaae704fac Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Thu, 1 Feb 2024 10:21:21 -0800 Subject: [PATCH] Use incompatible pre-release format version Change the format version so that this code is incompatible with existing releases, and vice versa. We're distributing test builds and might change the format based on feedback and we don't want it to be possible to corrupt volumes with the changes in these pre-release builds. This is a one-off patch for this feature branch. We may work this into the build more formally if it works out. Signed-off-by: Zach Brown --- kmod/src/format.h | 9 +++++++-- kmod/src/super.c | 6 +++++- tests/funcs/filter.sh | 2 ++ utils/src/change_format_version.c | 6 +++--- utils/src/cmd.c | 2 +- utils/src/mkfs.c | 6 +++++- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/kmod/src/format.h b/kmod/src/format.h index 70c7d6b9..d8664927 100644 --- a/kmod/src/format.h +++ b/kmod/src/format.h @@ -5,11 +5,16 @@ * The format version defines the format of structures on devices, * structures that are communicated over the wire, and the protocol * behind the structures. + * + * Builds can have unique pre-release formats that are incompatible with + * every other build. This lets people experiment with formats without + * accidentally corrupting data with release builds. */ -#define SCOUTFS_FORMAT_VERSION_MIN 1 +#define SCOUTFS_FORMAT_VERSION_MIN 0x8cf3b46619eb9975ULL #define SCOUTFS_FORMAT_VERSION_MIN_STR __stringify(SCOUTFS_FORMAT_VERSION_MIN) -#define SCOUTFS_FORMAT_VERSION_MAX 1 +#define SCOUTFS_FORMAT_VERSION_MAX 0x8cf3b46619eb9975ULL #define SCOUTFS_FORMAT_VERSION_MAX_STR __stringify(SCOUTFS_FORMAT_VERSION_MAX) +#define SCOUTFS_FORMAT_VER_PREREL 0x8000000000000000ULL /* statfs(2) f_type */ #define SCOUTFS_SUPER_MAGIC 0x554f4353 /* "SCOU" */ diff --git a/kmod/src/super.c b/kmod/src/super.c index 0086d7fb..d7b45f13 100644 --- a/kmod/src/super.c +++ b/kmod/src/super.c @@ -330,7 +330,7 @@ static int scoutfs_read_super_from_bdev(struct super_block *sb, if (le64_to_cpu(super->fmt_vers) < SCOUTFS_FORMAT_VERSION_MIN || le64_to_cpu(super->fmt_vers) > SCOUTFS_FORMAT_VERSION_MAX) { - scoutfs_err(sb, "super block has format version %llu outside of supported version range %u-%u", + scoutfs_err(sb, "super block has format version %llu outside of supported version range %llu-%llu", le64_to_cpu(super->fmt_vers), SCOUTFS_FORMAT_VERSION_MIN, SCOUTFS_FORMAT_VERSION_MAX); ret = -EINVAL; @@ -669,6 +669,10 @@ static int __init scoutfs_module_init(void) if (ret) return ret; + if (SCOUTFS_FORMAT_VERSION_MIN & SCOUTFS_FORMAT_VER_PREREL) { + printk(KERN_INFO "scoutfs module using incompatible pre-release format version 0x%016llx. This module can only mount volumes with this version, and volumes with this version will be incompatible with all other release builds.", SCOUTFS_FORMAT_VERSION_MIN); + } + scoutfs_debugfs_root = debugfs_create_dir("scoutfs", NULL); if (!scoutfs_debugfs_root) { ret = -ENOMEM; diff --git a/tests/funcs/filter.sh b/tests/funcs/filter.sh index 64f1f7c9..665aebf6 100644 --- a/tests/funcs/filter.sh +++ b/tests/funcs/filter.sh @@ -147,6 +147,8 @@ t_filter_dmesg() # ignore systemd-journal rotating re="$re|systemd-journald.*" + re="$re|incompatible pre-release format version" + egrep -v "($re)" | \ ignore_harmless_unwind_kasan_stack_oob } diff --git a/utils/src/change_format_version.c b/utils/src/change_format_version.c index 071e6303..6c60c89b 100644 --- a/utils/src/change_format_version.c +++ b/utils/src/change_format_version.c @@ -96,7 +96,7 @@ static int do_change_fmt_vers(struct change_fmt_vers_args *args) if (le64_to_cpu(meta_super->fmt_vers) < SCOUTFS_FORMAT_VERSION_MIN || le64_to_cpu(meta_super->fmt_vers) > SCOUTFS_FORMAT_VERSION_MAX) { - fprintf(stderr, "meta super block has format version %llu outside of supported version range %u-%u", + fprintf(stderr, "meta super block has format version %llu outside of supported version range %llu-%llu", le64_to_cpu(meta_super->fmt_vers), SCOUTFS_FORMAT_VERSION_MIN, SCOUTFS_FORMAT_VERSION_MAX); ret = -EINVAL; @@ -105,7 +105,7 @@ static int do_change_fmt_vers(struct change_fmt_vers_args *args) if (le64_to_cpu(data_super->fmt_vers) < SCOUTFS_FORMAT_VERSION_MIN || le64_to_cpu(data_super->fmt_vers) > SCOUTFS_FORMAT_VERSION_MAX) { - fprintf(stderr, "data super block has format version %llu outside of supported version range %u-%u", + fprintf(stderr, "data super block has format version %llu outside of supported version range %llu-%llu", le64_to_cpu(data_super->fmt_vers), SCOUTFS_FORMAT_VERSION_MIN, SCOUTFS_FORMAT_VERSION_MAX); ret = -EINVAL; @@ -186,7 +186,7 @@ static int parse_opt(int key, char *arg, struct argp_state *state) return ret; if (args->fmt_vers < SCOUTFS_FORMAT_VERSION_MIN || args->fmt_vers > SCOUTFS_FORMAT_VERSION_MAX) - argp_error(state, "format-version %llu is outside supported range of %u-%u", + argp_error(state, "format-version %llu is outside supported range of %llu-%llu", args->fmt_vers, SCOUTFS_FORMAT_VERSION_MIN, SCOUTFS_FORMAT_VERSION_MAX); break; diff --git a/utils/src/cmd.c b/utils/src/cmd.c index 10e10ca7..7ae0d36b 100644 --- a/utils/src/cmd.c +++ b/utils/src/cmd.c @@ -70,7 +70,7 @@ static void usage(void) fprintf(stderr, "Selected fs defaults to current working directory.\n"); fprintf(stderr, "See --help for more details.\n"); - fprintf(stderr, "\nSupported format version: %u-%u\n", + fprintf(stderr, "\nSupported format version: %llu-%llu\n", SCOUTFS_FORMAT_VERSION_MIN, SCOUTFS_FORMAT_VERSION_MAX); fprintf(stderr, "\nCore admin:\n"); diff --git a/utils/src/mkfs.c b/utils/src/mkfs.c index f27a5674..b9461b08 100644 --- a/utils/src/mkfs.c +++ b/utils/src/mkfs.c @@ -386,6 +386,10 @@ static int do_mkfs(struct mkfs_args *args) print_quorum_slots(super->qconf.slots, array_size(super->qconf.slots), " "); + if (SCOUTFS_FORMAT_VERSION_MIN & SCOUTFS_FORMAT_VER_PREREL) + printf("This volume was created with the incompatible pre-release format version 0x%016llx. This volume will only be mountable by pre-release builds with this specific matching format version.\n", + SCOUTFS_FORMAT_VERSION_MIN); + ret = 0; out: if (super) @@ -456,7 +460,7 @@ static int parse_opt(int key, char *arg, struct argp_state *state) return ret; if (args->fmt_vers < SCOUTFS_FORMAT_VERSION_MIN || args->fmt_vers > SCOUTFS_FORMAT_VERSION_MAX) - argp_error(state, "format-version %llu is outside supported range of %u-%u", + argp_error(state, "format-version %llu is outside supported range of %llu-%llu", args->fmt_vers, SCOUTFS_FORMAT_VERSION_MIN, SCOUTFS_FORMAT_VERSION_MAX); break;