diff --git a/include/sys/ddt.h b/include/sys/ddt.h index 8f2cc9c5a..8bdd7ca3a 100644 --- a/include/sys/ddt.h +++ b/include/sys/ddt.h @@ -339,6 +339,8 @@ extern void ddt_bp_create(enum zio_checksum checksum, const ddt_key_t *ddk, extern void ddt_phys_extend(ddt_univ_phys_t *ddp, ddt_phys_variant_t v, const blkptr_t *bp); +extern void ddt_phys_unextend(ddt_univ_phys_t *cur, ddt_univ_phys_t *orig, + ddt_phys_variant_t v); extern void ddt_phys_copy(ddt_univ_phys_t *dst, const ddt_univ_phys_t *src, ddt_phys_variant_t v); extern void ddt_phys_clear(ddt_univ_phys_t *ddp, ddt_phys_variant_t v); diff --git a/module/zfs/ddt.c b/module/zfs/ddt.c index ec577fff6..b0cd7f089 100644 --- a/module/zfs/ddt.c +++ b/module/zfs/ddt.c @@ -731,6 +731,27 @@ ddt_phys_extend(ddt_univ_phys_t *ddp, ddt_phys_variant_t v, const blkptr_t *bp) } } +void +ddt_phys_unextend(ddt_univ_phys_t *cur, ddt_univ_phys_t *orig, + ddt_phys_variant_t v) +{ + ASSERT3U(v, <, DDT_PHYS_NONE); + dva_t *cur_dvas = (v == DDT_PHYS_FLAT) ? + cur->ddp_flat.ddp_dva : cur->ddp_trad[v].ddp_dva; + dva_t *orig_dvas = (v == DDT_PHYS_FLAT) ? + orig->ddp_flat.ddp_dva : orig->ddp_trad[v].ddp_dva; + + for (int d = 0; d < SPA_DVAS_PER_BP; d++) + cur_dvas[d] = orig_dvas[d]; + + if (ddt_phys_birth(orig, v) == 0) { + if (v == DDT_PHYS_FLAT) + cur->ddp_flat.ddp_phys_birth = 0; + else + cur->ddp_trad[v].ddp_phys_birth = 0; + } +} + void ddt_phys_copy(ddt_univ_phys_t *dst, const ddt_univ_phys_t *src, ddt_phys_variant_t v) diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 5d39d28a7..47f229dcb 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -3607,7 +3607,7 @@ zio_ddt_child_write_done(zio_t *zio) * chain. We need to revert the entry back to what it was at * the last time it was successfully extended. */ - ddt_phys_copy(ddp, orig, v); + ddt_phys_unextend(ddp, orig, v); ddt_phys_clear(orig, v); ddt_exit(ddt);