Skip to content

Commit 6b058ec

Browse files
committed
zdb: better handling for corrupt block pointers
When dumping indirect blocks, attempt to print corrupt block pointers rather than abort the program. Sponsored by: ConnectWise Signed-off-by: Alan Somers <[email protected]>
1 parent 3862ebb commit 6b058ec

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

cmd/zdb/zdb.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,19 +2582,29 @@ snprintf_blkptr_compact(char *blkbuf, size_t buflen, const blkptr_t *bp,
25822582
}
25832583
}
25842584

2585-
static void
2585+
static u_longlong_t
25862586
print_indirect(spa_t *spa, blkptr_t *bp, const zbookmark_phys_t *zb,
25872587
const dnode_phys_t *dnp)
25882588
{
25892589
char blkbuf[BP_SPRINTF_LEN];
2590+
u_longlong_t offset;
25902591
int l;
25912592

2593+
offset = (u_longlong_t)blkid2offset(dnp, bp, zb);
25922594
if (!BP_IS_EMBEDDED(bp)) {
2593-
ASSERT3U(BP_GET_TYPE(bp), ==, dnp->dn_type);
2594-
ASSERT3U(BP_GET_LEVEL(bp), ==, zb->zb_level);
2595+
if (BP_GET_TYPE(bp) != dnp->dn_type) {
2596+
(void) fprintf(stderr, "%16llx: Block pointer type "
2597+
"(%llu) does not match dnode type (%hhu)\n",
2598+
offset, BP_GET_TYPE(bp), dnp->dn_type);
2599+
}
2600+
if (BP_GET_LEVEL(bp) != zb->zb_level) {
2601+
(void) fprintf(stderr, "%16llx: Block pointer level "
2602+
"(%llu) does not match bookmark level (%ld)\n",
2603+
offset, BP_GET_LEVEL(bp), zb->zb_level);
2604+
}
25952605
}
25962606

2597-
(void) printf("%16llx ", (u_longlong_t)blkid2offset(dnp, bp, zb));
2607+
(void) printf("%16llx ", offset);
25982608

25992609
ASSERT(zb->zb_level >= 0);
26002610

@@ -2610,18 +2620,21 @@ print_indirect(spa_t *spa, blkptr_t *bp, const zbookmark_phys_t *zb,
26102620
if (dump_opt['Z'] && BP_GET_COMPRESS(bp) == ZIO_COMPRESS_ZSTD)
26112621
snprintf_zstd_header(spa, blkbuf, sizeof (blkbuf), bp);
26122622
(void) printf("%s\n", blkbuf);
2623+
2624+
return (offset);
26132625
}
26142626

26152627
static int
26162628
visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
26172629
blkptr_t *bp, const zbookmark_phys_t *zb)
26182630
{
2631+
u_longlong_t offset;
26192632
int err = 0;
26202633

26212634
if (BP_GET_LOGICAL_BIRTH(bp) == 0)
26222635
return (0);
26232636

2624-
print_indirect(spa, bp, zb, dnp);
2637+
offset = print_indirect(spa, bp, zb, dnp);
26252638

26262639
if (BP_GET_LEVEL(bp) > 0 && !BP_IS_HOLE(bp)) {
26272640
arc_flags_t flags = ARC_FLAG_WAIT;
@@ -2651,8 +2664,14 @@ visit_indirect(spa_t *spa, const dnode_phys_t *dnp,
26512664
break;
26522665
fill += BP_GET_FILL(cbp);
26532666
}
2654-
if (!err)
2655-
ASSERT3U(fill, ==, BP_GET_FILL(bp));
2667+
if (!err) {
2668+
if (fill != BP_GET_FILL(bp)) {
2669+
(void)fprintf(stderr, "%16llx: Block pointer "
2670+
"fill (%llu) does not match calculated "
2671+
"value (%lu)\n", offset, BP_GET_FILL(bp),
2672+
fill);
2673+
}
2674+
}
26562675
arc_buf_destroy(buf, &buf);
26572676
}
26582677

0 commit comments

Comments
 (0)