Skip to content

Commit 2a2f520

Browse files
JackieLiu1axboe
authored andcommitted
block: fix zones_cond memory leak on zone revalidation error paths
When blk_revalidate_disk_zones() fails after disk_revalidate_zone_resources() has allocated args.zones_cond, the memory is leaked because no error path frees it. Fixes: 6e945ff ("block: use zone condition to determine conventional zones") Suggested-by: Damien Le Moal <dlemoal@kernel.org> Signed-off-by: Jackie Liu <liuyun01@kylinos.cn> Link: https://patch.msgid.link/20260331111216.24242-1-liu.yun@linux.dev Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 267ec4d commit 2a2f520

1 file changed

Lines changed: 20 additions & 6 deletions

File tree

block/blk-zoned.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,7 @@ static int disk_revalidate_zone_resources(struct gendisk *disk,
20162016
{
20172017
struct queue_limits *lim = &disk->queue->limits;
20182018
unsigned int pool_size;
2019+
int ret = 0;
20192020

20202021
args->disk = disk;
20212022
args->nr_zones =
@@ -2038,10 +2039,13 @@ static int disk_revalidate_zone_resources(struct gendisk *disk,
20382039
pool_size =
20392040
min(BLK_ZONE_WPLUG_DEFAULT_POOL_SIZE, args->nr_zones);
20402041

2041-
if (!disk->zone_wplugs_hash)
2042-
return disk_alloc_zone_resources(disk, pool_size);
2042+
if (!disk->zone_wplugs_hash) {
2043+
ret = disk_alloc_zone_resources(disk, pool_size);
2044+
if (ret)
2045+
kfree(args->zones_cond);
2046+
}
20432047

2044-
return 0;
2048+
return ret;
20452049
}
20462050

20472051
/*
@@ -2073,6 +2077,7 @@ static int disk_update_zone_resources(struct gendisk *disk,
20732077
disk->zone_capacity = args->zone_capacity;
20742078
disk->last_zone_capacity = args->last_zone_capacity;
20752079
disk_set_zones_cond_array(disk, args->zones_cond);
2080+
args->zones_cond = NULL;
20762081

20772082
/*
20782083
* Some devices can advertise zone resource limits that are larger than
@@ -2353,21 +2358,30 @@ int blk_revalidate_disk_zones(struct gendisk *disk)
23532358
}
23542359
memalloc_noio_restore(noio_flag);
23552360

2361+
if (ret <= 0)
2362+
goto free_resources;
2363+
23562364
/*
23572365
* If zones where reported, make sure that the entire disk capacity
23582366
* has been checked.
23592367
*/
2360-
if (ret > 0 && args.sector != capacity) {
2368+
if (args.sector != capacity) {
23612369
pr_warn("%s: Missing zones from sector %llu\n",
23622370
disk->disk_name, args.sector);
23632371
ret = -ENODEV;
2372+
goto free_resources;
23642373
}
23652374

2366-
if (ret > 0)
2367-
return disk_update_zone_resources(disk, &args);
2375+
ret = disk_update_zone_resources(disk, &args);
2376+
if (ret)
2377+
goto free_resources;
2378+
2379+
return 0;
23682380

2381+
free_resources:
23692382
pr_warn("%s: failed to revalidate zones\n", disk->disk_name);
23702383

2384+
kfree(args.zones_cond);
23712385
memflags = blk_mq_freeze_queue(q);
23722386
disk_free_zone_resources(disk);
23732387
blk_mq_unfreeze_queue(q, memflags);

0 commit comments

Comments
 (0)