range_tree: Provide more debug details upon unexpected add/remove

Sponsored-by: Klara, Inc.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <alexander.motin@TrueNAS.com>
Signed-off-by: Igor Ostapenko <igor.ostapenko@klarasystems.com>
Closes #17581
This commit is contained in:
Igor Ostapenko
2025-07-31 17:44:42 +03:00
committed by GitHub
parent 2957eabbef
commit cb5e7e097d
13 changed files with 227 additions and 87 deletions
+46 -18
View File
@@ -375,6 +375,16 @@ static metaslab_stats_t metaslab_stats = {
#define METASLABSTAT_BUMP(stat) \
atomic_inc_64(&metaslab_stats.stat.value.ui64);
char *
metaslab_rt_name(metaslab_group_t *mg, metaslab_t *ms, const char *name)
{
return (kmem_asprintf("{spa=%s vdev_guid=%llu ms_id=%llu %s}",
spa_name(mg->mg_vd->vdev_spa),
(u_longlong_t)mg->mg_vd->vdev_guid,
(u_longlong_t)ms->ms_id,
name));
}
static kstat_t *metaslab_ksp;
@@ -2900,30 +2910,43 @@ metaslab_init(metaslab_group_t *mg, uint64_t id, uint64_t object,
zfs_range_seg_type_t type =
metaslab_calculate_range_tree_type(vd, ms, &start, &shift);
ms->ms_allocatable = zfs_range_tree_create(NULL, type, NULL, start,
shift);
ms->ms_allocatable = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME, metaslab_rt_name(mg, ms, "ms_allocatable"));
for (int t = 0; t < TXG_SIZE; t++) {
ms->ms_allocating[t] = zfs_range_tree_create(NULL, type,
NULL, start, shift);
ms->ms_allocating[t] = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME,
metaslab_rt_name(mg, ms, "ms_allocating"));
}
ms->ms_freeing = zfs_range_tree_create(NULL, type, NULL, start, shift);
ms->ms_freed = zfs_range_tree_create(NULL, type, NULL, start, shift);
ms->ms_freeing = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME, metaslab_rt_name(mg, ms, "ms_freeing"));
ms->ms_freed = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME, metaslab_rt_name(mg, ms, "ms_freed"));
for (int t = 0; t < TXG_DEFER_SIZE; t++) {
ms->ms_defer[t] = zfs_range_tree_create(NULL, type, NULL,
start, shift);
ms->ms_defer[t] = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME, metaslab_rt_name(mg, ms, "ms_defer"));
}
ms->ms_checkpointing =
zfs_range_tree_create(NULL, type, NULL, start, shift);
ms->ms_unflushed_allocs =
zfs_range_tree_create(NULL, type, NULL, start, shift);
ms->ms_checkpointing = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME, metaslab_rt_name(mg, ms, "ms_checkpointing"));
ms->ms_unflushed_allocs = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME, metaslab_rt_name(mg, ms, "ms_unflushed_allocs"));
metaslab_rt_arg_t *mrap = kmem_zalloc(sizeof (*mrap), KM_SLEEP);
mrap->mra_bt = &ms->ms_unflushed_frees_by_size;
mrap->mra_floor_shift = metaslab_by_size_min_shift;
ms->ms_unflushed_frees = zfs_range_tree_create(&metaslab_rt_ops,
type, mrap, start, shift);
ms->ms_unflushed_frees = zfs_range_tree_create_flags(
&metaslab_rt_ops, type, mrap, start, shift,
ZFS_RT_F_DYN_NAME, metaslab_rt_name(mg, ms, "ms_unflushed_frees"));
ms->ms_trim = zfs_range_tree_create(NULL, type, NULL, start, shift);
ms->ms_trim = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME, metaslab_rt_name(mg, ms, "ms_trim"));
metaslab_group_add(mg, ms);
metaslab_set_fragmentation(ms, B_FALSE);
@@ -3897,7 +3920,10 @@ metaslab_condense(metaslab_t *msp, dmu_tx_t *tx)
type = metaslab_calculate_range_tree_type(msp->ms_group->mg_vd, msp,
&start, &shift);
condense_tree = zfs_range_tree_create(NULL, type, NULL, start, shift);
condense_tree = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME,
metaslab_rt_name(msp->ms_group, msp, "condense_tree"));
for (int t = 0; t < TXG_DEFER_SIZE; t++) {
zfs_range_tree_walk(msp->ms_defer[t],
@@ -3954,8 +3980,10 @@ metaslab_condense(metaslab_t *msp, dmu_tx_t *tx)
* followed by FREES (due to space_map_write() in metaslab_sync()) for
* sync pass 1.
*/
zfs_range_tree_t *tmp_tree = zfs_range_tree_create(NULL, type, NULL,
start, shift);
zfs_range_tree_t *tmp_tree = zfs_range_tree_create_flags(
NULL, type, NULL, start, shift,
ZFS_RT_F_DYN_NAME,
metaslab_rt_name(msp->ms_group, msp, "tmp_tree"));
zfs_range_tree_add(tmp_tree, msp->ms_start, msp->ms_size);
space_map_write(sm, tmp_tree, SM_ALLOC, SM_NO_VDEVID, tx);
space_map_write(sm, msp->ms_allocatable, SM_FREE, SM_NO_VDEVID, tx);