aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/linear.c1
-rw-r--r--drivers/md/md.c30
-rw-r--r--drivers/md/multipath.c2
-rw-r--r--drivers/md/raid0.c1
-rw-r--r--drivers/md/raid1.c18
-rw-r--r--drivers/md/raid10.c8
-rw-r--r--drivers/md/raid5.c1
7 files changed, 29 insertions, 32 deletions
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index b3e717adbc9b..c201555b9c6c 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -253,7 +253,6 @@ static int linear_stop (struct mddev *mddev)
253{ 253{
254 struct linear_conf *conf = mddev->private; 254 struct linear_conf *conf = mddev->private;
255 255
256 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
257 kfree(conf); 256 kfree(conf);
258 mddev->private = NULL; 257 mddev->private = NULL;
259 258
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 9f0ff7187136..58f140bef999 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -72,6 +72,7 @@ static struct workqueue_struct *md_misc_wq;
72 72
73static int remove_and_add_spares(struct mddev *mddev, 73static int remove_and_add_spares(struct mddev *mddev,
74 struct md_rdev *this); 74 struct md_rdev *this);
75static void mddev_detach(struct mddev *mddev);
75 76
76/* 77/*
77 * Default number of read corrections we'll attempt on an rdev 78 * Default number of read corrections we'll attempt on an rdev
@@ -3372,6 +3373,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
3372 3373
3373 /* Looks like we have a winner */ 3374 /* Looks like we have a winner */
3374 mddev_suspend(mddev); 3375 mddev_suspend(mddev);
3376 mddev_detach(mddev);
3375 mddev->pers->stop(mddev); 3377 mddev->pers->stop(mddev);
3376 3378
3377 if (mddev->pers->sync_request == NULL && 3379 if (mddev->pers->sync_request == NULL &&
@@ -4928,18 +4930,17 @@ int md_run(struct mddev *mddev)
4928 (unsigned long long)mddev->array_sectors / 2, 4930 (unsigned long long)mddev->array_sectors / 2,
4929 (unsigned long long)mddev->pers->size(mddev, 0, 0) / 2); 4931 (unsigned long long)mddev->pers->size(mddev, 0, 0) / 2);
4930 err = -EINVAL; 4932 err = -EINVAL;
4931 mddev->pers->stop(mddev);
4932 } 4933 }
4933 if (err == 0 && mddev->pers->sync_request && 4934 if (err == 0 && mddev->pers->sync_request &&
4934 (mddev->bitmap_info.file || mddev->bitmap_info.offset)) { 4935 (mddev->bitmap_info.file || mddev->bitmap_info.offset)) {
4935 err = bitmap_create(mddev); 4936 err = bitmap_create(mddev);
4936 if (err) { 4937 if (err)
4937 printk(KERN_ERR "%s: failed to create bitmap (%d)\n", 4938 printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
4938 mdname(mddev), err); 4939 mdname(mddev), err);
4939 mddev->pers->stop(mddev);
4940 }
4941 } 4940 }
4942 if (err) { 4941 if (err) {
4942 mddev_detach(mddev);
4943 mddev->pers->stop(mddev);
4943 module_put(mddev->pers->owner); 4944 module_put(mddev->pers->owner);
4944 mddev->pers = NULL; 4945 mddev->pers = NULL;
4945 bitmap_destroy(mddev); 4946 bitmap_destroy(mddev);
@@ -5112,9 +5113,30 @@ void md_stop_writes(struct mddev *mddev)
5112} 5113}
5113EXPORT_SYMBOL_GPL(md_stop_writes); 5114EXPORT_SYMBOL_GPL(md_stop_writes);
5114 5115
5116static void mddev_detach(struct mddev *mddev)
5117{
5118 struct bitmap *bitmap = mddev->bitmap;
5119 /* wait for behind writes to complete */
5120 if (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
5121 printk(KERN_INFO "md:%s: behind writes in progress - waiting to stop.\n",
5122 mdname(mddev));
5123 /* need to kick something here to make sure I/O goes? */
5124 wait_event(bitmap->behind_wait,
5125 atomic_read(&bitmap->behind_writes) == 0);
5126 }
5127 if (mddev->pers->quiesce) {
5128 mddev->pers->quiesce(mddev, 1);
5129 mddev->pers->quiesce(mddev, 0);
5130 }
5131 md_unregister_thread(&mddev->thread);
5132 if (mddev->queue)
5133 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
5134}
5135
5115static void __md_stop(struct mddev *mddev) 5136static void __md_stop(struct mddev *mddev)
5116{ 5137{
5117 mddev->ready = 0; 5138 mddev->ready = 0;
5139 mddev_detach(mddev);
5118 mddev->pers->stop(mddev); 5140 mddev->pers->stop(mddev);
5119 if (mddev->pers->sync_request && mddev->to_remove == NULL) 5141 if (mddev->pers->sync_request && mddev->to_remove == NULL)
5120 mddev->to_remove = &md_redundancy_group; 5142 mddev->to_remove = &md_redundancy_group;
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index fedb1b31877d..9fe34453835b 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -504,8 +504,6 @@ static int multipath_stop (struct mddev *mddev)
504{ 504{
505 struct mpconf *conf = mddev->private; 505 struct mpconf *conf = mddev->private;
506 506
507 md_unregister_thread(&mddev->thread);
508 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
509 mempool_destroy(conf->pool); 507 mempool_destroy(conf->pool);
510 kfree(conf->multipaths); 508 kfree(conf->multipaths);
511 kfree(conf); 509 kfree(conf);
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 3770c9675b17..01dfca94b663 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -477,7 +477,6 @@ static int raid0_stop(struct mddev *mddev)
477{ 477{
478 struct r0conf *conf = mddev->private; 478 struct r0conf *conf = mddev->private;
479 479
480 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
481 kfree(conf->strip_zone); 480 kfree(conf->strip_zone);
482 kfree(conf->devlist); 481 kfree(conf->devlist);
483 kfree(conf); 482 kfree(conf);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 45c512a4b75d..fccea0b39808 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2954,29 +2954,17 @@ static int run(struct mddev *mddev)
2954 } 2954 }
2955 2955
2956 ret = md_integrity_register(mddev); 2956 ret = md_integrity_register(mddev);
2957 if (ret) 2957 if (ret) {
2958 md_unregister_thread(&mddev->thread);
2958 stop(mddev); 2959 stop(mddev);
2960 }
2959 return ret; 2961 return ret;
2960} 2962}
2961 2963
2962static int stop(struct mddev *mddev) 2964static int stop(struct mddev *mddev)
2963{ 2965{
2964 struct r1conf *conf = mddev->private; 2966 struct r1conf *conf = mddev->private;
2965 struct bitmap *bitmap = mddev->bitmap;
2966
2967 /* wait for behind writes to complete */
2968 if (bitmap && atomic_read(&bitmap->behind_writes) > 0) {
2969 printk(KERN_INFO "md/raid1:%s: behind writes in progress - waiting to stop.\n",
2970 mdname(mddev));
2971 /* need to kick something here to make sure I/O goes? */
2972 wait_event(bitmap->behind_wait,
2973 atomic_read(&bitmap->behind_writes) == 0);
2974 }
2975
2976 freeze_array(conf, 0);
2977 unfreeze_array(conf);
2978 2967
2979 md_unregister_thread(&mddev->thread);
2980 if (conf->r1bio_pool) 2968 if (conf->r1bio_pool)
2981 mempool_destroy(conf->r1bio_pool); 2969 mempool_destroy(conf->r1bio_pool);
2982 kfree(conf->mirrors); 2970 kfree(conf->mirrors);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 407c81a820f4..654fdae906aa 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3802,14 +3802,6 @@ static int stop(struct mddev *mddev)
3802{ 3802{
3803 struct r10conf *conf = mddev->private; 3803 struct r10conf *conf = mddev->private;
3804 3804
3805 raise_barrier(conf, 0);
3806 lower_barrier(conf);
3807
3808 md_unregister_thread(&mddev->thread);
3809 if (mddev->queue)
3810 /* the unplug fn references 'conf'*/
3811 blk_sync_queue(mddev->queue);
3812
3813 if (conf->r10bio_pool) 3805 if (conf->r10bio_pool)
3814 mempool_destroy(conf->r10bio_pool); 3806 mempool_destroy(conf->r10bio_pool);
3815 safe_put_page(conf->tmppage); 3807 safe_put_page(conf->tmppage);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 2d4a2cc85eb2..482526077647 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -6317,7 +6317,6 @@ static int stop(struct mddev *mddev)
6317{ 6317{
6318 struct r5conf *conf = mddev->private; 6318 struct r5conf *conf = mddev->private;
6319 6319
6320 md_unregister_thread(&mddev->thread);
6321 free_conf(conf); 6320 free_conf(conf);
6322 mddev->private = NULL; 6321 mddev->private = NULL;
6323 mddev->to_remove = &raid5_attrs_group; 6322 mddev->to_remove = &raid5_attrs_group;