Author: avg
Date: Fri Oct  6 08:21:06 2017
New Revision: 324349
URL: https://svnweb.freebsd.org/changeset/base/324349

Log:
  MFV r322235: 8067 zdb should be able to dump literal embedded block pointer
  
  illumos/illumos-gate@4923c69fddc0887da5604a262585af3efd82ee20
  
https://github.com/illumos/illumos-gate/commit/4923c69fddc0887da5604a262585af3efd82ee20
  
  FreeBSD note: the manual page is to be updated separately.
  
  https://www.illumos.org/issues/8067
    Add an option to zdb to print a literal embedded block pointer supplied on 
the
    command line:
    zdb -E [-A] word0:word1:...:word15
  
  Reviewed by: George Wilson <george.wil...@delphix.com>
  Reviewed by: Alex Reece <a...@delphix.com>
  Reviewed by: Yuri Pankov <yuri.pan...@gmail.com>
  Approved by: Robert Mustacchi <r...@joyent.com>
  Author: Matthew Ahrens <mahr...@delphix.com>
  
  MFC after:    3 weeks

Modified:
  head/cddl/contrib/opensolaris/cmd/zdb/zdb.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/blkptr.h
Directory Properties:
  head/cddl/contrib/opensolaris/   (props changed)
  head/cddl/contrib/opensolaris/cmd/zdb/   (props changed)
  head/sys/cddl/contrib/opensolaris/   (props changed)

Modified: head/cddl/contrib/opensolaris/cmd/zdb/zdb.c
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/zdb/zdb.c Fri Oct  6 08:17:12 2017        
(r324348)
+++ head/cddl/contrib/opensolaris/cmd/zdb/zdb.c Fri Oct  6 08:21:06 2017        
(r324349)
@@ -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>
@@ -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");
@@ -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");
@@ -3653,6 +3657,33 @@ out:
        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)
 {
@@ -3771,13 +3802,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':
@@ -3841,6 +3873,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++;
@@ -3889,7 +3927,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;
@@ -3903,6 +3941,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);

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c        Fri Oct 
 6 08:17:12 2017        (r324348)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c        Fri Oct 
 6 08:21:06 2017        (r324349)
@@ -117,3 +117,36 @@ decode_embedded_bp_compressed(const blkptr_t *bp, void
                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_buf(BP_GET_COMPRESS(bp),
+                   dstbuf, buf, psize, buflen));
+       } else {
+               ASSERT3U(lsize, ==, psize);
+               decode_embedded_bp_compressed(bp, buf);
+       }
+
+       return (0);
+}

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/blkptr.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/blkptr.h    Fri Oct 
 6 08:17:12 2017        (r324348)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/blkptr.h    Fri Oct 
 6 08:21:06 2017        (r324349)
@@ -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
 }
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to