Fix available space accounting for special/dedup (#18222)

Currently, spa_dspace (base to calculate dataset AVAIL) only includes
the normal allocation class capacity, but dd_used_bytes tracks space
allocated across all classes.  Since we don't want to report free
space of other classes as available (we can't promise new allocations
will be able to use it), report only allocated space, similar to how
we report space saved by dedup and block cloning.

Since we need deflated space here, make allocation classes track
deflated allocated space also.  While here, make mc_deferred also
deflated, matching its use contexts.  Also while there, use
atomic_load() to read the allocation class stats.

Reviewed-by: Rob Norris <robn@despairlabs.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Alexander Motin <alexander.motin@TrueNAS.com>
Closes #18190
Closes #18222
This commit is contained in:
Alexander Motin
2026-02-19 13:36:35 -05:00
committed by GitHub
parent 640a217faf
commit d06a1d9ac3
6 changed files with 60 additions and 36 deletions
+2 -2
View File
@@ -117,12 +117,12 @@ boolean_t metaslab_class_throttle_unreserve(metaslab_class_t *, int, int,
void metaslab_class_evict_old(metaslab_class_t *, uint64_t);
const char *metaslab_class_get_name(metaslab_class_t *);
uint64_t metaslab_class_get_alloc(metaslab_class_t *);
uint64_t metaslab_class_get_dalloc(metaslab_class_t *);
uint64_t metaslab_class_get_space(metaslab_class_t *);
uint64_t metaslab_class_get_dspace(metaslab_class_t *);
uint64_t metaslab_class_get_deferred(metaslab_class_t *);
void metaslab_space_update(vdev_t *, metaslab_class_t *,
int64_t, int64_t, int64_t);
void metaslab_space_update(metaslab_group_t *, int64_t, int64_t, int64_t);
metaslab_group_t *metaslab_group_create(metaslab_class_t *, vdev_t *);
void metaslab_group_destroy(metaslab_group_t *);
+5 -3
View File
@@ -199,10 +199,12 @@ struct metaslab_class {
uint64_t mc_alloc_groups; /* # of allocatable groups */
uint64_t mc_alloc; /* total allocated space */
uint64_t mc_deferred; /* total deferred frees */
uint64_t mc_alloc; /* allocated space */
uint64_t mc_dalloc; /* deflated allocated space */
uint64_t mc_deferred; /* deferred frees */
uint64_t mc_ddeferred; /* deflated deferred frees */
uint64_t mc_space; /* total space (alloc + free) */
uint64_t mc_dspace; /* total deflated space */
uint64_t mc_dspace; /* deflated total space */
uint64_t mc_histogram[ZFS_RANGE_TREE_HISTOGRAM_SIZE];
/*