mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
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: 6e945ffb65 ("block: use zone condition to determine conventional zones")
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
committed by
Jens Axboe
parent
ba13710ddd
commit
c6886cf610
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user