ddt.c revision 837b568b3a2559f8c9b9403f95104271a85d129e
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * CDDL HEADER START
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * The contents of this file are subject to the terms of the
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * Common Development and Distribution License (the "License").
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * You may not use this file except in compliance with the License.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * See the License for the specific language governing permissions
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * and limitations under the License.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * When distributing Covered Code, include this CDDL HEADER in each
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * If applicable, add the following below this CDDL HEADER, with the
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * fields enclosed by brackets "[]" replaced with your own identifying
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * information: Portions Copyright [yyyy] [name of copyright owner]
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * CDDL HEADER END
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
837b568b3a2559f8c9b9403f95104271a85d129eGeorge Wilson * Enable/disable prefetching of dedup-ed blocks which are going to be freed.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickstatic const char *ddt_class_name[DDT_CLASSES] = {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick "duplicate",
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_create(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t *objectp = &ddt->ddt_object[type][class];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick boolean_t prehash = zio_checksum_table[ddt->ddt_checksum].ci_dedup;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(ddt_ops[type]->ddt_op_create(os, objectp, tx, prehash) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(zap_add(os, DMU_POOL_DIRECTORY_OBJECT, name,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(zap_add(os, spa->spa_ddt_stat_object, name,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick sizeof (uint64_t), sizeof (ddt_histogram_t) / sizeof (uint64_t),
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_destroy(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t *objectp = &ddt->ddt_object[type][class];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(ddt_object_count(ddt, type, class) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(ddt_histogram_empty(&ddt->ddt_histogram[type][class]));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(zap_remove(os, DMU_POOL_DIRECTORY_OBJECT, name, tx) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(zap_remove(os, spa->spa_ddt_stat_object, name, tx) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(ddt_ops[type]->ddt_op_destroy(os, *objectp, tx) == 0);
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson bzero(&ddt->ddt_object_stats[type][class], sizeof (ddt_object_t));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_load(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddt_object_t *ddo = &ddt->ddt_object_stats[type][class];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = zap_lookup(ddt->ddt_os, DMU_POOL_DIRECTORY_OBJECT, name,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick sizeof (uint64_t), 1, &ddt->ddt_object[type][class]);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = zap_lookup(ddt->ddt_os, ddt->ddt_spa->spa_ddt_stat_object, name,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick sizeof (uint64_t), sizeof (ddt_histogram_t) / sizeof (uint64_t),
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson * Seed the cached statistics.
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson VERIFY(ddt_object_info(ddt, type, class, &doi) == 0);
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddo->ddo_count = ddt_object_count(ddt, type, class);
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddo->ddo_dspace = doi.doi_physical_blocks_512 << 9;
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddo->ddo_mspace = doi.doi_fill_count * doi.doi_data_block_size;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_sync(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddt_object_t *ddo = &ddt->ddt_object_stats[type][class];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(zap_update(ddt->ddt_os, ddt->ddt_spa->spa_ddt_stat_object, name,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick sizeof (uint64_t), sizeof (ddt_histogram_t) / sizeof (uint64_t),
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson * Cache DDT statistics; this is the only time they'll change.
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson VERIFY(ddt_object_info(ddt, type, class, &doi) == 0);
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddo->ddo_count = ddt_object_count(ddt, type, class);
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddo->ddo_dspace = doi.doi_physical_blocks_512 << 9;
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddo->ddo_mspace = doi.doi_fill_count * doi.doi_data_block_size;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_lookup(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (ddt_ops[type]->ddt_op_lookup(ddt->ddt_os,
c7cd242109c82107ec2e50013369e92be9d77702George Wilsonddt_object_prefetch(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_update(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (ddt_ops[type]->ddt_op_update(ddt->ddt_os,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_remove(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (ddt_ops[type]->ddt_op_remove(ddt->ddt_os,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_walk(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (ddt_ops[type]->ddt_op_walk(ddt->ddt_os,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_count(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (ddt_ops[type]->ddt_op_count(ddt->ddt_os,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_info(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (dmu_object_info(ddt->ddt_os, ddt->ddt_object[type][class],
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_exists(ddt_t *ddt, enum ddt_type type, enum ddt_class class)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_object_name(ddt_t *ddt, enum ddt_type type, enum ddt_class class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ddt_ops[type]->ddt_op_name, ddt_class_name[class]);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_bp_fill(const ddt_phys_t *ddp, blkptr_t *bp, uint64_t txg)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int d = 0; d < SPA_DVAS_PER_BP; d++)
bbfd46c40e81c7d954cec28db66453ec5ab44613Jeff Bonwick const ddt_key_t *ddk, const ddt_phys_t *ddp, blkptr_t *bp)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_key_fill(ddt_key_t *ddk, const blkptr_t *bp)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_phys_fill(ddt_phys_t *ddp, const blkptr_t *bp)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int d = 0; d < SPA_DVAS_PER_BP; d++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_phys_free(ddt_t *ddt, ddt_key_t *ddk, ddt_phys_t *ddp, uint64_t txg)
bbfd46c40e81c7d954cec28db66453ec5ab44613Jeff Bonwick ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_phys_select(const ddt_entry_t *dde, const blkptr_t *bp)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (DVA_EQUAL(BP_IDENTITY(bp), &ddp->ddp_dva[0]) &&
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_stat_generate(ddt_t *ddt, ddt_entry_t *dde, ddt_stat_t *dds)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int d = 0; d < SPA_DVAS_PER_BP; d++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dsize += dva_get_dsize_sync(spa, &ddp->ddp_dva[d]);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_stat_add(ddt_stat_t *dst, const ddt_stat_t *src, uint64_t neg)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(neg == 0 || neg == -1ULL); /* add or subtract */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_stat_update(ddt_t *ddt, ddt_entry_t *dde, uint64_t neg)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ddh = &ddt->ddt_histogram[dde->dde_type][dde->dde_class];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ddt_stat_add(&ddh->ddh_stat[bucket], &dds, neg);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_histogram_add(ddt_histogram_t *dst, const ddt_histogram_t *src)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int h = 0; h < 64; h++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ddt_stat_add(&dst->ddh_stat[h], &src->ddh_stat[h], 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_histogram_stat(ddt_stat_t *dds, const ddt_histogram_t *ddh)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int h = 0; h < 64; h++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick const uint64_t *s_end = (const uint64_t *)(ddh + 1);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (*s++ != 0)
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilsonddt_get_dedup_object_stats(spa_t *spa, ddt_object_t *ddo_total)
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson /* Sum the statistics we cached in ddt_object_sync(). */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum ddt_class class = 0; class < DDT_CLASSES;
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson /* ... and compute the averages. */
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddo_total->ddo_dspace /= ddo_total->ddo_count;
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson ddo_total->ddo_mspace /= ddo_total->ddo_count;
9eb19f4d61679ca0382def038665019234458eddGeorge Wilsonddt_get_dedup_histogram(spa_t *spa, ddt_histogram_t *ddh)
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson for (enum ddt_class class = 0; class < DDT_CLASSES;
9eb19f4d61679ca0382def038665019234458eddGeorge Wilsonddt_get_dedup_stats(spa_t *spa, ddt_stat_t *dds_total)
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson ddh_total = kmem_zalloc(sizeof (ddt_histogram_t), KM_SLEEP);
9eb19f4d61679ca0382def038665019234458eddGeorge Wilson kmem_free(ddh_total, sizeof (ddt_histogram_t));
485bbbf5450c6645352388d798251c1a89ef4c9cGeorge Wilson return (dds_total.dds_ref_dsize - dds_total.dds_dsize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (100);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (dds_total.dds_ref_dsize * 100 / dds_total.dds_dsize);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_ditto_copies_needed(ddt_t *ddt, ddt_entry_t *dde, ddt_phys_t *ddp_willref)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int p = DDT_PHYS_SINGLE; p <= DDT_PHYS_TRIPLE; p++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick uint64_t refcnt = ddp->ddp_refcnt; /* committed refs */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick refcnt += zio->io_parent_count; /* pending refs */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (MAX(desired_copies, total_copies) - total_copies);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ddt_phys_t *ddp = &dde->dde_phys[DDT_PHYS_DITTO];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int d = 0; d < SPA_DVAS_PER_BP; d++, dva++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(copies >= 0 && copies < SPA_DVAS_PER_BP);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_compress(void *src, uchar_t *dst, size_t s_len, size_t d_len)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zio_compress_info_t *ci = &zio_compress_table[cpfunc];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(d_len >= s_len + 1); /* no compression plus version byte */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick c_len = ci->ci_compress(src, dst, s_len, d_len - 1, ci->ci_level);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick *version = (ZFS_HOST_BYTEORDER & DDT_COMPRESS_BYTEORDER_MASK) | cpfunc;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_decompress(uchar_t *src, void *dst, size_t s_len, size_t d_len)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick int cpfunc = version & DDT_COMPRESS_FUNCTION_MASK;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zio_compress_info_t *ci = &zio_compress_table[cpfunc];
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (void) ci->ci_decompress(src, dst, s_len, d_len, ci->ci_level);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if ((version ^ ZFS_HOST_BYTEORDER) & DDT_COMPRESS_BYTEORDER_MASK)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_select_by_checksum(spa_t *spa, enum zio_checksum c)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dde = kmem_zalloc(sizeof (ddt_entry_t), KM_SLEEP);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int p = 0; p < DDT_PHYS_TYPES; p++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dde = avl_find(&ddt->ddt_tree, &dde_search, &where);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (class = 0; class < DDT_CLASSES; class++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = ddt_object_lookup(ddt, type, class, dde);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dde->dde_type = type; /* will be DDT_TYPES if no entry found */
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick dde->dde_class = class; /* will be DDT_CLASSES if no entry found */
837b568b3a2559f8c9b9403f95104271a85d129eGeorge Wilson if (!zfs_dedup_prefetch || bp == NULL || !BP_GET_DEDUP(bp))
c7cd242109c82107ec2e50013369e92be9d77702George Wilson * We remove the DDT once it's empty and only prefetch dedup blocks
c7cd242109c82107ec2e50013369e92be9d77702George Wilson * when there are entries in the DDT. Thus no locking is required
c7cd242109c82107ec2e50013369e92be9d77702George Wilson * as the DDT can't disappear on us.
c7cd242109c82107ec2e50013369e92be9d77702George Wilson for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
c7cd242109c82107ec2e50013369e92be9d77702George Wilson for (enum ddt_class class = 0; class < DDT_CLASSES; class++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_entry_compare(const void *x1, const void *x2)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick const uint64_t *u1 = (const uint64_t *)&dde1->dde_key;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick const uint64_t *u2 = (const uint64_t *)&dde2->dde_key;
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int i = 0; i < DDT_KEY_WORDS; i++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick return (-1);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_table_alloc(spa_t *spa, enum zio_checksum c)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick mutex_init(&ddt->ddt_lock, NULL, MUTEX_DEFAULT, NULL);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick sizeof (ddt_entry_t), offsetof(ddt_entry_t, dde_node));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick avl_create(&ddt->ddt_repair_tree, ddt_entry_compare,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick sizeof (ddt_entry_t), offsetof(ddt_entry_t, dde_node));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(avl_numnodes(&ddt->ddt_repair_tree) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick error = zap_lookup(spa->spa_meta_objset, DMU_POOL_DIRECTORY_OBJECT,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum ddt_class class = 0; class < DDT_CLASSES;
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson * Seed the cached histograms.
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson bcopy(ddt->ddt_histogram, &ddt->ddt_histogram_cache,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
bbfd46c40e81c7d954cec28db66453ec5ab44613Jeff Bonwickddt_class_contains(spa_t *spa, enum ddt_class max_class, const blkptr_t *bp)
bbfd46c40e81c7d954cec28db66453ec5ab44613Jeff Bonwick for (enum ddt_type type = 0; type < DDT_TYPES; type++)
bbfd46c40e81c7d954cec28db66453ec5ab44613Jeff Bonwick for (enum ddt_class class = 0; class <= max_class; class++)
bbfd46c40e81c7d954cec28db66453ec5ab44613Jeff Bonwick if (ddt_object_lookup(ddt, type, class, &dde) == 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_repair_start(ddt_t *ddt, const blkptr_t *bp)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum ddt_class class = 0; class < DDT_CLASSES; class++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * We can only do repair if there are multiple copies
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * of the block. For anything in the UNIQUE class,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick * there's definitely only one copy, so don't even try.
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (dde->dde_repair_data != NULL && spa_writeable(ddt->ddt_spa) &&
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick avl_find(&ddt->ddt_repair_tree, dde, &where) == NULL)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_repair_entry(ddt_t *ddt, ddt_entry_t *dde, ddt_entry_t *rdde, zio_t *rio)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++, rddp++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick bcmp(ddp->ddp_dva, rddp->ddp_dva, sizeof (ddp->ddp_dva)))
bbfd46c40e81c7d954cec28db66453ec5ab44613Jeff Bonwick ddt_bp_create(ddt->ddt_checksum, ddk, ddp, &blk);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick zio_nowait(zio_rewrite(zio, zio->io_spa, 0, &blk,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick rdde->dde_repair_data, DDK_GET_PSIZE(rddk), NULL, NULL,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ZIO_PRIORITY_SYNC_WRITE, ZIO_DDT_CHILD_FLAGS(zio), NULL));
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (rdde = avl_first(t); rdde != NULL; rdde = rdde_next) {
bbfd46c40e81c7d954cec28db66453ec5ab44613Jeff Bonwick ddt_bp_create(ddt->ddt_checksum, &rdde->dde_key, NULL, &blk);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_sync_entry(ddt_t *ddt, ddt_entry_t *dde, dmu_tx_t *tx, uint64_t txg)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (int p = 0; p < DDT_PHYS_TYPES; p++, ddp++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (ddt_ditto_copies_needed(ddt, dde, NULL) == 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick if (dde->dde_phys[DDT_PHYS_DITTO].ddp_phys_birth != 0)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick (otype != ntype || oclass != nclass || total_refcnt == 0)) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(ddt_object_remove(ddt, otype, oclass, dde, tx) == 0);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(ddt_object_lookup(ddt, otype, oclass, dde) == ENOENT);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(ddt_object_update(ddt, ntype, nclass, dde, tx) == 0);
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * If the class changes, the order that we scan this bp
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * changes. If it decreases, we could miss it, so
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * scan it right now. (This covers both class changing
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * while we are doing ddt_walk(), and when we are
3f9d6ad73e45c6823b409f93b0c8d4f62861d2d5Lin Ling * traversing.)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwickddt_sync_table(ddt_t *ddt, dmu_tx_t *tx, uint64_t txg)
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick ASSERT(spa->spa_uberblock.ub_version >= SPA_VERSION_DEDUP);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick spa->spa_ddt_stat_object = zap_create(ddt->ddt_os,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick VERIFY(zap_add(ddt->ddt_os, DMU_POOL_DIRECTORY_OBJECT,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick while ((dde = avl_destroy_nodes(&ddt->ddt_tree, &cookie)) != NULL) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum ddt_class class = 0; class < DDT_CLASSES; class++) {
30f608a433ef7b19cb4981bba0a0f7ccd7c92d03George Wilson bcopy(ddt->ddt_histogram, &ddt->ddt_histogram_cache,
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick tx = dmu_tx_create_assigned(spa->spa_dsl_pool, txg);
b24ab6762772a3f6a89393947930c7fa61306783Jeff Bonwick for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
bbfd46c40e81c7d954cec28db66453ec5ab44613Jeff Bonwickddt_walk(spa_t *spa, ddt_bookmark_t *ddb, ddt_entry_t *dde)