]> git.proxmox.com Git - mirror_zfs.git/commitdiff
ddt: ensure ddt objects exist before trying to get stats from them
authorRob Norris <rob.norris@klarasystems.com>
Thu, 15 Jun 2023 06:10:00 +0000 (16:10 +1000)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 15 Feb 2024 19:45:33 +0000 (11:45 -0800)
ddt_get_dedup_histogram() was actually checking it, just in an extremely
cursed way. ddt_get_dedup_object_stats() wasn't, but wasn't being called
from a dangerous place so no one noticed.

These checks are necessary, because spa_ddt[] is not populated until
spa_load(), but the spa can exist before that, while being created, and
as vdevs and metaslabs are initialised the space accounting functions
will be called to update pool space counts.

Probably the whole create path doesn't need to go asking for space
accounting from metadata subsystems until after the pool is created.
This will at least catch misuse.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Sponsored-by: Klara, Inc.
Sponsored-by: iXsystems, Inc.
Closes #15887

module/zfs/ddt_stats.c

index 4ef6c3a07e3beb0fc53d07ebfeb18530a0f68c38..af5365a1d1140f1f1cf646bda5aaff4c6e4ba903 100644 (file)
@@ -132,6 +132,9 @@ ddt_get_dedup_object_stats(spa_t *spa, ddt_object_t *ddo_total)
        /* Sum the statistics we cached in ddt_object_sync(). */
        for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
                ddt_t *ddt = spa->spa_ddt[c];
+               if (!ddt)
+                       continue;
+
                for (ddt_type_t type = 0; type < DDT_TYPES; type++) {
                        for (ddt_class_t class = 0; class < DDT_CLASSES;
                            class++) {
@@ -156,7 +159,10 @@ ddt_get_dedup_histogram(spa_t *spa, ddt_histogram_t *ddh)
 {
        for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
                ddt_t *ddt = spa->spa_ddt[c];
-               for (ddt_type_t type = 0; type < DDT_TYPES && ddt; type++) {
+               if (!ddt)
+                       continue;
+
+               for (ddt_type_t type = 0; type < DDT_TYPES; type++) {
                        for (ddt_class_t class = 0; class < DDT_CLASSES;
                            class++) {
                                ddt_histogram_add(ddh,