summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Ercolani <214141+rincebrain@users.noreply.github.com>2021-07-13 11:47:57 -0400
committerTony Hutter <hutter2@llnl.gov>2021-09-22 15:19:08 -0700
commitccf6d0a59bf8ac33b1a4f7df1f88e99a9554d978 (patch)
treebd04240b8e07c47ebde3a90b5e6d925c66cccc0a
parent61ae6c99f711a0e64779ac85ffbeaf50f920a7cc (diff)
Tinker with slop space accounting with dedup
* Tinker with slop space accounting with dedup Do not include the deduplicated space usage in the slop space reservation, it leads to surprising outcomes. * Update spa_dedup_dspace sometimes Sometimes, we get into spa_get_slop_space() with spa_dedup_dspace=~0ULL, AKA "unset", while spa_dspace is correctly set. So call the code to update it before we use it if we hit that case. Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: Mark Maybee <mark.maybee@delphix.com> Signed-off-by: Rich Ercolani <rincebrain@gmail.com> Closes #12271
-rw-r--r--module/zfs/ddt.c2
-rw-r--r--module/zfs/spa_misc.c18
2 files changed, 17 insertions, 3 deletions
diff --git a/module/zfs/ddt.c b/module/zfs/ddt.c
index b94a9f54e..35c0f2da9 100644
--- a/module/zfs/ddt.c
+++ b/module/zfs/ddt.c
@@ -503,7 +503,7 @@ ddt_get_dedup_histogram(spa_t *spa, ddt_histogram_t *ddh)
{
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
ddt_t *ddt = spa->spa_ddt[c];
- for (enum ddt_type type = 0; type < DDT_TYPES; type++) {
+ for (enum ddt_type type = 0; type < DDT_TYPES && ddt; type++) {
for (enum ddt_class class = 0; class < DDT_CLASSES;
class++) {
ddt_histogram_add(ddh,
diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c
index eff8c716d..25502f769 100644
--- a/module/zfs/spa_misc.c
+++ b/module/zfs/spa_misc.c
@@ -1789,8 +1789,22 @@ spa_get_worst_case_asize(spa_t *spa, uint64_t lsize)
uint64_t
spa_get_slop_space(spa_t *spa)
{
- uint64_t space = spa_get_dspace(spa);
- uint64_t slop = MIN(space >> spa_slop_shift, spa_max_slop);
+ uint64_t space = 0;
+ uint64_t slop = 0;
+
+ /*
+ * Make sure spa_dedup_dspace has been set.
+ */
+ if (spa->spa_dedup_dspace == ~0ULL)
+ spa_update_dspace(spa);
+
+ /*
+ * spa_get_dspace() includes the space only logically "used" by
+ * deduplicated data, so since it's not useful to reserve more
+ * space with more deduplicated data, we subtract that out here.
+ */
+ space = spa_get_dspace(spa) - spa->spa_dedup_dspace;
+ slop = MIN(space >> spa_slop_shift, spa_max_slop);
/*
* Slop space should be at least spa_min_slop, but no more than half