From 4b56f524c98e7802d77ff91f07887d17c0eff61f Mon Sep 17 00:00:00 2001 From: Chunwei Chen Date: Fri, 14 Jun 2024 00:22:26 +0000 Subject: [PATCH] Fix long_free_dirty accounting for small files 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 --- module/zfs/dmu.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c index 8b440aafba43..0dc6e48b9c85 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