From 9e97d5cf9abefbe14edd734be07eb3a51ac0bca9 Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Mon, 18 Aug 2025 14:50:33 +0200 Subject: [PATCH] feat(mkdwarfs): add `--no-metadata-version-history` --- doc/mkdwarfs.md | 8 +++++ include/dwarfs/writer/metadata_options.h | 1 + src/writer/internal/metadata_builder.cpp | 8 +++-- test/tool_main_test.cpp | 37 ++++++++++++++++++++++-- tools/src/mkdwarfs_main.cpp | 3 ++ 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/doc/mkdwarfs.md b/doc/mkdwarfs.md index facd6230..9daba13f 100644 --- a/doc/mkdwarfs.md +++ b/doc/mkdwarfs.md @@ -252,6 +252,14 @@ Most other options are concerned with compression tuning: is unchanged, this will still re-order and re-compress *all* blocks. Implies `--recompress=all` and `--rebuild-metadata`. +- `--no-metadata-version-history`: + By default, when rebuilding the metadata block, a small history entry will + be added to the metadata block to keep track of versions and options across + metadata rebuilds. It is recommended to keep this history, as it allows for + better understanding of how the metadata block has changed over time and + why it may be lacking certain features. If you know what you're doing, you + can use this option to disable this history completely. + - `--recompress-categories=`[`!`]*category*[`,`...]: When `--recompress` is set to `all` or `block`, this option controls which categories of blocks will be recompressed. Adding a `!` in front diff --git a/include/dwarfs/writer/metadata_options.h b/include/dwarfs/writer/metadata_options.h index 29c657b2..37a78cf8 100644 --- a/include/dwarfs/writer/metadata_options.h +++ b/include/dwarfs/writer/metadata_options.h @@ -56,6 +56,7 @@ struct metadata_options { bool no_create_timestamp{false}; bool no_category_names{false}; bool no_category_metadata{false}; + bool no_metadata_version_history{false}; size_t inode_size_cache_min_chunk_count{128}; }; diff --git a/src/writer/internal/metadata_builder.cpp b/src/writer/internal/metadata_builder.cpp index e4dc3bc4..7b060cac 100644 --- a/src/writer/internal/metadata_builder.cpp +++ b/src/writer/internal/metadata_builder.cpp @@ -772,8 +772,12 @@ void metadata_builder_::upgrade_metadata( tv << "upgrading metadata..."; - md_.metadata_version_history().ensure(); - md_.metadata_version_history()->push_back(std::move(histent)); + if (options_.no_metadata_version_history) { + md_.metadata_version_history().reset(); + } else { + md_.metadata_version_history().ensure(); + md_.metadata_version_history()->push_back(std::move(histent)); + } } } // namespace diff --git a/test/tool_main_test.cpp b/test/tool_main_test.cpp index 398eedd0..031dc977 100644 --- a/test/tool_main_test.cpp +++ b/test/tool_main_test.cpp @@ -4104,9 +4104,15 @@ TEST(mkdwarfs_test, change_block_size) { auto fs = t.fs_from_stdout(); auto info = - fs.info_as_json({.features = reader::fsinfo_features::for_level(2)}); + fs.info_as_json({.features = reader::fsinfo_features::for_level(3)}); EXPECT_EQ(1 << lg_block_size, info["block_size"].get()); + + auto const& hist = info["meta"]["metadata_version_history"]; + + ASSERT_EQ(1, hist.size()); + + EXPECT_EQ(1 << 18, hist[0]["block_size"].get()); } auto t2 = rebuild_tester(t.out()); @@ -4121,9 +4127,36 @@ TEST(mkdwarfs_test, change_block_size) { auto fs = t2.fs_from_stdout(); auto info = - fs.info_as_json({.features = reader::fsinfo_features::for_level(2)}); + fs.info_as_json({.features = reader::fsinfo_features::for_level(3)}); EXPECT_EQ(1 << 18, info["block_size"].get()); + + auto const& hist = info["meta"]["metadata_version_history"]; + + ASSERT_EQ(2, hist.size()); + + EXPECT_EQ(1 << 18, hist[0]["block_size"].get()); + EXPECT_EQ(1 << lg_block_size, hist[1]["block_size"].get()); + } + + if (lg_block_size == 10) { + auto t3 = rebuild_tester(t2.out()); + ASSERT_EQ( + 0, t3.run({"-i", image_file, "-o", "-", "-S20", "-C", "zstd:level=5", + "--change-block-size", "--keep-all-times", + "--log-level=debug", "--no-metadata-version-history"})) + << t3.err(); + + { + auto fs = t3.fs_from_stdout(); + auto info = fs.info_as_json( + {.features = reader::fsinfo_features::for_level(3)}); + + EXPECT_EQ(1 << 20, info["block_size"].get()); + + EXPECT_FALSE(info["meta"].contains("metadata_version_history")) + << info.dump(2); + } } } } diff --git a/tools/src/mkdwarfs_main.cpp b/tools/src/mkdwarfs_main.cpp index ff41d418..c671cd0a 100644 --- a/tools/src/mkdwarfs_main.cpp +++ b/tools/src/mkdwarfs_main.cpp @@ -534,6 +534,9 @@ int mkdwarfs_main(int argc, sys_char** argv, iolayer const& iol) { ("change-block-size", po::value(&change_block_size)->zero_tokens(), "change block size when recompressing") + ("no-metadata-version-history", + po::value(&options.metadata.no_metadata_version_history)->zero_tokens(), + "remove metadata version history") ("recompress-categories", po::value(&recompress_categories), "only recompress blocks of these categories")