Skip to content

Commit

Permalink
8067 zdb should be able to dump literal embedded block pointer
Browse files Browse the repository at this point in the history
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Alex Reece <alex@delphix.com>
Reviewed by: Yuri Pankov <yuri.pankov@gmail.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
  • Loading branch information
ahrens authored and Prakash Surya committed May 24, 2017
1 parent c5ee468 commit d77f819
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 5 deletions.
52 changes: 49 additions & 3 deletions usr/src/cmd/zdb/zdb.c
Expand Up @@ -61,6 +61,7 @@
#include <sys/ddt.h>
#include <sys/zfeature.h>
#include <sys/abd.h>
#include <sys/blkptr.h>
#include <zfs_comutil.h>
#undef verify
#include <libzfs.h>
Expand Down Expand Up @@ -134,10 +135,11 @@ usage(void)
"\t%s -O <dataset> <path>\n"
"\t%s -R [-A] [-e [-V] [-p <path> ...]] [-U <cache>]\n"
"\t\t<poolname> <vdev>:<offset>:<size>[:<flags>]\n"
"\t%s -E [-A] word0:word1:...:word15\n"
"\t%s -S [-AP] [-e [-V] [-p <path> ...]] [-U <cache>] "
"<poolname>\n\n",
cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname,
cmdname);
cmdname, cmdname);

(void) fprintf(stderr, " Dataset name must include at least one "
"separator character '/' or '@'\n");
Expand All @@ -152,6 +154,8 @@ usage(void)
(void) fprintf(stderr, " -C config (or cachefile if alone)\n");
(void) fprintf(stderr, " -d dataset(s)\n");
(void) fprintf(stderr, " -D dedup statistics\n");
(void) fprintf(stderr, " -E decode and display block from an "
"embedded block pointer\n");
(void) fprintf(stderr, " -h pool history\n");
(void) fprintf(stderr, " -i intent logs\n");
(void) fprintf(stderr, " -l read label contents\n");
Expand Down Expand Up @@ -3623,6 +3627,33 @@ zdb_read_block(char *thing, spa_t *spa)
free(dup);
}

static void
zdb_embedded_block(char *thing)
{
blkptr_t bp = { 0 };
unsigned long long *words = (void *)&bp;
char buf[SPA_MAXBLOCKSIZE];
int err;

err = sscanf(thing, "%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx:"
"%llx:%llx:%llx:%llx:%llx:%llx:%llx:%llx",
words + 0, words + 1, words + 2, words + 3,
words + 4, words + 5, words + 6, words + 7,
words + 8, words + 9, words + 10, words + 11,
words + 12, words + 13, words + 14, words + 15);
if (err != 16) {
(void) printf("invalid input format\n");
exit(1);
}
ASSERT3U(BPE_GET_LSIZE(&bp), <=, SPA_MAXBLOCKSIZE);
err = decode_embedded_bp(&bp, buf, BPE_GET_LSIZE(&bp));
if (err != 0) {
(void) printf("decode failed: %u\n", err);
exit(1);
}
zdb_dump_block_raw(buf, BPE_GET_LSIZE(&bp), 0);
}

