diff options
Diffstat (limited to 'drivers/md')
-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 b3e717adbc9..c201555b9c6 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -253,7 +253,6 @@ static int linear_stop (struct mddev *mddev) { struct linear_conf *conf = mddev->private; - blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ kfree(conf); mddev->private = NULL; diff --git a/drivers/md/md.c b/drivers/md/md.c index 9f0ff718713..58f140bef99 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -72,6 +72,7 @@ static struct workqueue_struct *md_misc_wq; static int remove_and_add_spares(struct mddev *mddev, struct md_rdev *this); +static void mddev_detach(struct mddev *mddev); /* * 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) /* Looks like we have a winner */ mddev_suspend(mddev); + mddev_detach(mddev); mddev->pers->stop(mddev); if (mddev->pers->sync_request == NULL && @@ -4928,18 +4930,17 @@ int md_run(struct mddev *mddev) (unsigned long long)mddev->array_sectors / 2, (unsigned long long)mddev->pers->size(mddev, 0, 0) / 2); err = -EINVAL; - mddev->pers->stop(mddev); } if (err == 0 && mddev->pers->sync_request && (mddev->bitmap_info.file || mddev->bitmap_info.offset)) { err = bitmap_create(mddev); - if (err) { + if (err) printk(KERN_ERR "%s: failed to create bitmap (%d)\n", mdname(mddev), err); - mddev->pers->stop(mddev); - } } if (err) { + mddev_detach(mddev); + mddev->pers->stop(mddev); module_put(mddev->pers->owner); mddev->pers = NULL; bitmap_destroy(mddev); @@ -5112,9 +5113,30 @@ void md_stop_writes(struct mddev *mddev) } EXPORT_SYMBOL_GPL(md_stop_writes); +static void mddev_detach(struct mddev *mddev) +{ + struct bitmap *bitmap = mddev->bitmap; + /* wait for behind writes to complete */ + if (bitmap && atomic_read(&bitmap->behind_writes) > 0) { + printk(KERN_INFO "md:%s: behind writes in progress - waiting to stop.\n", + mdname(mddev)); + /* need to kick something here to make sure I/O goes? */ + wait_event(bitmap->behind_wait, + atomic_read(&bitmap->behind_writes) == 0); + } + if (mddev->pers->quiesce) { + mddev->pers->quiesce(mddev, 1); + mddev->pers->quiesce(mddev, 0); + } + md_unregister_thread(&mddev->thread); + if (mddev->queue) + blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ +} + static void __md_stop(struct mddev *mddev) { mddev->ready = 0; + mddev_detach(mddev); mddev->pers->stop(mddev); if (mddev->pers->sync_request && mddev->to_remove == NULL) mddev->to_remove = &md_redundancy_group; diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index fedb1b31877..9fe34453835 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -504,8 +504,6 @@ static int multipath_stop (struct mddev *mddev) { struct mpconf *conf = mddev->private; - md_unregister_thread(&mddev->thread); - blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ mempool_destroy(conf->pool); kfree(conf->multipaths); kfree(conf); diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 3770c9675b1..01dfca94b66 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -477,7 +477,6 @@ static int raid0_stop(struct mddev *mddev) { struct r0conf *conf = mddev->private; - blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ kfree(conf->strip_zone); kfree(conf->devlist); kfree(conf); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 45c512a4b75..fccea0b3980 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2954,29 +2954,17 @@ static int run(struct mddev *mddev) } ret = md_integrity_register(mddev); - if (ret) + if (ret) { + md_unregister_thread(&mddev->thread); stop(mddev); + } return ret; } static int stop(struct mddev *mddev) { struct r1conf *conf = mddev->private; - struct bitmap *bitmap = mddev->bitmap; - - /* wait for behind writes to complete */ - if (bitmap && atomic_read(&bitmap->behind_writes) > 0) { - printk(KERN_INFO "md/raid1:%s: behind writes in progress - waiting to stop.\n", - mdname(mddev)); - /* need to kick something here to make sure I/O goes? */ - wait_event(bitmap->behind_wait, - atomic_read(&bitmap->behind_writes) == 0); - } - - freeze_array(conf, 0); - unfreeze_array(conf); - md_unregister_thread(&mddev->thread); if (conf->r1bio_pool) mempool_destroy(conf->r1bio_pool); kfree(conf->mirrors); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 407c81a820f..654fdae906a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -3802,14 +3802,6 @@ static int stop(struct mddev *mddev) { struct r10conf *conf = mddev->private; - raise_barrier(conf, 0); - lower_barrier(conf); - - md_unregister_thread(&mddev->thread); - if (mddev->queue) - /* the unplug fn references 'conf'*/ - blk_sync_queue(mddev->queue); - if (conf->r10bio_pool) mempool_destroy(conf->r10bio_pool); safe_put_page(conf->tmppage); diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 2d4a2cc85eb..48252607764 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -6317,7 +6317,6 @@ static int stop(struct mddev *mddev) { struct r5conf *conf = mddev->private; - md_unregister_thread(&mddev->thread); free_conf(conf); mddev->private = NULL; mddev->to_remove = &raid5_attrs_group; |