zdb: output refcounts from verify_spacemap_refcounts()

Output information about refcounts when there is refcount mismatch.
Use plain uint64_t even as the values are expected to not be large. 
Also use unsigned as we should never get negative refcounts there.

Reviewed-by: Allan Jude <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Alexander Motin <[email protected]>
Signed-off-by: Toomas Soome <[email protected]>
Closes #18809
This commit is contained in:
Toomas Soome authored and GitHub committed 2026-07-22 09:47:03 -07:00
1 parent d98fa72ca0
commit bd2d87399c
1 file changed
+36 -21
+36 -21
View File
@@ -37,6 +37,7 @@
* Copyright (c) 2023, 2024, Klara Inc.
* Copyright (c) 2023, Rob Norris <robn@despairlabs.com>
* Copyright (c) 2026, TrueNAS.
* Copyright 2026 Edgecast Cloud LLC.
*/
#include <stdio.h>
@@ -1447,10 +1448,10 @@ dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
zap_attribute_free(attrp);
}
static int
static uint64_t
get_dtl_refcount(vdev_t *vd)
{
int refcount = 0;
uint64_t refcount = 0;
if (vd->vdev_ops->vdev_op_leaf) {
space_map_t *sm = vd->vdev_dtl_sm;
@@ -1466,10 +1467,10 @@ get_dtl_refcount(vdev_t *vd)
return (refcount);
}
static int
static uint64_t
get_metaslab_refcount(vdev_t *vd)
{
int refcount = 0;
uint64_t refcount = 0;
if (vd->vdev_top == vd) {
for (uint64_t m = 0; m < vd->vdev_ms_count; m++) {
@@ -1486,11 +1487,11 @@ get_metaslab_refcount(vdev_t *vd)
return (refcount);
}
static int
static uint64_t
get_obsolete_refcount(vdev_t *vd)
{
uint64_t obsolete_sm_object;
int refcount = 0;
uint64_t refcount = 0;
VERIFY0(vdev_obsolete_sm_object(vd, &obsolete_sm_object));
if (vd->vdev_top == vd && obsolete_sm_object != 0) {
@@ -1511,7 +1512,7 @@ get_obsolete_refcount(vdev_t *vd)
return (refcount);
}
static int
static uint64_t
get_prev_obsolete_spacemap_refcount(spa_t *spa)
{
uint64_t prev_obj =
@@ -1526,10 +1527,10 @@ get_prev_obsolete_spacemap_refcount(spa_t *spa)
return (0);
}
static int
static uint64_t
get_checkpoint_refcount(vdev_t *vd)
{
int refcount = 0;
uint64_t refcount = 0;
if (vd->vdev_top == vd && vd->vdev_top_zap != 0 &&
zap_contains(spa_meta_objset(vd->vdev_spa),
@@ -1542,7 +1543,7 @@ get_checkpoint_refcount(vdev_t *vd)
return (refcount);
}
static int
static uint64_t
get_log_spacemap_refcount(spa_t *spa)
{
return (avl_numnodes(&spa->spa_sm_logs_by_txg));
@@ -1552,23 +1553,37 @@ static int
verify_spacemap_refcounts(spa_t *spa)
{
uint64_t expected_refcount = 0;
uint64_t actual_refcount;
uint64_t actual_refcount = 0;
uint64_t dtl_refcount, metaslab_refcount, obsolete_refcount,
prev_obsolete_refcount, checkpoint_refcount, log_spacemap_refcount;
(void) feature_get_refcount(spa,
&spa_feature_table[SPA_FEATURE_SPACEMAP_HISTOGRAM],
&expected_refcount);
actual_refcount = get_dtl_refcount(spa->spa_root_vdev);
actual_refcount += get_metaslab_refcount(spa->spa_root_vdev);
actual_refcount += get_obsolete_refcount(spa->spa_root_vdev);
actual_refcount += get_prev_obsolete_spacemap_refcount(spa);
actual_refcount += get_checkpoint_refcount(spa->spa_root_vdev);
actual_refcount += get_log_spacemap_refcount(spa);
dtl_refcount = get_dtl_refcount(spa->spa_root_vdev);
metaslab_refcount = get_metaslab_refcount(spa->spa_root_vdev);
obsolete_refcount = get_obsolete_refcount(spa->spa_root_vdev);
prev_obsolete_refcount = get_prev_obsolete_spacemap_refcount(spa);
checkpoint_refcount = get_checkpoint_refcount(spa->spa_root_vdev);
log_spacemap_refcount = get_log_spacemap_refcount(spa);
actual_refcount = dtl_refcount + metaslab_refcount +
obsolete_refcount + prev_obsolete_refcount +
checkpoint_refcount + log_spacemap_refcount;
if (expected_refcount != actual_refcount) {
(void) printf("space map refcount mismatch: expected %lld != "
"actual %lld\n",
(longlong_t)expected_refcount,
(longlong_t)actual_refcount);
(void) printf("space map refcount mismatch: expected %llu != "
"actual %llu\n",
(u_longlong_t)expected_refcount,
(u_longlong_t)actual_refcount);
(void) printf("\tDTL: %llu, metaslab: %llu, obsolete: %llu, "
"prev obsolete: %llu, checkpoint: %llu, "
"log spacemap: %llu\n",
(u_longlong_t)dtl_refcount,
(u_longlong_t)metaslab_refcount,
(u_longlong_t)obsolete_refcount,
(u_longlong_t)prev_obsolete_refcount,
(u_longlong_t)checkpoint_refcount,
(u_longlong_t)log_spacemap_refcount);
return (2);
}
return (0);