diff options
-rw-r--r-- | drivers/md/linear.c | 1 | ||||
-rw-r--r-- | drivers/md/md.c | 30 | ||||
-rw-r--r-- | drivers/md/multipath.c | 2 | ||||
-rw-r--r-- | drivers/md/raid0.c | 1 | ||||
-rw-r--r-- | drivers/md/raid1.c | 18 | ||||
-rw-r--r-- | drivers/md/raid10.c | 8 | ||||
-rw-r--r-- | drivers/md/raid5.c | 1 |
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 | ||
73 | static int remove_and_add_spares(struct mddev *mddev, | 73 | static int remove_and_add_spares(struct mddev *mddev, |
74 | struct md_rdev *this); | 74 | struct md_rdev *this); |
75 | static 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 | } |
5113 | EXPORT_SYMBOL_GPL(md_stop_writes); | 5114 | EXPORT_SYMBOL_GPL(md_stop_writes); |
5114 | 5115 | ||
5116 | static 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 | |||
5115 | static void __md_stop(struct mddev *mddev) | 5136 | static 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 | ||
2962 | static int stop(struct mddev *mddev) | 2964 | static 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; |