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; |
