linux/kstat: replace existing kstat if name is reused

Previously, if a kstat proc name already existed, the old one would be
kept. This makes it so the old one is discarded and the new one kept.

Arguably, a collision like this shouldn't ever happen, but during
import multiple vdev_t (and so vdev_queue_t, and so vdev_queue stats)
can exist at the same time for the same guid. There's no real way to
tell which is which without substantial refactoring in the import and
vdev init codepaths, whch is probably worthwhile but not for today.

Sponsored-by: Klara, Inc.
Sponsored-by: Syneto
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
This commit is contained in:
Rob Norris 2024-05-15 12:46:22 +10:00 committed by Rob Norris
parent 0dd0a2d302
commit e31ed02433
1 changed files with 12 additions and 4 deletions

View File

@ -667,12 +667,20 @@ kstat_proc_entry_install(kstat_proc_entry_t *kpep, mode_t mode,
}
/*
* Only one entry by this name per-module, on failure the module
* shouldn't be deleted because we know it has at least one entry.
* We can only have one entry of this name per module. If one already
* exists, replace it by first removing the proc entry, then removing
* it from the list. The kstat itself lives on; it just can't be
* inspected through the filesystem.
*/
list_for_each_entry(tmp, &module->ksm_kstat_list, kpe_list) {
if (strncmp(tmp->kpe_name, kpep->kpe_name, KSTAT_STRLEN) == 0)
goto out;
if (tmp->kpe_proc != NULL &&
strncmp(tmp->kpe_name, kpep->kpe_name, KSTAT_STRLEN) == 0) {
ASSERT3P(tmp->kpe_owner, ==, module);
remove_proc_entry(tmp->kpe_name, module->ksm_proc);
tmp->kpe_proc = NULL;
list_del_init(&tmp->kpe_list);
break;
}
}
list_add_tail(&kpep->kpe_list, &module->ksm_kstat_list);