diff options
author | Yu Kuai <yukuai3@huawei.com> | 2023-03-10 15:38:54 +0800 |
---|---|---|
committer | Song Liu <song@kernel.org> | 2023-04-14 00:42:03 -0700 |
commit | c9ac2acde53f5385de185bccf6aaa91cf9ac1541 (patch) | |
tree | 39128948b887bcf642ebe489d538e26db2b6977d /drivers/md | |
parent | 26208a7cffd0c7cbf14237ccd20c7270b3ffeb7e (diff) | |
download | linux-stable-c9ac2acde53f5385de185bccf6aaa91cf9ac1541.tar.gz linux-stable-c9ac2acde53f5385de185bccf6aaa91cf9ac1541.tar.bz2 linux-stable-c9ac2acde53f5385de185bccf6aaa91cf9ac1541.zip |
md/raid10: fix memleak for 'conf->bio_split'
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: fc9977dd069e ("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
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/raid10.c | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 82f2277d7bcf..befa4775c78b 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -4017,6 +4017,20 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new) 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) { struct r10conf *conf = NULL; @@ -4099,13 +4113,7 @@ static struct r10conf *setup_conf(struct mddev *mddev) return conf; out: - if (conf) { - mempool_exit(&conf->r10bio_pool); - kfree(conf->mirrors); - safe_put_page(conf->tmppage); - bioset_exit(&conf->bio_split); - kfree(conf); - } + raid10_free_conf(conf); return ERR_PTR(err); } @@ -4296,10 +4304,7 @@ static int raid10_run(struct mddev *mddev) out_free_conf: md_unregister_thread(&mddev->thread); - mempool_exit(&conf->r10bio_pool); - safe_put_page(conf->tmppage); - kfree(conf->mirrors); - kfree(conf); + raid10_free_conf(conf); mddev->private = NULL; out: return -EIO; @@ -4307,15 +4312,7 @@ out: static void raid10_free(struct mddev *mddev, void *priv) { - struct r10conf *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); + raid10_free_conf(priv); } static void raid10_quiesce(struct mddev *mddev, int quiesce) |