summaryrefslogtreecommitdiffstats
path: root/module/zfs/space_map.c
diff options
context:
space:
mode:
authorMatthew Ahrens <[email protected]>2018-01-11 08:54:38 -0800
committerBrian Behlendorf <[email protected]>2018-07-25 14:11:35 -0700
commit3a549dc7a1f5e5511b4c8699081f704eeb4381b7 (patch)
tree257c2d2bedb78cef825d598980235422a8d991bb /module/zfs/space_map.c
parente106a7bacbf6a642a07ecaecc82ef2c45c458865 (diff)
OpenZFS 9442 - decrease indirect block size of spacemaps
Authored by: Matthew Ahrens <[email protected]> Reviewed by: Serapheim Dimitropoulos <[email protected]> Reviewed by: George Wilson <[email protected]> Reviewed by: Albert Lee <[email protected]> Reviewed by: Igor Kozhukhov <[email protected]> Reviewed by: George Melikov <[email protected]> Approved by: Dan McDonald <[email protected]> Ported-by: Brian Behlendorf <[email protected]> Updates to indirect blocks of spacemaps can contribute significantly to write inflation. Therefore we want to reduce the indirect block size of spacemaps from 128K to 16K. Porting notes: * Refactored to allow the dmu_object_alloc(), dmu_object_alloc_ibs() and dmu_object_alloc_dnsize() functions to use a common shared dmu_object_alloc_impl() function. OpenZFS-issue: https://www.illumos.org/issues/9442 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/0c2e6408b Closes #7712
Diffstat (limited to 'module/zfs/space_map.c')
-rw-r--r--module/zfs/space_map.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/module/zfs/space_map.c b/module/zfs/space_map.c
index 5f67a7987..9ba6ff6ff 100644
--- a/module/zfs/space_map.c
+++ b/module/zfs/space_map.c
@@ -52,6 +52,14 @@
*/
boolean_t zfs_force_some_double_word_sm_entries = B_FALSE;
+/*
+ * Override the default indirect block size of 128K, instead use 16K for
+ * spacemaps (2^14 bytes). This dramatically reduces write inflation since
+ * appending to a spacemap typically has to write one data block (4KB) and one
+ * or two indirect blocks (16K-32K, rather than 128K).
+ */
+int space_map_ibs = 14;
+
boolean_t
sm_entry_is_debug(uint64_t e)
{
@@ -674,8 +682,8 @@ space_map_write_impl(space_map_t *sm, range_tree_t *rt, maptype_t maptype,
*
* [1] The feature is enabled.
* [2] The offset or run is too big for a single-word entry,
- * or the vdev_id is set (meaning not equal to
- * SM_NO_VDEVID).
+ * or the vdev_id is set (meaning not equal to
+ * SM_NO_VDEVID).
*
* Note that for purposes of testing we've added the case that
* we write two-word entries occasionally when the feature is
@@ -837,7 +845,8 @@ space_map_truncate(space_map_t *sm, int blocksize, dmu_tx_t *tx)
*/
if ((spa_feature_is_enabled(spa, SPA_FEATURE_SPACEMAP_HISTOGRAM) &&
doi.doi_bonus_size != sizeof (space_map_phys_t)) ||
- doi.doi_data_block_size != blocksize) {
+ doi.doi_data_block_size != blocksize ||
+ doi.doi_metadata_block_size != 1 << space_map_ibs) {
zfs_dbgmsg("txg %llu, spa %s, sm %p, reallocating "
"object[%llu]: old bonus %u, old blocksz %u",
dmu_tx_get_txg(tx), spa_name(spa), sm, sm->sm_object,
@@ -893,8 +902,8 @@ space_map_alloc(objset_t *os, int blocksize, dmu_tx_t *tx)
bonuslen = SPACE_MAP_SIZE_V0;
}
- object = dmu_object_alloc(os, DMU_OT_SPACE_MAP, blocksize,
- DMU_OT_SPACE_MAP_HEADER, bonuslen, tx);
+ object = dmu_object_alloc_ibs(os, DMU_OT_SPACE_MAP, blocksize,
+ space_map_ibs, DMU_OT_SPACE_MAP_HEADER, bonuslen, tx);
return (object);
}