From a4b21eadec9a185a222a5e8a12d19d31e0e32b07 Mon Sep 17 00:00:00 2001 From: Mateusz Piotrowski <0mp@FreeBSD.org> Date: Tue, 10 Jan 2023 22:41:54 +0100 Subject: [PATCH] Add tunable to allow changing micro ZAP's max size This change turns `MZAP_MAX_BLKSZ` into a `ZFS_MODULE_PARAM()` called `zap_micro_max_size`. As a result, we can experiment with different micro ZAP sizes to improve directory size scaling. Reviewed-by: Brian Behlendorf Co-authored-by: Mateusz Piotrowski Co-authored-by: Toomas Soome Signed-off-by: Mateusz Piotrowski Sponsored-by: Wasabi Technology, Inc. Closes #14292 --- man/man4/zfs.4 | 6 +++++- module/zfs/dmu_tx.c | 3 ++- module/zfs/zap_micro.c | 8 +++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/man/man4/zfs.4 b/man/man4/zfs.4 index f788e645c411..efdd10409e2b 100644 --- a/man/man4/zfs.4 +++ b/man/man4/zfs.4 @@ -15,7 +15,7 @@ .\" own identifying information: .\" Portions Copyright [yyyy] [name of copyright owner] .\" -.Dd November 9, 2022 +.Dd December 21, 2022 .Dt ZFS 4 .Os . @@ -496,6 +496,10 @@ prefetch the entire object (all leaf blocks). However, this is limited by .Sy dmu_prefetch_max . . +.It Sy zap_micro_max_size Ns = Ns Sy 131072 Ns B Po 128 KiB Pc Pq int +Maximum micro ZAP size. +A micro ZAP is upgraded to a fat ZAP, once it grows beyond the specified size. +. .It Sy zfetch_array_rd_sz Ns = Ns Sy 1048576 Ns B Po 1 MiB Pc Pq u64 If prefetching is enabled, disable prefetching for reads larger than this size. . diff --git a/module/zfs/dmu_tx.c b/module/zfs/dmu_tx.c index a7a554691a78..815e27a6c7f7 100644 --- a/module/zfs/dmu_tx.c +++ b/module/zfs/dmu_tx.c @@ -465,6 +465,7 @@ dmu_tx_hold_zap_impl(dmu_tx_hold_t *txh, const char *name) dmu_tx_t *tx = txh->txh_tx; dnode_t *dn = txh->txh_dnode; int err; + extern int zap_micro_max_size; ASSERT(tx->tx_txg == 0); @@ -480,7 +481,7 @@ dmu_tx_hold_zap_impl(dmu_tx_hold_t *txh, const char *name) * - 2 grown ptrtbl blocks */ (void) zfs_refcount_add_many(&txh->txh_space_towrite, - MZAP_MAX_BLKSZ, FTAG); + zap_micro_max_size, FTAG); if (dn == NULL) return; diff --git a/module/zfs/zap_micro.c b/module/zfs/zap_micro.c index 606f426404cc..d6ad8b2b8bc5 100644 --- a/module/zfs/zap_micro.c +++ b/module/zfs/zap_micro.c @@ -41,6 +41,8 @@ #include #endif +int zap_micro_max_size = MZAP_MAX_BLKSZ; + static int mzap_upgrade(zap_t **zapp, const void *tag, dmu_tx_t *tx, zap_flags_t flags); @@ -568,7 +570,7 @@ zap_lockdir_impl(dmu_buf_t *db, const void *tag, dmu_tx_t *tx, if (zap->zap_ismicro && tx && adding && zap->zap_m.zap_num_entries == zap->zap_m.zap_num_chunks) { uint64_t newsz = db->db_size + SPA_MINBLOCKSIZE; - if (newsz > MZAP_MAX_BLKSZ) { + if (newsz > zap_micro_max_size) { dprintf("upgrading obj %llu: num_entries=%u\n", (u_longlong_t)obj, zap->zap_m.zap_num_entries); *zapp = zap; @@ -1724,4 +1726,8 @@ EXPORT_SYMBOL(zap_cursor_advance); EXPORT_SYMBOL(zap_cursor_serialize); EXPORT_SYMBOL(zap_cursor_init_serialized); EXPORT_SYMBOL(zap_get_stats); + +/* CSTYLED */ +ZFS_MODULE_PARAM(zfs, , zap_micro_max_size, INT, ZMOD_RW, + "Maximum micro ZAP size, before converting to a fat ZAP, in bytes"); #endif