diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index c381d02a3..4c0a8245f 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -3984,13 +3984,6 @@ name: return (NULL); } -/* ARGSUSED */ -static int -random_get_pseudo_bytes_cb(void *buf, size_t len, void *unused) -{ - return (random_get_pseudo_bytes(buf, len)); -} - /* * Read a block from a pool and print it out. The syntax of the * block descriptor is: @@ -4160,17 +4153,8 @@ zdb_read_block(char *thing, spa_t *spa) * every decompress function at every inflated blocksize. */ enum zio_compress c; - void *pbuf2 = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL); void *lbuf2 = umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL); - abd_copy_to_buf(pbuf2, pabd, psize); - - VERIFY0(abd_iterate_func(pabd, psize, SPA_MAXBLOCKSIZE - psize, - random_get_pseudo_bytes_cb, NULL)); - - VERIFY0(random_get_pseudo_bytes((uint8_t *)pbuf2 + psize, - SPA_MAXBLOCKSIZE - psize)); - /* * XXX - On the one hand, with SPA_MAXBLOCKSIZE at 16MB, * this could take a while and we should let the user know @@ -4180,13 +4164,29 @@ zdb_read_block(char *thing, spa_t *spa) for (lsize = psize + SPA_MINBLOCKSIZE; lsize <= SPA_MAXBLOCKSIZE; lsize += SPA_MINBLOCKSIZE) { for (c = 0; c < ZIO_COMPRESS_FUNCTIONS; c++) { + /* + * ZLE can easily decompress non zle stream. + * So have an option to disable it. + */ + if (c == ZIO_COMPRESS_ZLE && + getenv("ZDB_NO_ZLE")) + continue; + (void) fprintf(stderr, "Trying %05llx -> %05llx (%s)\n", (u_longlong_t)psize, (u_longlong_t)lsize, zio_compress_table[c].ci_name); + + /* + * We randomize lbuf2, and decompress to both + * lbuf and lbuf2. This way, we will know if + * decompression fill exactly to lsize. + */ + VERIFY0(random_get_pseudo_bytes(lbuf2, lsize)); + if (zio_decompress_data(c, pabd, lbuf, psize, lsize) == 0 && - zio_decompress_data_buf(c, pbuf2, + zio_decompress_data(c, pabd, lbuf2, psize, lsize) == 0 && bcmp(lbuf, lbuf2, lsize) == 0) break; @@ -4194,11 +4194,9 @@ zdb_read_block(char *thing, spa_t *spa) if (c != ZIO_COMPRESS_FUNCTIONS) break; } - - umem_free(pbuf2, SPA_MAXBLOCKSIZE); umem_free(lbuf2, SPA_MAXBLOCKSIZE); - if (lsize <= psize) { + if (lsize > SPA_MAXBLOCKSIZE) { (void) printf("Decompress of %s failed\n", thing); goto out; } diff --git a/man/man8/zdb.8 b/man/man8/zdb.8 index d69d6f529..0ce4d852d 100644 --- a/man/man8/zdb.8 +++ b/man/man8/zdb.8 @@ -248,7 +248,9 @@ and, optionally, .It Sy b Ar offset Print block pointer .It Sy d -Decompress the block +Decompress the block. Set environment variable +.Nm ZBD_NO_ZLE +to skip zle when guessing. .It Sy e Byte swap the block .It Sy g