mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Rebase master to b105
This commit is contained in:
+74
-43
@@ -87,8 +87,8 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
(void) fprintf(stderr,
|
||||
"Usage: %s [-udibcsv] [-U cachefile_path] "
|
||||
"[-S user:cksumalg] "
|
||||
"Usage: %s [-udibcsvL] [-U cachefile_path] [-t txg]\n"
|
||||
"\t [-S user:cksumalg] "
|
||||
"dataset [object...]\n"
|
||||
" %s -C [pool]\n"
|
||||
" %s -l dev\n"
|
||||
@@ -108,6 +108,8 @@ usage(void)
|
||||
"dump blkptr signatures\n");
|
||||
(void) fprintf(stderr, " -v verbose (applies to all others)\n");
|
||||
(void) fprintf(stderr, " -l dump label contents\n");
|
||||
(void) fprintf(stderr, " -L disable leak tracking (do not "
|
||||
"load spacemaps)\n");
|
||||
(void) fprintf(stderr, " -U cachefile_path -- use alternate "
|
||||
"cachefile\n");
|
||||
(void) fprintf(stderr, " -R read and display block from a "
|
||||
@@ -115,6 +117,8 @@ usage(void)
|
||||
(void) fprintf(stderr, " -e Pool is exported/destroyed/"
|
||||
"has altroot\n");
|
||||
(void) fprintf(stderr, " -p <Path to vdev dir> (use with -e)\n");
|
||||
(void) fprintf(stderr, " -t <txg> highest txg to use when "
|
||||
"searching for uberblocks\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");
|
||||
@@ -516,45 +520,53 @@ dump_metaslabs(spa_t *spa)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dtl_seg(space_map_t *sm, uint64_t start, uint64_t size)
|
||||
{
|
||||
char *prefix = (void *)sm;
|
||||
|
||||
(void) printf("%s [%llu,%llu) length %llu\n",
|
||||
prefix,
|
||||
(u_longlong_t)start,
|
||||
(u_longlong_t)(start + size),
|
||||
(u_longlong_t)(size));
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dtl(vdev_t *vd, int indent)
|
||||
{
|
||||
avl_tree_t *t = &vd->vdev_dtl_map.sm_root;
|
||||
space_seg_t *ss;
|
||||
vdev_t *pvd;
|
||||
int c;
|
||||
spa_t *spa = vd->vdev_spa;
|
||||
boolean_t required;
|
||||
char *name[DTL_TYPES] = { "missing", "partial", "scrub", "outage" };
|
||||
char prefix[256];
|
||||
|
||||
spa_vdev_state_enter(spa);
|
||||
required = vdev_dtl_required(vd);
|
||||
(void) spa_vdev_state_exit(spa, NULL, 0);
|
||||
|
||||
if (indent == 0)
|
||||
(void) printf("\nDirty time logs:\n\n");
|
||||
|
||||
(void) printf("\t%*s%s\n", indent, "",
|
||||
(void) printf("\t%*s%s [%s]\n", indent, "",
|
||||
vd->vdev_path ? vd->vdev_path :
|
||||
vd->vdev_parent ? vd->vdev_ops->vdev_op_type :
|
||||
spa_name(vd->vdev_spa));
|
||||
vd->vdev_parent ? vd->vdev_ops->vdev_op_type : spa_name(spa),
|
||||
required ? "DTL-required" : "DTL-expendable");
|
||||
|
||||
for (ss = avl_first(t); ss; ss = AVL_NEXT(t, ss)) {
|
||||
/*
|
||||
* Everything in this DTL must appear in all parent DTL unions.
|
||||
*/
|
||||
for (pvd = vd; pvd; pvd = pvd->vdev_parent)
|
||||
ASSERT(vdev_dtl_contains(&pvd->vdev_dtl_map,
|
||||
ss->ss_start, ss->ss_end - ss->ss_start));
|
||||
(void) printf("\t%*soutage [%llu,%llu] length %llu\n",
|
||||
indent, "",
|
||||
(u_longlong_t)ss->ss_start,
|
||||
(u_longlong_t)ss->ss_end - 1,
|
||||
(u_longlong_t)(ss->ss_end - ss->ss_start));
|
||||
for (int t = 0; t < DTL_TYPES; t++) {
|
||||
space_map_t *sm = &vd->vdev_dtl[t];
|
||||
if (sm->sm_space == 0)
|
||||
continue;
|
||||
(void) snprintf(prefix, sizeof (prefix), "\t%*s%s",
|
||||
indent + 2, "", name[t]);
|
||||
mutex_enter(sm->sm_lock);
|
||||
space_map_walk(sm, dump_dtl_seg, (void *)prefix);
|
||||
mutex_exit(sm->sm_lock);
|
||||
if (dump_opt['d'] > 5 && vd->vdev_children == 0)
|
||||
dump_spacemap(spa->spa_meta_objset,
|
||||
&vd->vdev_dtl_smo, sm);
|
||||
}
|
||||
|
||||
(void) printf("\n");
|
||||
|
||||
if (dump_opt['d'] > 5 && vd->vdev_children == 0) {
|
||||
dump_spacemap(vd->vdev_spa->spa_meta_objset, &vd->vdev_dtl,
|
||||
&vd->vdev_dtl_map);
|
||||
(void) printf("\n");
|
||||
}
|
||||
|
||||
for (c = 0; c < vd->vdev_children; c++)
|
||||
for (int c = 0; c < vd->vdev_children; c++)
|
||||
dump_dtl(vd->vdev_child[c], indent + 4);
|
||||
}
|
||||
|
||||
@@ -668,7 +680,8 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
|
||||
break;
|
||||
fill += cbp->blk_fill;
|
||||
}
|
||||
ASSERT3U(fill, ==, bp->blk_fill);
|
||||
if (!err)
|
||||
ASSERT3U(fill, ==, bp->blk_fill);
|
||||
(void) arc_buf_remove_ref(buf, &buf);
|
||||
}
|
||||
|
||||
@@ -1481,8 +1494,9 @@ zdb_count_block(spa_t *spa, zdb_cb_t *zcb, blkptr_t *bp, dmu_object_type_t type)
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY(zio_wait(zio_claim(NULL, spa, spa_first_txg(spa), bp,
|
||||
NULL, NULL, ZIO_FLAG_MUSTSUCCEED)) == 0);
|
||||
if (!dump_opt['L'])
|
||||
VERIFY(zio_wait(zio_claim(NULL, spa, spa_first_txg(spa), bp,
|
||||
NULL, NULL, ZIO_FLAG_MUSTSUCCEED)) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1557,9 +1571,11 @@ dump_block_stats(spa_t *spa)
|
||||
int c, e;
|
||||
|
||||
if (!dump_opt['S']) {
|
||||
(void) printf("\nTraversing all blocks to %sverify"
|
||||
" nothing leaked ...\n",
|
||||
dump_opt['c'] ? "verify checksums and " : "");
|
||||
(void) printf("\nTraversing all blocks %s%s%s%s...\n",
|
||||
(dump_opt['c'] || !dump_opt['L']) ? "to verify " : "",
|
||||
dump_opt['c'] ? "checksums " : "",
|
||||
(dump_opt['c'] && !dump_opt['L']) ? "and verify " : "",
|
||||
!dump_opt['L'] ? "nothing leaked " : "");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1570,7 +1586,8 @@ dump_block_stats(spa_t *spa)
|
||||
* it's not part of any space map) is a double allocation,
|
||||
* reference to a freed block, or an unclaimed log block.
|
||||
*/
|
||||
zdb_leak_init(spa);
|
||||
if (!dump_opt['L'])
|
||||
zdb_leak_init(spa);
|
||||
|
||||
/*
|
||||
* If there's a deferred-free bplist, process that first.
|
||||
@@ -1612,7 +1629,8 @@ dump_block_stats(spa_t *spa)
|
||||
/*
|
||||
* Report any leaked segments.
|
||||
*/
|
||||
zdb_leak_fini(spa);
|
||||
if (!dump_opt['L'])
|
||||
zdb_leak_fini(spa);
|
||||
|
||||
/*
|
||||
* If we're interested in printing out the blkptr signatures,
|
||||
@@ -1638,14 +1656,16 @@ dump_block_stats(spa_t *spa)
|
||||
tzb = &zcb.zcb_type[ZB_TOTAL][DMU_OT_TOTAL];
|
||||
|
||||
if (tzb->zb_asize == alloc + logalloc) {
|
||||
(void) printf("\n\tNo leaks (block sum matches space"
|
||||
" maps exactly)\n");
|
||||
if (!dump_opt['L'])
|
||||
(void) printf("\n\tNo leaks (block sum matches space"
|
||||
" maps exactly)\n");
|
||||
} else {
|
||||
(void) printf("block traversal size %llu != alloc %llu "
|
||||
"(leaked %lld)\n",
|
||||
"(%s %lld)\n",
|
||||
(u_longlong_t)tzb->zb_asize,
|
||||
(u_longlong_t)alloc + logalloc,
|
||||
(u_longlong_t)(alloc + logalloc - tzb->zb_asize));
|
||||
(dump_opt['L']) ? "unreachable" : "leaked",
|
||||
(longlong_t)(alloc + logalloc - tzb->zb_asize));
|
||||
leaks = 1;
|
||||
}
|
||||
|
||||
@@ -2235,7 +2255,7 @@ main(int argc, char **argv)
|
||||
|
||||
dprintf_setup(&argc, argv);
|
||||
|
||||
while ((c = getopt(argc, argv, "udibcsvCS:U:lRep:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "udibcsvCLS:U:lRep:t:")) != -1) {
|
||||
switch (c) {
|
||||
case 'u':
|
||||
case 'd':
|
||||
@@ -2249,6 +2269,9 @@ main(int argc, char **argv)
|
||||
dump_opt[c]++;
|
||||
dump_all = 0;
|
||||
break;
|
||||
case 'L':
|
||||
dump_opt[c]++;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
@@ -2279,6 +2302,14 @@ main(int argc, char **argv)
|
||||
else
|
||||
usage();
|
||||
break;
|
||||
case 't':
|
||||
ub_max_txg = strtoull(optarg, NULL, 0);
|
||||
if (ub_max_txg < TXG_INITIAL) {
|
||||
(void) fprintf(stderr, "incorrect txg "
|
||||
"specified: %s\n", optarg);
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user