diff --git a/include/sys/ddt.h b/include/sys/ddt.h index 671127154550..5f0d168bd45f 100644 --- a/include/sys/ddt.h +++ b/include/sys/ddt.h @@ -146,6 +146,7 @@ typedef struct { typedef struct { ddt_phys_t ddpf_phys[1]; + uint64_t ddpf_class_birth; } ddt_phys_flat_t; typedef struct { @@ -162,6 +163,9 @@ typedef struct { #define DDT_PHYS_FOR_COPIES(ddt, p) _DDT_PHYS_SWITCH(ddt, 0, p) #define DDT_PHYS_IS_DITTO(ddt, p) _DDT_PHYS_SWITCH(ddt, 0, (p == 0)) +#define DDT_PHYS_FLAT_CLASS_BIRTH(phys) \ + (((ddt_phys_flat_t *)(phys))->ddpf_class_birth) + /* * A "live" entry, holding changes to an entry made this txg, and other data to * support loading, updating and repairing the entry. diff --git a/include/sys/ddt_impl.h b/include/sys/ddt_impl.h index e88a046ab8ae..d8365eb4a4f2 100644 --- a/include/sys/ddt_impl.h +++ b/include/sys/ddt_impl.h @@ -42,14 +42,17 @@ extern "C" { #define DDT_DIR_FLAGS "flags" /* Fill a lightweight entry from a live entry. */ -#define DDT_ENTRY_TO_LIGHTWEIGHT(ddt, dde, ddlwe) do { \ - memset((ddlwe), 0, sizeof (*ddlwe)); \ - (ddlwe)->ddlwe_key = (dde)->dde_key; \ - (ddlwe)->ddlwe_type = (dde)->dde_type; \ - (ddlwe)->ddlwe_class = (dde)->dde_class; \ - (ddlwe)->ddlwe_nphys = DDT_NPHYS(ddt); \ - for (int p = 0; p < (ddlwe)->ddlwe_nphys; p++) \ - (ddlwe)->ddlwe_phys[p] = (dde)->dde_phys[p]; \ +#define DDT_ENTRY_TO_LIGHTWEIGHT(ddt, dde, ddlwe) do { \ + memset((ddlwe), 0, sizeof (*ddlwe)); \ + (ddlwe)->ddlwe_key = (dde)->dde_key; \ + (ddlwe)->ddlwe_type = (dde)->dde_type; \ + (ddlwe)->ddlwe_class = (dde)->dde_class; \ + (ddlwe)->ddlwe_nphys = DDT_NPHYS(ddt); \ + for (int p = 0; p < (ddlwe)->ddlwe_nphys; p++) \ + (ddlwe)->ddlwe_phys[p] = (dde)->dde_phys[p]; \ + if (ddt->ddt_flags & DDT_FLAG_FLAT) \ + DDT_PHYS_FLAT_CLASS_BIRTH(&((ddlwe)->ddlwe_phys[0])) = \ + DDT_PHYS_FLAT_CLASS_BIRTH(&((dde)->dde_phys[0])); \ } while (0) /* diff --git a/module/zfs/ddt.c b/module/zfs/ddt.c index 686b6f23ba24..c54add9ca364 100644 --- a/module/zfs/ddt.c +++ b/module/zfs/ddt.c @@ -849,6 +849,9 @@ ddt_lookup(ddt_t *ddt, const blkptr_t *bp, boolean_t add) /* Time to make a new entry. */ dde = ddt_alloc(ddt, &search); + if (ddt->ddt_flags & DDT_FLAG_FLAT) + DDT_PHYS_FLAT_CLASS_BIRTH(&dde->dde_phys[0]) = + gethrestime_sec(); avl_insert(&ddt->ddt_tree, dde, where); /*