static boolean_t
pool_match(nvlist_t *cfg, char *tgt)
{
Expand Down Expand Up @@ -3741,13 +3772,14 @@ main(int argc, char **argv)
spa_config_path = spa_config_path_env;

while ((c = getopt(argc, argv,
"AbcCdDeFGhiI:lLmMo:Op:PqRsSt:uU:vVx:X")) != -1) {
"AbcCdDeEFGhiI:lLmMo:Op:PqRsSt:uU:vVx:X")) != -1) {
switch (c) {
case 'b':
case 'c':
case 'C':
case 'd':
case 'D':
case 'E':
case 'G':
case 'h':
case 'i':
Expand Down Expand Up @@ -3811,6 +3843,12 @@ main(int argc, char **argv)
break;
case 'U':
spa_config_path = optarg;
if (spa_config_path[0] != '/') {
(void) fprintf(stderr,
"cachefile must be an absolute path "
"(i.e. start with a slash)\n");
usage();
}
break;
case 'v':
verbose++;
Expand Down Expand Up @@ -3858,7 +3896,7 @@ main(int argc, char **argv)
verbose = MAX(verbose, 1);

for (c = 0; c < 256; c++) {
if (dump_all && strchr("AeFlLOPRSX", c) == NULL)
if (dump_all && strchr("AeEFlLOPRSX", c) == NULL)
dump_opt[c] = 1;
if (dump_opt[c])
dump_opt[c] += verbose;
Expand All @@ -3872,6 +3910,14 @@ main(int argc, char **argv)

if (argc < 2 && dump_opt['R'])
usage();

if (dump_opt['E']) {
if (argc != 1)
usage();
zdb_embedded_block(argv[0]);
return (0);
}

if (argc < 1) {
if (!dump_opt['e'] && dump_opt['C']) {
dump_cachefile(spa_config_path);
Expand Down
12 changes: 10 additions & 2 deletions usr/src/man/man1m/zdb.1m
Expand Up @@ -10,10 +10,10 @@
.\"
.\"
.\" Copyright 2012, Richard Lowe.
.\" Copyright (c) 2012, 2016 by Delphix. All rights reserved.
.\" Copyright (c) 2012, 2017 by Delphix. All rights reserved.
.\" Copyright 2017 Nexenta Systems, Inc.
.\"
.Dd January 14, 2017
.Dd April 14, 2017
.Dt ZDB 1M
.Os
.Sh NAME
Expand All @@ -39,6 +39,10 @@
.Op Fl A
.Op Fl U Ar cache
.Nm
.Fl E
.Op Fl A
.Ar word0 Ns : Ns Ar word1 Ns :...: Ns Ar word15
.Nm
.Fl l
.Op Fl Aqu
.Ar device
Expand Down Expand Up @@ -153,6 +157,10 @@ Display the statistics independently for each deduplication table.
Dump the contents of the deduplication tables describing duplicate blocks.
.It Fl DDDDD
Also dump the contents of the deduplication tables describing unique blocks.
.It Fl E Ar word0 Ns : Ns Ar word1 Ns :...: Ns Ar word15
Decode and display block from an embedded block pointer specified by the
.Ar word
arguments.
.It Fl h
Display pool history similar to
.Nm zpool Cm history ,
Expand Down
33 changes: 33 additions & 0 deletions usr/src/uts/common/fs/zfs/blkptr.c
Expand Up @@ -117,3 +117,36 @@ decode_embedded_bp_compressed(const blkptr_t *bp, void *buf)
buf8[i] = BF64_GET(w, (i % sizeof (w)) * NBBY, NBBY);
}
}

/*
* Fill in the buffer with the (decompressed) payload of the embedded
* blkptr_t. Takes into account compression and byteorder (the payload is
* treated as a stream of bytes).
* Return 0 on success, or ENOSPC if it won't fit in the buffer.
*/
int
decode_embedded_bp(const blkptr_t *bp, void *buf, int buflen)
{
int lsize, psize;

ASSERT(BP_IS_EMBEDDED(bp));

lsize = BPE_GET_LSIZE(bp);
psize = BPE_GET_PSIZE(bp);

if (lsize > buflen)
return (ENOSPC);
ASSERT3U(lsize, ==, buflen);

if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF) {
uint8_t dstbuf[BPE_PAYLOAD_SIZE];
decode_embedded_bp_compressed(bp, dstbuf);
VERIFY0(zio_decompress_data(BP_GET_COMPRESS(bp),
dstbuf, buf, psize, buflen));
} else {
ASSERT3U(lsize, ==, psize);
decode_embedded_bp_compressed(bp, buf);
}

return (0);
}
1 change: 1 addition & 0 deletions usr/src/uts/common/fs/zfs/sys/blkptr.h
Expand Up @@ -30,6 +30,7 @@ extern "C" {
void encode_embedded_bp_compressed(blkptr_t *, void *,
enum zio_compress, int, int);
void decode_embedded_bp_compressed(const blkptr_t *, void *);
int decode_embedded_bp(const blkptr_t *, void *, int);

#ifdef __cplusplus
}
Expand Down

0 comments on commit d77f819

Please sign in to comment.