aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2009-10-16 00:55:44 -0400
committerNeilBrown <neilb@suse.de>2009-10-16 00:55:44 -0400
commited9bfdf1a40952fd0f8094ec77f876b84ead69af (patch)
tree2b92f23e861fa2695a55a0cd797233d032634c9d /drivers/md
parentf5efd45ae597c96ed017afad5662b67d55b402a0 (diff)
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: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid1.c5
-rw-r--r--drivers/md/raid10.c4
2 files changed, 5 insertions, 4 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 71a01a2e1938..a053423785c9 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -64,7 +64,7 @@ static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data)
64 64
65 /* allocate a r1bio with room for raid_disks entries in the bios array */ 65 /* allocate a r1bio with room for raid_disks entries in the bios array */
66 r1_bio = kzalloc(size, gfp_flags); 66 r1_bio = kzalloc(size, gfp_flags);
67 if (!r1_bio) 67 if (!r1_bio && pi->mddev)
68 unplug_slaves(pi->mddev); 68 unplug_slaves(pi->mddev);
69 69
70 return r1_bio; 70 return r1_bio;
@@ -1979,13 +1979,14 @@ static int run(mddev_t *mddev)
1979 conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL); 1979 conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
1980 if (!conf->poolinfo) 1980 if (!conf->poolinfo)
1981 goto out_no_mem; 1981 goto out_no_mem;
1982 conf->poolinfo->mddev = mddev; 1982 conf->poolinfo->mddev = NULL;
1983 conf->poolinfo->raid_disks = mddev->raid_disks; 1983 conf->poolinfo->raid_disks = mddev->raid_disks;
1984 conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc, 1984 conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
1985 r1bio_pool_free, 1985 r1bio_pool_free,
1986 conf->poolinfo); 1986 conf->poolinfo);
1987 if (!conf->r1bio_pool) 1987 if (!conf->r1bio_pool)
1988 goto out_no_mem; 1988 goto out_no_mem;
1989 conf->poolinfo->mddev = mddev;
1989 1990
1990 spin_lock_init(&conf->device_lock); 1991 spin_lock_init(&conf->device_lock);
1991 mddev->queue->queue_lock = &conf->device_lock; 1992 mddev->queue->queue_lock = &conf->device_lock;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 69fc76caa469..c2cb7b87b440 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -68,7 +68,7 @@ static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
68 68
69 /* allocate a r10bio with room for raid_disks entries in the bios array */ 69 /* allocate a r10bio with room for raid_disks entries in the bios array */
70 r10_bio = kzalloc(size, gfp_flags); 70 r10_bio = kzalloc(size, gfp_flags);
71 if (!r10_bio) 71 if (!r10_bio && conf->mddev)
72 unplug_slaves(conf->mddev); 72 unplug_slaves(conf->mddev);
73 73
74 return r10_bio; 74 return r10_bio;
@@ -2096,7 +2096,6 @@ static int run(mddev_t *mddev)
2096 if (!conf->tmppage) 2096 if (!conf->tmppage)
2097 goto out_free_conf; 2097 goto out_free_conf;
2098 2098
2099 conf->mddev = mddev;
2100 conf->raid_disks = mddev->raid_disks; 2099 conf->raid_disks = mddev->raid_disks;
2101 conf->near_copies = nc; 2100 conf->near_copies = nc;
2102 conf->far_copies = fc; 2101 conf->far_copies = fc;
@@ -2133,6 +2132,7 @@ static int run(mddev_t *mddev)
2133 goto out_free_conf; 2132 goto out_free_conf;
2134 } 2133 }
2135 2134
2135 conf->mddev = mddev;
2136 spin_lock_init(&conf->device_lock); 2136 spin_lock_init(&conf->device_lock);
2137 mddev->queue->queue_lock = &conf->device_lock; 2137 mddev->queue->queue_lock = &conf->device_lock;
2138 2138