diff options
Diffstat (limited to 'cmd/zdb/zdb.c')
-rw-r--r-- | cmd/zdb/zdb.c | 106 |
1 files changed, 96 insertions, 10 deletions
diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 977ba02c1..e7211711a 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -27,6 +27,10 @@ * Copyright (c) 2017, 2018 Lawrence Livermore National Security, LLC. * Copyright (c) 2015, 2017, Intel Corporation. * Copyright (c) 2020 Datto Inc. + * Copyright (c) 2020, The FreeBSD Foundation [1] + * + * [1] Portions of this software were developed by Allan Jude + * under sponsorship from the FreeBSD Foundation. */ #include <stdio.h> @@ -71,6 +75,7 @@ #include <sys/dsl_scan.h> #include <sys/btree.h> #include <zfs_comutil.h> +#include <sys/zstd/zstd.h> #include <libnvpair.h> #include <libzutil.h> @@ -834,6 +839,7 @@ usage(void) "work with dataset)\n"); (void) fprintf(stderr, " -Y attempt all reconstruction " "combinations for split blocks\n"); + (void) fprintf(stderr, " -Z show ZSTD headers \n"); (void) fprintf(stderr, "Specify an option more than once (e.g. -bb) " "to make only that option verbose\n"); (void) fprintf(stderr, "Default is to dump everything non-verbosely\n"); @@ -2135,6 +2141,65 @@ blkid2offset(const dnode_phys_t *dnp, const blkptr_t *bp, } static void +snprintf_zstd_header(spa_t *spa, char *blkbuf, size_t buflen, + const blkptr_t *bp) +{ + abd_t *pabd; + void *buf; + zio_t *zio; + zfs_zstdhdr_t zstd_hdr; + int error; + + if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_ZSTD) + return; + + if (BP_IS_HOLE(bp)) + return; + + if (BP_IS_EMBEDDED(bp)) { + buf = malloc(SPA_MAXBLOCKSIZE); + if (buf == NULL) { + (void) fprintf(stderr, "out of memory\n"); + exit(1); + } + decode_embedded_bp_compressed(bp, buf); + memcpy(&zstd_hdr, buf, sizeof (zstd_hdr)); + free(buf); + zstd_hdr.c_len = BE_32(zstd_hdr.c_len); + zstd_hdr.raw_version_level = BE_32(zstd_hdr.raw_version_level); + (void) snprintf(blkbuf + strlen(blkbuf), + buflen - strlen(blkbuf), + " ZSTD:size=%u:version=%u:level=%u:EMBEDDED", + zstd_hdr.c_len, zstd_hdr.version, zstd_hdr.level); + return; + } + + pabd = abd_alloc_for_io(SPA_MAXBLOCKSIZE, B_FALSE); + zio = zio_root(spa, NULL, NULL, 0); + + /* Decrypt but don't decompress so we can read the compression header */ + zio_nowait(zio_read(zio, spa, bp, pabd, BP_GET_PSIZE(bp), NULL, NULL, + ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL | ZIO_FLAG_RAW_COMPRESS, + NULL)); + error = zio_wait(zio); + if (error) { + (void) fprintf(stderr, "read failed: %d\n", error); + return; + } + buf = abd_borrow_buf_copy(pabd, BP_GET_LSIZE(bp)); + memcpy(&zstd_hdr, buf, sizeof (zstd_hdr)); + zstd_hdr.c_len = BE_32(zstd_hdr.c_len); + zstd_hdr.raw_version_level = BE_32(zstd_hdr.raw_version_level); + + (void) snprintf(blkbuf + strlen(blkbuf), + buflen - strlen(blkbuf), + " ZSTD:size=%u:version=%u:level=%u:NORMAL", + zstd_hdr.c_len, zstd_hdr.version, zstd_hdr.level); + + abd_return_buf_copy(pabd, buf, BP_GET_LSIZE(bp)); +} + +static void snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp, boolean_t bp_freed) { @@ -2198,7 +2263,7 @@ snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp, } static void -print_indirect(blkptr_t *bp, const zbookmark_phys_t *zb, +print_indirect(spa_t *spa, blkptr_t *bp, const zbookmark_phys_t *zb, const dnode_phys_t *dnp) { char blkbuf[BP_SPRINTF_LEN]; @@ -2222,6 +2287,8 @@ print_indirect(blkptr_t *bp, const zbookmark_phys_t *zb, } snprintf_blkptr_compact(blkbuf, sizeof (blkbuf), bp, B_FALSE); + if (dump_opt['Z'] && BP_GET_COMPRESS(bp) == ZIO_COMPRESS_ZSTD) + snprintf_zstd_header(spa, blkbuf, sizeof (blkbuf), bp); (void) printf("%s\n", blkbuf); } @@ -2234,7 +2301,7 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp, if (bp->blk_birth == 0) return (0); - print_indirect(bp, zb, dnp); + print_indirect(spa, bp, zb, dnp); if (BP_GET_LEVEL(bp) > 0 && !BP_IS_HOLE(bp)) { arc_flags_t flags = ARC_FLAG_WAIT; @@ -3310,7 +3377,25 @@ dump_object(objset_t *os, uint64_t object, int verbosity, " (K=%s)", ZDB_CHECKSUM_NAME(doi.doi_checksum)); } - if (doi.doi_compress != ZIO_COMPRESS_INHERIT || verbosity >= 6) { + if (doi.doi_compress == ZIO_COMPRESS_INHERIT && + ZIO_COMPRESS_HASLEVEL(os->os_compress) && verbosity >= 6) { + const char *compname = NULL; + if (zfs_prop_index_to_string(ZFS_PROP_COMPRESSION, + ZIO_COMPRESS_RAW(os->os_compress, os->os_complevel), + &compname) == 0) { + (void) snprintf(aux + strlen(aux), + sizeof (aux) - strlen(aux), " (Z=inherit=%s)", + compname); + } else { + (void) snprintf(aux + strlen(aux), + sizeof (aux) - strlen(aux), + " (Z=inherit=%s-unknown)", + ZDB_COMPRESS_NAME(os->os_compress)); + } + } else if (doi.doi_compress == ZIO_COMPRESS_INHERIT && verbosity >= 6) { + (void) snprintf(aux + strlen(aux), sizeof (aux) - strlen(aux), + " (Z=inherit=%s)", ZDB_COMPRESS_NAME(os->os_compress)); + } else if (doi.doi_compress != ZIO_COMPRESS_INHERIT || verbosity >= 6) { (void) snprintf(aux + strlen(aux), sizeof (aux) - strlen(aux), " (Z=%s)", ZDB_COMPRESS_NAME(doi.doi_compress)); } @@ -4093,6 +4178,8 @@ dump_l2arc_log_entries(uint64_t log_entries, (u_longlong_t)L2BLK_GET_PSIZE((&le[j])->le_prop)); (void) printf("|\t\t\t\tcompr: %llu\n", (u_longlong_t)L2BLK_GET_COMPRESS((&le[j])->le_prop)); + (void) printf("|\t\t\t\tcomplevel: %llu\n", + (u_longlong_t)(&le[j])->le_complevel); (void) printf("|\t\t\t\ttype: %llu\n", (u_longlong_t)L2BLK_GET_TYPE((&le[j])->le_prop)); (void) printf("|\t\t\t\tprotected: %llu\n", @@ -4186,16 +4273,14 @@ dump_l2arc_log_blocks(int fd, l2arc_dev_hdr_phys_t l2dhdr, switch (L2BLK_GET_COMPRESS((&lbps[0])->lbp_prop)) { case ZIO_COMPRESS_OFF: break; - case ZIO_COMPRESS_LZ4: + default: abd = abd_alloc_for_io(asize, B_TRUE); abd_copy_from_buf_off(abd, &this_lb, 0, asize); zio_decompress_data(L2BLK_GET_COMPRESS( (&lbps[0])->lbp_prop), abd, &this_lb, - asize, sizeof (this_lb)); + asize, sizeof (this_lb), NULL); abd_free(abd); break; - default: - break; } if (this_lb.lb_magic == BSWAP_64(L2ARC_LOG_BLK_MAGIC)) @@ -7684,9 +7769,9 @@ zdb_decompress_block(abd_t *pabd, void *buf, void *lbuf, uint64_t lsize, VERIFY0(random_get_pseudo_bytes(lbuf2, lsize)); if (zio_decompress_data(*cfuncp, pabd, - lbuf, psize, lsize) == 0 && + lbuf, psize, lsize, NULL) == 0 && zio_decompress_data(*cfuncp, pabd, - lbuf2, psize, lsize) == 0 && + lbuf2, psize, lsize, NULL) == 0 && bcmp(lbuf, lbuf2, lsize) == 0) break; } @@ -8078,7 +8163,7 @@ main(int argc, char **argv) zfs_btree_verify_intensity = 3; while ((c = getopt(argc, argv, - "AbcCdDeEFGhiI:klLmMo:Op:PqRsSt:uU:vVx:XYy")) != -1) { + "AbcCdDeEFGhiI:klLmMo:Op:PqRsSt:uU:vVx:XYyZ")) != -1) { switch (c) { case 'b': case 'c': @@ -8098,6 +8183,7 @@ main(int argc, char **argv) case 'S': case 'u': case 'y': + case 'Z': dump_opt[c]++; dump_all = 0; break; |