mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-29 20:04:57 +01:00
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:
1 parent
d98fa72ca0
commit
bd2d87399c
1 file changed
+36
-21
+36
-21
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user