md/raid10: fix memleak for 'conf->bio_split'
[ Upstream commitc9ac2acde5
] In the error path of raid10_run(), 'conf' need be freed, however, 'conf->bio_split' is missed and memory will be leaked. Since there are 3 places to free 'conf', factor out a helper to fix the problem. Fixes:fc9977dd06
("md/raid10: simplify the splitting of requests.") Signed-off-by: Yu Kuai <yukuai3@huawei.com> Signed-off-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20230310073855.1337560-6-yukuai1@huaweicloud.com Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
1697fb124c
commit
6361b0592b
@ -3618,6 +3618,20 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new)
|
|||||||
return nc*fc;
|
return nc*fc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void raid10_free_conf(struct r10conf *conf)
|
||||||
|
{
|
||||||
|
if (!conf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mempool_exit(&conf->r10bio_pool);
|
||||||
|
kfree(conf->mirrors);
|
||||||
|
kfree(conf->mirrors_old);
|
||||||
|
kfree(conf->mirrors_new);
|
||||||
|
safe_put_page(conf->tmppage);
|
||||||
|
bioset_exit(&conf->bio_split);
|
||||||
|
kfree(conf);
|
||||||
|
}
|
||||||
|
|
||||||
static struct r10conf *setup_conf(struct mddev *mddev)
|
static struct r10conf *setup_conf(struct mddev *mddev)
|
||||||
{
|
{
|
||||||
struct r10conf *conf = NULL;
|
struct r10conf *conf = NULL;
|
||||||
@ -3700,13 +3714,7 @@ static struct r10conf *setup_conf(struct mddev *mddev)
|
|||||||
return conf;
|
return conf;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (conf) {
|
raid10_free_conf(conf);
|
||||||
mempool_exit(&conf->r10bio_pool);
|
|
||||||
kfree(conf->mirrors);
|
|
||||||
safe_put_page(conf->tmppage);
|
|
||||||
bioset_exit(&conf->bio_split);
|
|
||||||
kfree(conf);
|
|
||||||
}
|
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3912,10 +3920,7 @@ static int raid10_run(struct mddev *mddev)
|
|||||||
|
|
||||||
out_free_conf:
|
out_free_conf:
|
||||||
md_unregister_thread(&mddev->thread);
|
md_unregister_thread(&mddev->thread);
|
||||||
mempool_exit(&conf->r10bio_pool);
|
raid10_free_conf(conf);
|
||||||
safe_put_page(conf->tmppage);
|
|
||||||
kfree(conf->mirrors);
|
|
||||||
kfree(conf);
|
|
||||||
mddev->private = NULL;
|
mddev->private = NULL;
|
||||||
out:
|
out:
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@ -3923,15 +3928,7 @@ out:
|
|||||||
|
|
||||||
static void raid10_free(struct mddev *mddev, void *priv)
|
static void raid10_free(struct mddev *mddev, void *priv)
|
||||||
{
|
{
|
||||||
struct r10conf *conf = priv;
|
raid10_free_conf(priv);
|
||||||
|
|
||||||
mempool_exit(&conf->r10bio_pool);
|
|
||||||
safe_put_page(conf->tmppage);
|
|
||||||
kfree(conf->mirrors);
|
|
||||||
kfree(conf->mirrors_old);
|
|
||||||
kfree(conf->mirrors_new);
|
|
||||||
bioset_exit(&conf->bio_split);
|
|
||||||
kfree(conf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raid10_quiesce(struct mddev *mddev, int quiesce)
|
static void raid10_quiesce(struct mddev *mddev, int quiesce)
|
||||||
|
Reference in New Issue
Block a user