Skip to content

Commit 4bf6d0e

Browse files
author
Paul Dagnelie
committed
Fix FDT rollback to not overwrite unnecessary fields
When a dedup write fails, we try to roll the DDT entry back to a known good state. However, this also rolls the refcounts and the last-update time back to the state they were at when we started this write. This doesn't appear to be able to cause any refcount leaks (after the fix in 13172). This PR prevents that from happening by only rolling back the parts of the DDT entry that have been updated by the write so far. Signed-off-by: Paul Dagnelie <[email protected]> Sponsored-by: iXsystems, Inc. Sponsored-by: Klara, Inc.
1 parent 75e921d commit 4bf6d0e

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

include/sys/ddt.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ extern void ddt_bp_create(enum zio_checksum checksum, const ddt_key_t *ddk,
339339

340340
extern void ddt_phys_extend(ddt_univ_phys_t *ddp, ddt_phys_variant_t v,
341341
const blkptr_t *bp);
342+
extern void ddt_phys_unextend(ddt_univ_phys_t *cur, ddt_univ_phys_t *orig,
343+
ddt_phys_variant_t v);
342344
extern void ddt_phys_copy(ddt_univ_phys_t *dst, const ddt_univ_phys_t *src,
343345
ddt_phys_variant_t v);
344346
extern void ddt_phys_clear(ddt_univ_phys_t *ddp, ddt_phys_variant_t v);

module/zfs/ddt.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,27 @@ ddt_phys_extend(ddt_univ_phys_t *ddp, ddt_phys_variant_t v, const blkptr_t *bp)
731731
}
732732
}
733733

734+
void
735+
ddt_phys_unextend(ddt_univ_phys_t *cur, ddt_univ_phys_t *orig,
736+
ddt_phys_variant_t v)
737+
{
738+
ASSERT3U(v, <, DDT_PHYS_NONE);
739+
dva_t *cur_dvas = (v == DDT_PHYS_FLAT) ?
740+
cur->ddp_flat.ddp_dva : cur->ddp_trad[v].ddp_dva;
741+
dva_t *orig_dvas = (v == DDT_PHYS_FLAT) ?
742+
orig->ddp_flat.ddp_dva : orig->ddp_trad[v].ddp_dva;
743+
744+
for (int d = 0; d < SPA_DVAS_PER_BP; d++)
745+
cur_dvas[d] = orig_dvas[d];
746+
747+
if (ddt_phys_birth(orig, v) == 0) {
748+
if (v == DDT_PHYS_FLAT)
749+
cur->ddp_flat.ddp_phys_birth = 0;
750+
else
751+
cur->ddp_trad[v].ddp_phys_birth = 0;
752+
}
753+
}
754+
734755
void
735756
ddt_phys_copy(ddt_univ_phys_t *dst, const ddt_univ_phys_t *src,
736757
ddt_phys_variant_t v)

module/zfs/zio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3607,7 +3607,7 @@ zio_ddt_child_write_done(zio_t *zio)
36073607
* chain. We need to revert the entry back to what it was at
36083608
* the last time it was successfully extended.
36093609
*/
3610-
ddt_phys_copy(ddp, orig, v);
3610+
ddt_phys_unextend(ddp, orig, v);
36113611
ddt_phys_clear(orig, v);
36123612

36133613
ddt_exit(ddt);

0 commit comments

Comments
 (0)