diff options
author | Serapheim Dimitropoulos <serapheim@delphix.com> | 2017-08-04 09:30:49 -0700 |
---|---|---|
committer | Prakash Surya <prakash.surya@delphix.com> | 2018-04-02 09:16:05 -0700 |
commit | 17f11284b49b98353b5119463254074fd9bc0a28 (patch) | |
tree | 7efffb8c98a425199065e78b99ba894b9127795f /usr/src/cmd/mdb | |
parent | 1c10ae76c0cb31326c320e7cef1d3f24a1f47125 (diff) | |
download | illumos-gate-17f11284b49b98353b5119463254074fd9bc0a28.tar.gz |
9238 ZFS Spacemap Encoding V2
Reviewed by: Matt Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <gwilson@zfsmail.com>
Approved by: Gordon Ross <gwr@nexenta.com>
Diffstat (limited to 'usr/src/cmd/mdb')
-rw-r--r-- | usr/src/cmd/mdb/common/modules/zfs/zfs.c | 142 |
1 files changed, 99 insertions, 43 deletions
diff --git a/usr/src/cmd/mdb/common/modules/zfs/zfs.c b/usr/src/cmd/mdb/common/modules/zfs/zfs.c index 06ce396ef8..5d3af7ff3c 100644 --- a/usr/src/cmd/mdb/common/modules/zfs/zfs.c +++ b/usr/src/cmd/mdb/common/modules/zfs/zfs.c @@ -178,55 +178,110 @@ mdb_nicenum(uint64_t num, char *buf) } } -static int verbose; - +/* + * <addr>::sm_entries <buffer length in bytes> + * + * Treat the buffer specified by the given address as a buffer that contains + * space map entries. Iterate over the specified number of entries and print + * them in both encoded and decoded form. + */ +/* ARGSUSED */ static int -freelist_walk_init(mdb_walk_state_t *wsp) +sm_entries(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { - if (wsp->walk_addr == NULL) { - mdb_warn("must supply starting address\n"); - return (WALK_ERR); + uint64_t bufsz = 0; + boolean_t preview = B_FALSE; + + if (!(flags & DCMD_ADDRSPEC)) + return (DCMD_USAGE); + + if (argc < 1) { + preview = B_TRUE; + bufsz = 2; + } else if (argc != 1) { + return (DCMD_USAGE); + } else { + switch (argv[0].a_type) { + case MDB_TYPE_STRING: + bufsz = mdb_strtoull(argv[0].a_un.a_str); + break; + case MDB_TYPE_IMMEDIATE: + bufsz = argv[0].a_un.a_val; + break; + default: + return (DCMD_USAGE); + } } - wsp->walk_data = 0; /* Index into the freelist */ - return (WALK_NEXT); -} + char *actions[] = { "ALLOC", "FREE", "INVALID" }; + for (uintptr_t bufend = addr + bufsz; addr < bufend; + addr += sizeof (uint64_t)) { + uint64_t nwords; + uint64_t start_addr = addr; -static int -freelist_walk_step(mdb_walk_state_t *wsp) -{ - uint64_t entry; - uintptr_t number = (uintptr_t)wsp->walk_data; - char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID", - "INVALID", "INVALID", "INVALID", "INVALID" }; - int mapshift = SPA_MINBLOCKSHIFT; + uint64_t word = 0; + if (mdb_vread(&word, sizeof (word), addr) == -1) { + mdb_warn("failed to read space map entry %p", addr); + return (DCMD_ERR); + } - if (mdb_vread(&entry, sizeof (entry), wsp->walk_addr) == -1) { - mdb_warn("failed to read freelist entry %p", wsp->walk_addr); - return (WALK_DONE); - } - wsp->walk_addr += sizeof (entry); - wsp->walk_data = (void *)(number + 1); + if (SM_PREFIX_DECODE(word) == SM_DEBUG_PREFIX) { + (void) mdb_printf("\t [%6llu] %s: txg %llu, " + "pass %llu\n", + (u_longlong_t)(addr), + actions[SM_DEBUG_ACTION_DECODE(word)], + (u_longlong_t)SM_DEBUG_TXG_DECODE(word), + (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(word)); + continue; + } - if (SM_DEBUG_DECODE(entry)) { - mdb_printf("DEBUG: %3u %10s: txg=%llu pass=%llu\n", - number, - ddata[SM_DEBUG_ACTION_DECODE(entry)], - SM_DEBUG_TXG_DECODE(entry), - SM_DEBUG_SYNCPASS_DECODE(entry)); - } else { - mdb_printf("Entry: %3u offsets=%08llx-%08llx type=%c " - "size=%06llx", number, - SM_OFFSET_DECODE(entry) << mapshift, - (SM_OFFSET_DECODE(entry) + SM_RUN_DECODE(entry)) << - mapshift, - SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F', - SM_RUN_DECODE(entry) << mapshift); - if (verbose) - mdb_printf(" (raw=%012llx)\n", entry); - mdb_printf("\n"); + char entry_type; + uint64_t raw_offset, raw_run, vdev_id = SM_NO_VDEVID; + + if (SM_PREFIX_DECODE(word) != SM2_PREFIX) { + entry_type = (SM_TYPE_DECODE(word) == SM_ALLOC) ? + 'A' : 'F'; + raw_offset = SM_OFFSET_DECODE(word); + raw_run = SM_RUN_DECODE(word); + nwords = 1; + } else { + ASSERT3U(SM_PREFIX_DECODE(word), ==, SM2_PREFIX); + + raw_run = SM2_RUN_DECODE(word); + vdev_id = SM2_VDEV_DECODE(word); + + /* it is a two-word entry so we read another word */ + addr += sizeof (uint64_t); + if (addr >= bufend) { + mdb_warn("buffer ends in the middle of a two " + "word entry\n", addr); + return (DCMD_ERR); + } + + if (mdb_vread(&word, sizeof (word), addr) == -1) { + mdb_warn("failed to read space map entry %p", + addr); + return (DCMD_ERR); + } + + entry_type = (SM2_TYPE_DECODE(word) == SM_ALLOC) ? + 'A' : 'F'; + raw_offset = SM2_OFFSET_DECODE(word); + nwords = 2; + } + + (void) mdb_printf("\t [%6llx] %c range:" + " %010llx-%010llx size: %06llx vdev: %06llu words: %llu\n", + (u_longlong_t)start_addr, + entry_type, (u_longlong_t)raw_offset, + (u_longlong_t)(raw_offset + raw_run), + (u_longlong_t)raw_run, + (u_longlong_t)vdev_id, (u_longlong_t)nwords); + + if (preview) + break; } - return (WALK_NEXT); + return (DCMD_OK); } static int @@ -3974,6 +4029,9 @@ static const mdb_dcmd_t dcmds[] = { "\t-M display metaslab group statistic\n" "\t-h display histogram (requires -m or -M)\n", "given a spa_t, print vdev summary", spa_vdevs }, + { "sm_entries", "<buffer length in bytes>", + "print out space map entries from a buffer decoded", + sm_entries}, { "vdev", ":[-remMh]\n" "\t-r display recursively\n" "\t-e display statistics\n" @@ -4024,8 +4082,6 @@ static const mdb_dcmd_t dcmds[] = { }; static const mdb_walker_t walkers[] = { - { "zms_freelist", "walk ZFS metaslab freelist", - freelist_walk_init, freelist_walk_step, NULL }, { "txg_list", "given any txg_list_t *, walk all entries in all txgs", txg_list_walk_init, txg_list_walk_step, NULL }, { "txg_list0", "given any txg_list_t *, walk all entries in txg 0", |