]> git.proxmox.com Git - mirror_zfs.git/commitdiff
ddt: compare keys, not entries
authorRob Norris <rob.norris@klarasystems.com>
Fri, 9 Jun 2023 00:14:42 +0000 (10:14 +1000)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 15 Feb 2024 19:45:00 +0000 (11:45 -0800)
We're about to have different kinds of things that we'll compare on key,
so generalise this function to support that.

(It actually worked fine because of the way the casts work out, but it
requires the key to be at the start of the object so the cast through
ddt_entry_t works, and even then it reads strangely for anything that's
not a ddt_entry_t).

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

cmd/zdb/zdb.c
include/sys/ddt.h
module/zfs/ddt.c

index b857e61bd04fad9b9ce746a9ae9012c616f25994..35d71012f77f7636f514af6505dc8cfdc7dec3ea 100644 (file)
@@ -7121,6 +7121,7 @@ dump_block_stats(spa_t *spa)
 }
 
 typedef struct zdb_ddt_entry {
+       /* key must be first for ddt_key_compare */
        ddt_key_t       zdde_key;
        uint64_t        zdde_ref_blocks;
        uint64_t        zdde_ref_lsize;
@@ -7181,7 +7182,7 @@ dump_simulated_ddt(spa_t *spa)
        ddt_histogram_t ddh_total = {{{0}}};
        ddt_stat_t dds_total = {0};
 
-       avl_create(&t, ddt_entry_compare,
+       avl_create(&t, ddt_key_compare,
            sizeof (zdb_ddt_entry_t), offsetof(zdb_ddt_entry_t, zdde_node));
 
        spa_config_enter(spa, SCL_CONFIG, FTAG, RW_READER);
index 2f9ff84b28c077b10718bbf41d7d25b1f73fb1f4..e6bbaa10e9aca4d694a67e4abf1eeb9f55c83600 100644 (file)
@@ -114,6 +114,7 @@ enum ddt_phys_type {
  * In-core ddt entry
  */
 struct ddt_entry {
+       /* key must be first for ddt_key_compare */
        ddt_key_t       dde_key;
        ddt_phys_t      dde_phys[DDT_PHYS_TYPES];
        zio_t           *dde_lead_zio[DDT_PHYS_TYPES];
@@ -230,7 +231,7 @@ extern boolean_t ddt_class_contains(spa_t *spa, enum ddt_class max_class,
 extern ddt_entry_t *ddt_repair_start(ddt_t *ddt, const blkptr_t *bp);
 extern void ddt_repair_done(ddt_t *ddt, ddt_entry_t *dde);
 
-extern int ddt_entry_compare(const void *x1, const void *x2);
+extern int ddt_key_compare(const void *x1, const void *x2);
 
 extern void ddt_create(spa_t *spa);
 extern int ddt_load(spa_t *spa);
index 221e96413886e8d67c163fe5647a2975efb6c2fd..f54a51842ebb41a2391296459c00a793f43b77cb 100644 (file)
@@ -628,7 +628,8 @@ ddt_remove(ddt_t *ddt, ddt_entry_t *dde)
 ddt_entry_t *
 ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add)
 {
-       ddt_entry_t *dde, dde_search;
+       ddt_key_t search;
+       ddt_entry_t *dde;
        enum ddt_type type;
        enum ddt_class class;
        avl_index_t where;
@@ -636,13 +637,13 @@ ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add)
 
        ASSERT(MUTEX_HELD(&ddt->ddt_lock));
 
-       ddt_key_fill(&dde_search.dde_key, bp);
+       ddt_key_fill(&search, bp);
 
-       dde = avl_find(&ddt->ddt_tree, &dde_search, &where);
+       dde = avl_find(&ddt->ddt_tree, &search, &where);
        if (dde == NULL) {
                if (!add)
                        return (NULL);
-               dde = ddt_alloc(&dde_search.dde_key);
+               dde = ddt_alloc(&search);
                avl_insert(&ddt->ddt_tree, dde, where);
        }
 
@@ -713,7 +714,8 @@ ddt_prefetch(spa_t *spa, const blkptr_t *bp)
 }
 
 /*
- * Opaque struct used for ddt_key comparison
+ * Key comparison. Any struct wanting to make use of this function must have
+ * the key as the first element.
  */
 #define        DDT_KEY_CMP_LEN (sizeof (ddt_key_t) / sizeof (uint16_t))
 
@@ -722,12 +724,10 @@ typedef struct ddt_key_cmp {
 } ddt_key_cmp_t;
 
 int
-ddt_entry_compare(const void *x1, const void *x2)
+ddt_key_compare(const void *x1, const void *x2)
 {
-       const ddt_entry_t *dde1 = x1;
-       const ddt_entry_t *dde2 = x2;
-       const ddt_key_cmp_t *k1 = (const ddt_key_cmp_t *)&dde1->dde_key;
-       const ddt_key_cmp_t *k2 = (const ddt_key_cmp_t *)&dde2->dde_key;
+       const ddt_key_cmp_t *k1 = (const ddt_key_cmp_t *)x1;
+       const ddt_key_cmp_t *k2 = (const ddt_key_cmp_t *)x2;
        int32_t cmp = 0;
 
        for (int i = 0; i < DDT_KEY_CMP_LEN; i++) {
@@ -748,9 +748,9 @@ ddt_table_alloc(spa_t *spa, enum zio_checksum c)
        memset(ddt, 0, sizeof (ddt_t));
 
        mutex_init(&ddt->ddt_lock, NULL, MUTEX_DEFAULT, NULL);
-       avl_create(&ddt->ddt_tree, ddt_entry_compare,
+       avl_create(&ddt->ddt_tree, ddt_key_compare,
            sizeof (ddt_entry_t), offsetof(ddt_entry_t, dde_node));
-       avl_create(&ddt->ddt_repair_tree, ddt_entry_compare,
+       avl_create(&ddt->ddt_repair_tree, ddt_key_compare,
            sizeof (ddt_entry_t), offsetof(ddt_entry_t, dde_node));
        ddt->ddt_checksum = c;
        ddt->ddt_spa = spa;