Commit ed9bfdf1 authored by NeilBrown's avatar NeilBrown

md: raid1/raid10: handle allocation errors during array setup.

Both raid1 and raid10 create a mempool during startup.
If the 'alloc' function for this mempool fails, unplug_slaves
is called.
If that happens when the pool is being initialised, unplug_slaves
will try to use the 'conf' structure that isn't filled in yet, and
badness will happen.

So ensure that unplug_slaves doesn't get called unless we know
that the conf structure if fully initialised.
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent f5efd45a
...@@ -64,7 +64,7 @@ static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data) ...@@ -64,7 +64,7 @@ static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
/* allocate a r1bio with room for raid_disks entries in the bios array */ /* allocate a r1bio with room for raid_disks entries in the bios array */
r1_bio = kzalloc(size, gfp_flags); r1_bio = kzalloc(size, gfp_flags);
if (!r1_bio) if (!r1_bio && pi->mddev)
unplug_slaves(pi->mddev); unplug_slaves(pi->mddev);
return r1_bio; return r1_bio;
...@@ -1979,13 +1979,14 @@ static int run(mddev_t *mddev) ...@@ -1979,13 +1979,14 @@ static int run(mddev_t *mddev)
conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL); conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
if (!conf->poolinfo) if (!conf->poolinfo)
goto out_no_mem; goto out_no_mem;
conf->poolinfo->mddev = mddev; conf->poolinfo->mddev = NULL;
conf->poolinfo->raid_disks = mddev->raid_disks; conf->poolinfo->raid_disks = mddev->raid_disks;
conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc, conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
r1bio_pool_free, r1bio_pool_free,
conf->poolinfo); conf->poolinfo);
if (!conf->r1bio_pool) if (!conf->r1bio_pool)
goto out_no_mem; goto out_no_mem;
conf->poolinfo->mddev = mddev;
spin_lock_init(&conf->device_lock); spin_lock_init(&conf->device_lock);
mddev->queue->queue_lock = &conf->device_lock; mddev->queue->queue_lock = &conf->device_lock;
......
...@@ -68,7 +68,7 @@ static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data) ...@@ -68,7 +68,7 @@ static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
/* allocate a r10bio with room for raid_disks entries in the bios array */ /* allocate a r10bio with room for raid_disks entries in the bios array */
r10_bio = kzalloc(size, gfp_flags); r10_bio = kzalloc(size, gfp_flags);
if (!r10_bio) if (!r10_bio && conf->mddev)
unplug_slaves(conf->mddev); unplug_slaves(conf->mddev);
return r10_bio; return r10_bio;
...@@ -2096,7 +2096,6 @@ static int run(mddev_t *mddev) ...@@ -2096,7 +2096,6 @@ static int run(mddev_t *mddev)
if (!conf->tmppage) if (!conf->tmppage)
goto out_free_conf; goto out_free_conf;
conf->mddev = mddev;
conf->raid_disks = mddev->raid_disks; conf->raid_disks = mddev->raid_disks;
conf->near_copies = nc; conf->near_copies = nc;
conf->far_copies = fc; conf->far_copies = fc;
...@@ -2133,6 +2132,7 @@ static int run(mddev_t *mddev) ...@@ -2133,6 +2132,7 @@ static int run(mddev_t *mddev)
goto out_free_conf; goto out_free_conf;
} }
conf->mddev = mddev;
spin_lock_init(&conf->device_lock); spin_lock_init(&conf->device_lock);
mddev->queue->queue_lock = &conf->device_lock; mddev->queue->queue_lock = &conf->device_lock;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment