refactor(fileio): move zstd window diagnostic policy to Rust
Project the zstd window-too-large diagnostic inputs into Rust so Rust owns error filtering and the concrete-versus-unsupported guidance choice. C keeps frame-header parsing, window-log extraction, and the exact display text behind a callback, preserving the existing diagnostics and fallback behavior. All heavy verification was run serially with a 40 GiB virtual-memory cap and one build job. Test Plan: - git diff --cached --check - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml --all-targets (790 passed) - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/cli/Cargo.toml --all-targets (184 passed) - ulimit -v 41943040; cargo +nightly fmt --manifest-path rust/Cargo.toml --all -- --check - ulimit -v 41943040; make -j1 (clean after C90 declaration cleanup) - ulimit -v 41943040; make -j1 -C tests test (passed; the later cleanup only moved a declaration before statements)
This commit is contained in:
+103
-20
@@ -3755,6 +3755,83 @@ static int FIO_passThrough(dRess_t *ress)
|
||||
return FIO_rust_passThrough(ress->readCtx, ress->writeCtx);
|
||||
}
|
||||
|
||||
enum {
|
||||
FIO_RUST_ZSTD_ERROR_HELP_WINDOW_SIZE = 0,
|
||||
FIO_RUST_ZSTD_ERROR_HELP_WINDOW_GUIDANCE = 1,
|
||||
FIO_RUST_ZSTD_ERROR_HELP_UNSUPPORTED_WINDOW_LOG = 2
|
||||
};
|
||||
typedef void (*FIO_rust_zstdErrorHelpDisplayFn)(
|
||||
void* callbackContext,
|
||||
int diagnostic,
|
||||
const char* srcFileName,
|
||||
unsigned long long windowSize,
|
||||
unsigned windowLog,
|
||||
unsigned windowMB,
|
||||
unsigned memLimit);
|
||||
typedef struct {
|
||||
void* callbackContext;
|
||||
const char* srcFileName;
|
||||
unsigned long long windowSize;
|
||||
size_t headerError;
|
||||
unsigned windowLog;
|
||||
unsigned memLimit;
|
||||
int errorCode;
|
||||
FIO_rust_zstdErrorHelpDisplayFn display;
|
||||
} FIO_rust_zstdErrorHelpState;
|
||||
typedef char FIO_rust_zstd_error_help_state_layout[
|
||||
(offsetof(FIO_rust_zstdErrorHelpState, callbackContext) == 0
|
||||
&& offsetof(FIO_rust_zstdErrorHelpState, srcFileName)
|
||||
== sizeof(void*)
|
||||
&& offsetof(FIO_rust_zstdErrorHelpState, windowSize)
|
||||
== 2 * sizeof(void*)
|
||||
&& offsetof(FIO_rust_zstdErrorHelpState, headerError)
|
||||
== offsetof(FIO_rust_zstdErrorHelpState, windowSize)
|
||||
+ sizeof(unsigned long long)
|
||||
&& offsetof(FIO_rust_zstdErrorHelpState, windowLog)
|
||||
== offsetof(FIO_rust_zstdErrorHelpState, headerError)
|
||||
+ sizeof(size_t)
|
||||
&& offsetof(FIO_rust_zstdErrorHelpState, memLimit)
|
||||
== offsetof(FIO_rust_zstdErrorHelpState, windowLog)
|
||||
+ sizeof(unsigned)
|
||||
&& offsetof(FIO_rust_zstdErrorHelpState, errorCode)
|
||||
== offsetof(FIO_rust_zstdErrorHelpState, memLimit)
|
||||
+ sizeof(unsigned)
|
||||
&& offsetof(FIO_rust_zstdErrorHelpState, display)
|
||||
== ((offsetof(FIO_rust_zstdErrorHelpState, errorCode)
|
||||
+ sizeof(int) + sizeof(void*) - 1)
|
||||
/ sizeof(void*)) * sizeof(void*)
|
||||
&& sizeof(FIO_rust_zstdErrorHelpState)
|
||||
== offsetof(FIO_rust_zstdErrorHelpState, display)
|
||||
+ sizeof(void*)
|
||||
&& sizeof(FIO_rust_zstdErrorHelpDisplayFn) == sizeof(void*))
|
||||
? 1 : -1];
|
||||
void FIO_rust_zstdErrorHelp(const FIO_rust_zstdErrorHelpState* state);
|
||||
|
||||
static void FIO_rust_zstdErrorHelp_display(
|
||||
void* callbackContext,
|
||||
int diagnostic,
|
||||
const char* srcFileName,
|
||||
unsigned long long windowSize,
|
||||
unsigned windowLog,
|
||||
unsigned windowMB,
|
||||
unsigned memLimit)
|
||||
{
|
||||
(void)callbackContext;
|
||||
if (diagnostic == FIO_RUST_ZSTD_ERROR_HELP_WINDOW_SIZE) {
|
||||
DISPLAYLEVEL(1, "%s : Window size larger than maximum : %llu > %u \n",
|
||||
srcFileName, windowSize, memLimit);
|
||||
return;
|
||||
}
|
||||
if (diagnostic == FIO_RUST_ZSTD_ERROR_HELP_WINDOW_GUIDANCE) {
|
||||
DISPLAYLEVEL(1, "%s : Use --long=%u or --memory=%uMB \n",
|
||||
srcFileName, windowLog, windowMB);
|
||||
return;
|
||||
}
|
||||
assert(diagnostic == FIO_RUST_ZSTD_ERROR_HELP_UNSUPPORTED_WINDOW_LOG);
|
||||
DISPLAYLEVEL(1, "%s : Window log larger than ZSTD_WINDOWLOG_MAX=%u; not supported \n",
|
||||
srcFileName, ZSTD_WINDOWLOG_MAX);
|
||||
}
|
||||
|
||||
/* FIO_zstdErrorHelp() :
|
||||
* detailed error message when requested window size is too large */
|
||||
static void
|
||||
@@ -3764,28 +3841,34 @@ FIO_zstdErrorHelp(const FIO_prefs_t* const prefs,
|
||||
const char* srcFileName)
|
||||
{
|
||||
ZSTD_FrameHeader header;
|
||||
int const errorCode = (int)ZSTD_getErrorCode(err);
|
||||
size_t headerError = 1;
|
||||
unsigned long long windowSize = 0;
|
||||
unsigned windowLog = 0;
|
||||
unsigned memLimit = 0;
|
||||
FIO_rust_zstdErrorHelpState state = { 0 };
|
||||
|
||||
/* Help message only for one specific error */
|
||||
if (ZSTD_getErrorCode(err) != ZSTD_error_frameParameter_windowTooLarge)
|
||||
return;
|
||||
if (errorCode == ZSTD_error_frameParameter_windowTooLarge) {
|
||||
/* Keep codec/header parsing and the private read-pool layout in C. */
|
||||
headerError = ZSTD_getFrameHeader(
|
||||
&header, ress->readCtx->srcBuffer, ress->readCtx->srcBufferLoaded);
|
||||
if (headerError == 0) {
|
||||
windowSize = header.windowSize;
|
||||
windowLog = FIO_highbit64(windowSize)
|
||||
+ ((windowSize & (windowSize - 1)) != 0);
|
||||
memLimit = prefs->memLimit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to decode the frame header */
|
||||
err = ZSTD_getFrameHeader(&header, ress->readCtx->srcBuffer, ress->readCtx->srcBufferLoaded);
|
||||
if (err == 0) {
|
||||
unsigned long long const windowSize = header.windowSize;
|
||||
unsigned const windowLog = FIO_highbit64(windowSize) + ((windowSize & (windowSize - 1)) != 0);
|
||||
assert(prefs->memLimit > 0);
|
||||
DISPLAYLEVEL(1, "%s : Window size larger than maximum : %llu > %u \n",
|
||||
srcFileName, windowSize, prefs->memLimit);
|
||||
if (windowLog <= ZSTD_WINDOWLOG_MAX) {
|
||||
unsigned const windowMB = (unsigned)((windowSize >> 20) + ((windowSize & ((1 MB) - 1)) != 0));
|
||||
assert(windowSize < (U64)(1ULL << 52)); /* ensure now overflow for windowMB */
|
||||
DISPLAYLEVEL(1, "%s : Use --long=%u or --memory=%uMB \n",
|
||||
srcFileName, windowLog, windowMB);
|
||||
return;
|
||||
} }
|
||||
DISPLAYLEVEL(1, "%s : Window log larger than ZSTD_WINDOWLOG_MAX=%u; not supported \n",
|
||||
srcFileName, ZSTD_WINDOWLOG_MAX);
|
||||
state.callbackContext = NULL;
|
||||
state.srcFileName = srcFileName;
|
||||
state.windowSize = windowSize;
|
||||
state.headerError = headerError;
|
||||
state.windowLog = windowLog;
|
||||
state.memLimit = memLimit;
|
||||
state.errorCode = errorCode;
|
||||
state.display = FIO_rust_zstdErrorHelp_display;
|
||||
FIO_rust_zstdErrorHelp(&state);
|
||||
}
|
||||
|
||||
/** FIO_decompressFrame() :
|
||||
|
||||
Reference in New Issue
Block a user