zstream decompress: fix decompress size and output

This was incorrectly using the compressed length for the size of the
decompress buffer, and quietly doing nothing if the decompressor refused
to decompress the block because there wasn't enough space.

After that, it wasn't correctly rewriting the record to indicate
"not compressed".

So that's fixed now. Sigh.

Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
This commit is contained in:
Rob Norris 2024-07-23 11:43:18 +10:00 committed by Tony Hutter
parent a9c94bea9f
commit a537d90734

View File

@ -275,7 +275,8 @@ zstream_do_decompress(int argc, char *argv[])
if (c == ZIO_COMPRESS_OFF) { if (c == ZIO_COMPRESS_OFF) {
(void) sfread(buf, payload_size, stdin); (void) sfread(buf, payload_size, stdin);
drrw->drr_compressiontype = ZIO_COMPRESS_OFF; drrw->drr_compressiontype = 0;
drrw->drr_compressed_size = 0;
if (verbose) if (verbose)
fprintf(stderr, fprintf(stderr,
"Resetting compression type to " "Resetting compression type to "
@ -285,18 +286,32 @@ zstream_do_decompress(int argc, char *argv[])
break; break;
} }
uint64_t lsize = drrw->drr_logical_size;
ASSERT3U(payload_size, <=, lsize);
char *lzbuf = safe_calloc(payload_size); char *lzbuf = safe_calloc(payload_size);
(void) sfread(lzbuf, payload_size, stdin); (void) sfread(lzbuf, payload_size, stdin);
abd_t sabd, dabd; abd_t sabd, dabd;
abd_get_from_buf_struct(&sabd, lzbuf, payload_size); abd_get_from_buf_struct(&sabd, lzbuf, payload_size);
abd_get_from_buf_struct(&dabd, buf, payload_size); abd_get_from_buf_struct(&dabd, buf, lsize);
int err = zio_decompress_data(c, &sabd, &dabd, int err = zio_decompress_data(c, &sabd, &dabd,
payload_size, payload_size, NULL); payload_size, lsize, NULL);
abd_free(&dabd); abd_free(&dabd);
abd_free(&sabd); abd_free(&sabd);
if (err != 0) { if (err == 0) {
drrw->drr_compressiontype = 0;
drrw->drr_compressed_size = 0;
payload_size = lsize;
if (verbose) {
fprintf(stderr,
"successfully decompressed "
"ino %llu offset %llu\n",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
}
} else {
/* /*
* The block must not be compressed, at least * The block must not be compressed, at least
* not with this compression type, possibly * not with this compression type, possibly
@ -308,14 +323,6 @@ zstream_do_decompress(int argc, char *argv[])
(u_longlong_t)drrw->drr_object, (u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset); (u_longlong_t)drrw->drr_offset);
memcpy(buf, lzbuf, payload_size); memcpy(buf, lzbuf, payload_size);
} else if (verbose) {
drrw->drr_compressiontype = ZIO_COMPRESS_OFF;
fprintf(stderr, "successfully decompressed "
"ino %llu offset %llu\n",
(u_longlong_t)drrw->drr_object,
(u_longlong_t)drrw->drr_offset);
} else {
drrw->drr_compressiontype = ZIO_COMPRESS_OFF;
} }
free(lzbuf); free(lzbuf);