Re: 2.5.70-mm1 bootcrash, possibly RAID-1

Neil Brown
2003-05-30T01:59:30Z

On Thursday May 29, zwane@linuxpower.ca wrote:
> How does the following patch look for the double free.
>

Thanks. It is a good start, but there are other problems with freeing
things on error paths. This patch should fix it all.

NeilBrown

--------------------------------------------
Fix up freeing of kmalloc structures

Some paths free things twice, others free un-initialised values :-(
Not any more.

----------- Diffstat output ------------
./drivers/md/raid0.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)

diff ./drivers/md/raid0.c~current~ ./drivers/md/raid0.c
--- ./drivers/md/raid0.c~current~ 2003-05-30 11:40:06.000000000 +1000
+++ ./drivers/md/raid0.c 2003-05-30 11:47:03.000000000 +1000
@@ -85,10 +85,8 @@ static int create_strip_zones (mddev_t *
conf->devlist = kmalloc(sizeof(mdk_rdev_t*)*
conf->nr_strip_zones*mddev->raid_disks,
GFP_KERNEL);
- if (!conf->devlist) {
- kfree(conf);
+ if (!conf->devlist)
return 1;
- }

memset(conf->strip_zone, 0,sizeof(struct strip_zone)*
conf->nr_strip_zones);
@@ -235,6 +233,8 @@ static int raid0_run (mddev_t *mddev)
goto out;
mddev->private = (void *)conf;

+ mddev->strip_zone = NULL;
+ mddev->devlist = NULL;
if (create_strip_zones (mddev))
goto out_free_conf;

@@ -273,7 +273,7 @@ static int raid0_run (mddev_t *mddev)
nb_zone*sizeof(struct strip_zone*));
conf->hash_table = kmalloc (sizeof (struct strip_zone *)*nb_zone, GFP_KERNEL);
if (!conf->hash_table)
- goto out_free_zone_conf;
+ goto out_free_conf;
size = conf->strip_zone[cur].size;

for (i=0; i< nb_zone; i++) {
@@ -296,12 +296,11 @@ static int raid0_run (mddev_t *mddev)
blk_queue_merge_bvec(&mddev->queue, raid0_mergeable_bvec);
return 0;

-out_free_zone_conf:
- kfree(conf->strip_zone);
- conf->strip_zone = NULL;
-
out_free_conf:
- kfree (conf->devlist);
+ if (conf->strip_zone)
+ kfree(conf->strip_zone);
+ if (conf->devlist)
+ kfree (conf->devlist);
kfree(conf);
mddev->private = NULL;