From fbbb0c5801457ce5d12cc69164b2b5260560cafe Mon Sep 17 00:00:00 2001 From: ddidderr Date: Mon, 20 Jul 2026 15:15:02 +0200 Subject: [PATCH] fix(fileio): keep zstd display callback optional The Rust zstd stream callback initially called a display helper defined only in programs/fileio.c. The CLI linked successfully, but the upstream C tests also link the shared Rust archive without the CLI translation unit, leaving that symbol unresolved even though those tests do not use the fileio projection. Keep the diagnostic implementation in C, but pass it as an optional final field of the zstd compression projection. Rust invokes it from the stream loop after a successful codec call, using the same directive, input position, input size, and produced-output count as the former C callback. Test projections can leave the hook empty, so the reusable Rust archive has no dependency on CLI-only symbols while the production CLI preserves its level-6 diagnostic. Test Plan: - `cargo +nightly fmt --manifest-path rust/Cargo.toml --all` -- passed - `cc -fsyntax-only -Werror=incompatible-pointer-types -Ilib -Ilib/common -Ilib/compress -Ilib/decompress -Ilib/dict -Ilib/legacy programs/fileio.c` -- passed - `git diff --check` and `git diff --cached --check` -- passed - `make -j1 -C tests test` reached the suite but failed before this fix on the now-removed unresolved `FIO_rust_zstd_compressStreamDisplay` reference --- programs/fileio.c | 4 ++++ rust/src/fileio_asyncio.rs | 25 +++++++++---------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index c569bcc0b..5becad0b2 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1331,6 +1331,8 @@ typedef int (*FIO_rust_zstd_compress_stream_fn)( unsigned char* output, size_t outputSize, size_t* inputPosAfter, size_t* outputProduced, size_t* toFlushNow, size_t* zstdResult); +typedef void (*FIO_rust_zstd_compress_display_fn)( + int directive, size_t inputPos, size_t inputSize, size_t outputProduced); int FIO_rust_zstd_compressStream( void* opaque, const char* srcFileName, int directive, const unsigned char* input, size_t inputSize, size_t inputPos, @@ -1357,6 +1359,7 @@ typedef struct { FIO_rust_zstd_sparse_write_end_fn sparseWriteEnd; FIO_rust_zstd_compress_stream_fn compressStream; FIO_rust_zstd_iteration_fn iteration; + FIO_rust_zstd_compress_display_fn compressStreamDisplay; } FIO_rust_zstd_compress_projection_t; int FIO_rust_compressZstdFrame( @@ -2759,6 +2762,7 @@ FIO_rust_compressZstdCallback(void* fCtx, void* prefs, void* ress, projection.sparseWriteEnd = FIO_rust_zstd_sparseWriteEnd; projection.compressStream = FIO_rust_zstd_compressStream; projection.iteration = FIO_rust_zstd_iteration; + projection.compressStreamDisplay = FIO_rust_zstd_compressStreamDisplay; DISPLAYLEVEL(6, "compression using zstd format \n"); diff --git a/rust/src/fileio_asyncio.rs b/rust/src/fileio_asyncio.rs index cd4f4d67b..d4affddf7 100644 --- a/rust/src/fileio_asyncio.rs +++ b/rust/src/fileio_asyncio.rs @@ -31,12 +31,6 @@ use crate::zstd_compress::{ZSTD_inBuffer, ZSTD_outBuffer}; #[cfg(not(test))] unsafe extern "C" { fn ZSTD_toFlushNow(cctx: *mut c_void) -> usize; - fn FIO_rust_zstd_compressStreamDisplay( - directive: c_int, - input_pos: usize, - input_size: usize, - output_produced: usize, - ); } const MAX_IO_JOBS: usize = 10; @@ -855,6 +849,7 @@ pub type FIO_rust_zstd_compress_stream_fn = unsafe extern "C" fn( *mut usize, *mut usize, ) -> c_int; +pub type FIO_rust_zstd_compress_display_fn = unsafe extern "C" fn(c_int, usize, usize, usize); pub type FIO_rust_zstd_iteration_fn = unsafe extern "C" fn(*mut c_void, *const c_char, *mut c_int, usize, usize, usize); @@ -970,6 +965,7 @@ pub struct FIO_rust_zstd_compress_projection_t { pub sparse_write_end: Option, pub compress_stream: Option, pub iteration: Option, + pub compress_display: Option, } pub const FIO_RUST_GZIP_OK: c_int = 0; @@ -3334,7 +3330,6 @@ pub unsafe extern "C" fn FIO_rust_zstd_adapt( type FIO_rust_zstd_to_flush_now_fn = unsafe extern "C" fn(*mut c_void) -> usize; type FIO_rust_zstd_compress_stream2_fn = unsafe extern "C" fn(*mut c_void, *mut ZSTD_outBuffer, *mut ZSTD_inBuffer, c_int) -> usize; -type FIO_rust_zstd_compress_display_fn = unsafe extern "C" fn(c_int, usize, usize, usize); /// Build the public stream-buffer views, call the Rust compressor, and publish /// the same scalar results as the former C-only callback. The codec context @@ -3353,7 +3348,6 @@ unsafe fn fio_zstd_compress_stream_with( zstd_result: *mut usize, to_flush_now_fn: FIO_rust_zstd_to_flush_now_fn, compress_stream2_fn: FIO_rust_zstd_compress_stream2_fn, - display_fn: Option, ) -> c_int { let mut input_view = ZSTD_inBuffer { src: input.cast::(), @@ -3377,11 +3371,6 @@ unsafe fn fio_zstd_compress_stream_with( } if !crate::errors::ERR_isError(result) { - if let Some(display) = display_fn { - unsafe { - display(directive, input_view.pos, input_view.size, output_view.pos); - } - } 0 } else { 1 @@ -3423,7 +3412,6 @@ pub unsafe extern "C" fn FIO_rust_zstd_compressStream( zstd_result, ZSTD_toFlushNow, crate::zstd_compress::ZSTD_compressStream2, - Some(FIO_rust_zstd_compressStreamDisplay), ) } } @@ -3567,6 +3555,12 @@ pub unsafe extern "C" fn FIO_rust_compressZstdFrame( assert!(new_input_pos <= input_size); assert!(output_produced <= output_size); + if let Some(display) = projection.compress_display { + unsafe { + display(directive, new_input_pos, input_size, output_produced); + } + } + unsafe { read_consume(projection.read_opaque, new_input_pos - old_input_pos) }; input_pos = new_input_pos; @@ -6968,7 +6962,6 @@ mod tests { &mut zstd_result, zstd_test_to_flush_now, zstd_test_compress_stream2, - None, ) }, 0 @@ -7004,7 +6997,6 @@ mod tests { &mut zstd_result, zstd_test_to_flush_now, zstd_test_compress_stream2, - None, ) }, 1 @@ -7196,6 +7188,7 @@ mod tests { sparse_write_end: Some(zstd_test_sparse_end), compress_stream: Some(zstd_test_compress), iteration: Some(zstd_test_iteration), + compress_display: None, } }