md/raid10: fix memleak for 'conf->bio_split'
authorYu Kuai <yukuai3@huawei.com>
Fri, 10 Mar 2023 07:38:54 +0000 (15:38 +0800)
committerSong Liu <song@kernel.org>
Fri, 14 Apr 2023 07:42:03 +0000 (00:42 -0700)
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
drivers/md/raid10.c

index 82f2277..befa477 100644 (file)
@@ -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)