From ef08cb26dae6b3c2e930e66852f13329babb7c2e Mon Sep 17 00:00:00 2001 From: Chunwei Chen Date: Tue, 23 Jul 2024 11:34:19 -0700 Subject: [PATCH] Fix long_free_dirty accounting for small files (#16264) For files smaller than recordsize, it's most likely that they don't have L1 blocks. However, current calculation will always return at least 1 L1 block. In this change, we check dnode level to figure out if it has L1 blocks or not, and return 0 if it doesn't. This will reduce the chance of unnecessary throttling when deleting a large number of small files. Signed-off-by: Chunwei Chen Co-authored-by: Chunwei Chen Reviewed-by: Alexander Motin Reviewed-by: Brian Behlendorf --- module/zfs/dmu.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c index 1d10ceebfb..24c5ab07df 100644 --- a/module/zfs/dmu.c +++ b/module/zfs/dmu.c @@ -815,6 +815,13 @@ get_next_chunk(dnode_t *dn, uint64_t *start, uint64_t minimum, uint64_t *l1blks) ASSERT3U(minimum, <=, *start); + /* dn_nlevels == 1 means we don't have any L1 blocks */ + if (dn->dn_nlevels <= 1) { + *l1blks = 0; + *start = minimum; + return (0); + } + /* * Check if we can free the entire range assuming that all of the * L1 blocks in this range have data. If we can, we use this