From c6886cf610f4bb0b8aa6b88ab013a042e317f898 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 5 Nov 2025 14:52:14 -0500 Subject: [PATCH] block: don't leak disk->zones_cond for !disk_need_zone_resources disk->zones_cond is allocated for all zoned devices, but disk_free_zone_resources skips it when the zone write plug hash is not allocated, leaking the allocation for non-mq devices that don't emulate zone append. This is reported by kmemleak-enabled xfstests for various tests that use simple device mapper targets. Fix this by moving all code that requires writes plugs from disk_free_zone_resources into disk_destroy_zone_wplugs_hash_table and executing the rest of the code, including the disk->zones_cond freeing unconditionally. Fixes: 6e945ffb6555 ("block: use zone condition to determine conventional zones") Signed-off-by: Christoph Hellwig Reviewed-by: Damien Le Moal Reviewed-by: Bart Van Assche Signed-off-by: Jens Axboe --- block/blk-zoned.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/block/blk-zoned.c b/block/blk-zoned.c index bba64b4270826..a0ce17e2143f4 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -1834,6 +1834,14 @@ static void disk_destroy_zone_wplugs_hash_table(struct gendisk *disk) kfree(disk->zone_wplugs_hash); disk->zone_wplugs_hash = NULL; disk->zone_wplugs_hash_bits = 0; + + /* + * Wait for the zone write plugs to be RCU-freed before destroying the + * mempool. + */ + rcu_barrier(); + mempool_destroy(disk->zone_wplugs_pool); + disk->zone_wplugs_pool = NULL; } static void disk_set_zones_cond_array(struct gendisk *disk, u8 *zones_cond) @@ -1850,9 +1858,6 @@ static void disk_set_zones_cond_array(struct gendisk *disk, u8 *zones_cond) void disk_free_zone_resources(struct gendisk *disk) { - if (!disk->zone_wplugs_pool) - return; - if (disk->zone_wplugs_wq) { destroy_workqueue(disk->zone_wplugs_wq); disk->zone_wplugs_wq = NULL; @@ -1860,15 +1865,6 @@ void disk_free_zone_resources(struct gendisk *disk) disk_destroy_zone_wplugs_hash_table(disk); - /* - * Wait for the zone write plugs to be RCU-freed before - * destorying the mempool. - */ - rcu_barrier(); - - mempool_destroy(disk->zone_wplugs_pool); - disk->zone_wplugs_pool = NULL; - disk_set_zones_cond_array(disk, NULL); disk->zone_capacity = 0; disk->last_zone_capacity = 0; -- 2.47.3