diff --git a/include/sys/ddt.h b/include/sys/ddt.h index 9c34d8699..d2fef16c9 100644 --- a/include/sys/ddt.h +++ b/include/sys/ddt.h @@ -342,6 +342,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 e0a6abea3..de35f748f 100644 --- a/module/zfs/ddt.c +++ b/module/zfs/ddt.c @@ -711,6 +711,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 1ff16d7ea..f0328e84e 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -3636,7 +3636,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);