Introduce dedupused/dedupsaved pool properties

Currently there is only a dedup ratio reported via pool properties.
If dedup is enabled only for some datasets, it is impossible to say
how much space the ratio actually covers.  Fix this by introducing
dedupused/dedupsaved pool properties, similar to earlier added
block cloning ones.  Combined with work to expose allocation classes
stats, it should give user-space enough visibility to correlate
`zpool list` and `zfs list` space numbers.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Ryan Moeller <ryan.moeller@klarasystems.com>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #18245
This commit is contained in:
Alexander Motin 2026-02-25 09:41:38 -05:00 committed by GitHub
parent 3408332d71
commit 991fc56fae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 53 additions and 3 deletions

View File

@ -396,6 +396,8 @@ extern void ddt_get_dedup_histogram(spa_t *spa, ddt_histogram_t *ddh);
extern void ddt_get_dedup_stats(spa_t *spa, ddt_stat_t *dds_total);
extern uint64_t ddt_get_dedup_dspace(spa_t *spa);
extern uint64_t ddt_get_dedup_used(spa_t *spa);
extern uint64_t ddt_get_dedup_saved(spa_t *spa);
extern uint64_t ddt_get_pool_dedup_ratio(spa_t *spa);
extern int ddt_get_pool_dedup_cached(spa_t *spa, uint64_t *psize);

View File

@ -273,6 +273,8 @@ typedef enum {
ZPOOL_PROP_DEDUP_TABLE_QUOTA,
ZPOOL_PROP_DEDUPCACHED,
ZPOOL_PROP_LAST_SCRUBBED_TXG,
ZPOOL_PROP_DEDUPUSED,
ZPOOL_PROP_DEDUPSAVED,
ZPOOL_NUM_PROPS
} zpool_prop_t;

View File

@ -3370,7 +3370,9 @@
<enumerator name='ZPOOL_PROP_DEDUP_TABLE_QUOTA' value='37'/>
<enumerator name='ZPOOL_PROP_DEDUPCACHED' value='38'/>
<enumerator name='ZPOOL_PROP_LAST_SCRUBBED_TXG' value='39'/>
<enumerator name='ZPOOL_NUM_PROPS' value='40'/>
<enumerator name='ZPOOL_PROP_DEDUPUSED' value='40'/>
<enumerator name='ZPOOL_PROP_DEDUPSAVED' value='41'/>
<enumerator name='ZPOOL_NUM_PROPS' value='42'/>
</enum-decl>
<typedef-decl name='zpool_prop_t' type-id='af1ba157' id='5d0c23fb'/>
<typedef-decl name='regoff_t' type-id='95e97e5e' id='54a2a2a8'/>

View File

@ -380,6 +380,8 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf,
case ZPOOL_PROP_BCLONESAVED:
case ZPOOL_PROP_BCLONEUSED:
case ZPOOL_PROP_DEDUP_TABLE_SIZE:
case ZPOOL_PROP_DEDUPUSED:
case ZPOOL_PROP_DEDUPSAVED:
case ZPOOL_PROP_DEDUPCACHED:
if (literal)
(void) snprintf(buf, len, "%llu",

View File

@ -80,6 +80,21 @@ See
.Xr zpool-prefetch 8 .
.It Sy dedup_table_size
Total on-disk size of the deduplication table.
.It Sy dedupratio
The ratio of the total amount of storage that would be required to store all
the deduplicated blocks without deduplication to the actual storage used.
The
.Sy dedupratio
property is calculated as:
.Pp
.Sy ( ( dedupsaved + dedupused ) * 100 ) / dedupused
.It Sy dedupsaved
The amount of additional storage that would be required if deduplication
was not used.
This represents the space saved by deduplication.
.It Sy dedupused
The amount of storage used by deduplicated blocks.
This is the actual physical space occupied on disk after deduplication.
.It Sy expandsize
Amount of uninitialized space within the pool or device that can be used to
increase the total capacity of the pool.

View File

@ -117,6 +117,12 @@ zpool_prop_init(void)
zprop_register_number(ZPOOL_PROP_DEDUPRATIO, "dedupratio", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<1.00x or higher if deduped>",
"DEDUP", B_FALSE, sfeatures);
zprop_register_number(ZPOOL_PROP_DEDUPUSED, "dedupused", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<size>",
"DEDUP_USED", B_FALSE, sfeatures);
zprop_register_number(ZPOOL_PROP_DEDUPSAVED, "dedupsaved", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<size>",
"DEDUP_SAVED", B_FALSE, sfeatures);
zprop_register_number(ZPOOL_PROP_BCLONEUSED, "bcloneused", 0,
PROP_READONLY, ZFS_TYPE_POOL, "<size>",
"BCLONE_USED", B_FALSE, sfeatures);

View File

@ -297,6 +297,21 @@ ddt_get_dedup_dspace(spa_t *spa)
return (spa->spa_dedup_dspace);
}
uint64_t
ddt_get_dedup_used(spa_t *spa)
{
ddt_stat_t dds_total = { 0 };
ddt_get_dedup_stats(spa, &dds_total);
return (dds_total.dds_dsize);
}
uint64_t
ddt_get_dedup_saved(spa_t *spa)
{
return (ddt_get_dedup_dspace(spa));
}
uint64_t
ddt_get_pool_dedup_ratio(spa_t *spa)
{

View File

@ -483,6 +483,10 @@ spa_prop_get_config(spa_t *spa, nvlist_t *nv)
spa_prop_add_list(nv, ZPOOL_PROP_DEDUPRATIO, NULL,
ddt_get_pool_dedup_ratio(spa), src);
spa_prop_add_list(nv, ZPOOL_PROP_DEDUPUSED, NULL,
ddt_get_dedup_used(spa), src);
spa_prop_add_list(nv, ZPOOL_PROP_DEDUPSAVED, NULL,
ddt_get_dedup_saved(spa), src);
spa_prop_add_list(nv, ZPOOL_PROP_BCLONEUSED, NULL,
brt_get_used(spa), src);
spa_prop_add_list(nv, ZPOOL_PROP_BCLONESAVED, NULL,

View File

@ -65,6 +65,8 @@ typeset -a properties=(
"bclonesaved"
"bcloneratio"
"last_scrubbed_txg"
"dedupused"
"dedupsaved"
"feature@async_destroy"
"feature@empty_bpobj"
"feature@lz4_compress"

View File

@ -30,5 +30,5 @@
#
# Set the expected properties of zpool
typeset -a properties=("allocated" "capacity" "expandsize" "free" "freeing"
"leaked" "size")
typeset -a properties=("allocated" "bcloneused" "bclonesaved" "capacity"
"dedupused" "dedupsaved" "expandsize" "free" "freeing" "leaked" "size")