}
}
while (input.pos < input.size) {
+ size_t prev_in = input.pos;
+ size_t prev_out = output.pos;
+
ret = ZSTD_decompressStream(data->dstream, &output, &input);
if (ZSTD_isError(ret)) {
pr_err("failed to decompress (B): %zd -> %zd, dst_size %zd : %s\n",
- src_size, output.size, dst_size, ZSTD_getErrorName(ret));
- break;
+ src_size, output.pos, dst_size, ZSTD_getErrorName(ret));
+ return 0;
}
- output.dst = dst + output.pos;
- output.size = dst_size - output.pos;
+ /*
+ * Neither stream advanced — decompression is stuck.
+ * Return 0 (error) rather than partial output: perf
+ * uses ZSTD_flushStream (not ZSTD_endStream), so the
+ * stream is continuous across compressed events.
+ * Discarding unconsumed input would desynchronize the
+ * decompressor, causing the next call to produce
+ * garbage that could be misinterpreted as valid events.
+ */
+ if (input.pos == prev_in && output.pos == prev_out)
+ return 0;
}
return output.pos;