From e6d848bcb4268f62687c81e2b5e20317a3c1f7dc Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Tue, 26 Aug 2025 23:26:01 +0200 Subject: [PATCH] feat: pass category metadata to compressors when re-writing filesystem --- .../internal/filesystem_writer_detail.h | 4 ++- src/utility/rewrite_filesystem.cpp | 15 ++++++++-- src/writer/filesystem_writer.cpp | 30 ++++++++++++------- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/include/dwarfs/writer/internal/filesystem_writer_detail.h b/include/dwarfs/writer/internal/filesystem_writer_detail.h index 41227553..a51da4ca 100644 --- a/include/dwarfs/writer/internal/filesystem_writer_detail.h +++ b/include/dwarfs/writer/internal/filesystem_writer_detail.h @@ -93,11 +93,13 @@ class filesystem_writer_detail { virtual void check_block_compression( compression_type compression, std::span data, std::optional cat = std::nullopt, + std::optional cat_metadata = std::nullopt, block_compression_info* info = nullptr) = 0; virtual void rewrite_section( section_type type, compression_type compression, std::span data, - std::optional cat = std::nullopt) = 0; + std::optional cat = std::nullopt, + std::optional cat_metadata = std::nullopt) = 0; virtual void rewrite_block( delayed_data_fn_type data, size_t uncompressed_size, std::optional cat = std::nullopt) = 0; diff --git a/src/utility/rewrite_filesystem.cpp b/src/utility/rewrite_filesystem.cpp index 6c55c547..c19d5b42 100644 --- a/src/utility/rewrite_filesystem.cpp +++ b/src/utility/rewrite_filesystem.cpp @@ -288,13 +288,18 @@ void rewrite_filesystem(logger& lgr, dwarfs::reader::filesystem_v2 const& fs, dwarfs::writer::internal::block_compression_info bci; auto catstr = fs.get_block_category(block_no); std::optional cat; + std::optional cat_metadata; if (catstr) { cat = cat_resolver.category_value(catstr.value()); } + if (auto cm = fs.get_block_category_metadata(block_no)) { + cat_metadata = cm->dump(); + } + writer.check_block_compression( - s->compression(), parser->section_data(*s), cat, + s->compression(), parser->section_data(*s), cat, cat_metadata, opts.change_block_size ? &bci : nullptr); if (opts.change_block_size) { @@ -453,8 +458,14 @@ void rewrite_filesystem(logger& lgr, dwarfs::reader::filesystem_v2 const& fs, if (recompress_block) { log_recompress(s, cat); + std::optional cat_metadata; + + if (auto cm = fs.get_block_category_metadata(block_no)) { + cat_metadata = cm->dump(); + } + writer.rewrite_section(section_type::BLOCK, s->compression(), - parser->section_data(*s), cat); + parser->section_data(*s), cat, cat_metadata); } else { copy_compressed(s, cat); } diff --git a/src/writer/filesystem_writer.cpp b/src/writer/filesystem_writer.cpp index fa37b7f1..b96afd71 100644 --- a/src/writer/filesystem_writer.cpp +++ b/src/writer/filesystem_writer.cpp @@ -594,11 +594,12 @@ class filesystem_writer_ final : public filesystem_writer_detail { void check_block_compression(compression_type compression, std::span data, std::optional cat, + std::optional cat_metadata, block_compression_info* info) override; - void - rewrite_section(section_type type, compression_type compression, - std::span data, - std::optional cat) override; + void rewrite_section(section_type type, compression_type compression, + std::span data, + std::optional cat, + std::optional cat_metadata) override; void rewrite_block(delayed_data_fn_type data, size_t uncompressed_size, std::optional cat) override; void write_compressed_section(fs_section const& sec, @@ -892,7 +893,7 @@ template void filesystem_writer_::check_block_compression( compression_type compression, std::span data, std::optional cat, - block_compression_info* info) { + std::optional cat_metadata, block_compression_info* info) { block_compressor const* bc{nullptr}; if (cat) { @@ -903,11 +904,15 @@ void filesystem_writer_::check_block_compression( block_decompressor bd(compression, data); + if (!cat_metadata) { + cat_metadata = bd.metadata(); + } + if (auto reqstr = bc->metadata_requirements(); !reqstr.empty()) { auto req = compression_metadata_requirements{reqstr}; try { - req.check(bd.metadata()); + req.check(cat_metadata); } catch (std::exception const& e) { auto msg = fmt::format( "cannot compress {} compressed block with compressor '{}' because " @@ -919,7 +924,7 @@ void filesystem_writer_::check_block_compression( if (info) { info->uncompressed_size = bd.uncompressed_size(); - info->metadata = bd.metadata(); + info->metadata = cat_metadata; if (info->metadata) { info->constraints = bc->get_compression_constraints(*info->metadata); } @@ -961,16 +966,21 @@ template void filesystem_writer_::rewrite_section( section_type type, compression_type compression, std::span data, - std::optional cat) { + std::optional cat, + std::optional cat_metadata) { auto bd = block_decompressor(compression, data); auto uncompressed_size = bd.uncompressed_size(); + if (!cat_metadata) { + cat_metadata = bd.metadata(); + } + rewrite_section_delayed_data( type, - [bd = std::move(bd)]() mutable { + [bd = std::move(bd), meta = std::move(cat_metadata)]() mutable { auto block = bd.start_decompression(malloc_byte_buffer::create()); bd.decompress_frame(bd.uncompressed_size()); - return std::pair{std::move(block), bd.metadata()}; + return std::pair{std::move(block), meta}; }, uncompressed_size, cat); }