aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c56
1 files changed, 16 insertions, 40 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index f4f5f82f9f53..a20a71e5efd3 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -386,7 +386,9 @@ static void mddev_put(mddev_t *mddev)
386 if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock)) 386 if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
387 return; 387 return;
388 if (!mddev->raid_disks && list_empty(&mddev->disks) && 388 if (!mddev->raid_disks && list_empty(&mddev->disks) &&
389 !mddev->hold_active) { 389 mddev->ctime == 0 && !mddev->hold_active) {
390 /* Array is not configured at all, and not held active,
391 * so destroy it */
390 list_del(&mddev->all_mddevs); 392 list_del(&mddev->all_mddevs);
391 if (mddev->gendisk) { 393 if (mddev->gendisk) {
392 /* we did a probe so need to clean up. 394 /* we did a probe so need to clean up.
@@ -4073,8 +4075,10 @@ static void mddev_delayed_delete(struct work_struct *ws)
4073{ 4075{
4074 mddev_t *mddev = container_of(ws, mddev_t, del_work); 4076 mddev_t *mddev = container_of(ws, mddev_t, del_work);
4075 4077
4076 if (mddev->private == &md_redundancy_group) { 4078 if (mddev->private) {
4077 sysfs_remove_group(&mddev->kobj, &md_redundancy_group); 4079 sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
4080 if (mddev->private != (void*)1)
4081 sysfs_remove_group(&mddev->kobj, mddev->private);
4078 if (mddev->sysfs_action) 4082 if (mddev->sysfs_action)
4079 sysfs_put(mddev->sysfs_action); 4083 sysfs_put(mddev->sysfs_action);
4080 mddev->sysfs_action = NULL; 4084 mddev->sysfs_action = NULL;
@@ -4285,10 +4289,7 @@ static int do_md_run(mddev_t * mddev)
4285 sysfs_notify_dirent(rdev->sysfs_state); 4289 sysfs_notify_dirent(rdev->sysfs_state);
4286 } 4290 }
4287 4291
4288 md_probe(mddev->unit, NULL, NULL);
4289 disk = mddev->gendisk; 4292 disk = mddev->gendisk;
4290 if (!disk)
4291 return -ENOMEM;
4292 4293
4293 spin_lock(&pers_lock); 4294 spin_lock(&pers_lock);
4294 pers = find_pers(mddev->level, mddev->clevel); 4295 pers = find_pers(mddev->level, mddev->clevel);
@@ -4355,7 +4356,7 @@ static int do_md_run(mddev_t * mddev)
4355 mddev->barriers_work = 1; 4356 mddev->barriers_work = 1;
4356 mddev->ok_start_degraded = start_dirty_degraded; 4357 mddev->ok_start_degraded = start_dirty_degraded;
4357 4358
4358 if (start_readonly) 4359 if (start_readonly && mddev->ro == 0)
4359 mddev->ro = 2; /* read-only, but switch on first write */ 4360 mddev->ro = 2; /* read-only, but switch on first write */
4360 4361
4361 err = mddev->pers->run(mddev); 4362 err = mddev->pers->run(mddev);
@@ -4419,33 +4420,6 @@ static int do_md_run(mddev_t * mddev)
4419 4420
4420 set_capacity(disk, mddev->array_sectors); 4421 set_capacity(disk, mddev->array_sectors);
4421 4422
4422 /* If there is a partially-recovered drive we need to
4423 * start recovery here. If we leave it to md_check_recovery,
4424 * it will remove the drives and not do the right thing
4425 */
4426 if (mddev->degraded && !mddev->sync_thread) {
4427 int spares = 0;
4428 list_for_each_entry(rdev, &mddev->disks, same_set)
4429 if (rdev->raid_disk >= 0 &&
4430 !test_bit(In_sync, &rdev->flags) &&
4431 !test_bit(Faulty, &rdev->flags))
4432 /* complete an interrupted recovery */
4433 spares++;
4434 if (spares && mddev->pers->sync_request) {
4435 mddev->recovery = 0;
4436 set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
4437 mddev->sync_thread = md_register_thread(md_do_sync,
4438 mddev,
4439 "resync");
4440 if (!mddev->sync_thread) {
4441 printk(KERN_ERR "%s: could not start resync"
4442 " thread...\n",
4443 mdname(mddev));
4444 /* leave the spares where they are, it shouldn't hurt */
4445 mddev->recovery = 0;
4446 }
4447 }
4448 }
4449 md_wakeup_thread(mddev->thread); 4423 md_wakeup_thread(mddev->thread);
4450 md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ 4424 md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
4451 4425
@@ -4555,8 +4529,8 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
4555 mddev->queue->unplug_fn = NULL; 4529 mddev->queue->unplug_fn = NULL;
4556 mddev->queue->backing_dev_info.congested_fn = NULL; 4530 mddev->queue->backing_dev_info.congested_fn = NULL;
4557 module_put(mddev->pers->owner); 4531 module_put(mddev->pers->owner);
4558 if (mddev->pers->sync_request) 4532 if (mddev->pers->sync_request && mddev->private == NULL)
4559 mddev->private = &md_redundancy_group; 4533 mddev->private = (void*)1;
4560 mddev->pers = NULL; 4534 mddev->pers = NULL;
4561 /* tell userspace to handle 'inactive' */ 4535 /* tell userspace to handle 'inactive' */
4562 sysfs_notify_dirent(mddev->sysfs_state); 4536 sysfs_notify_dirent(mddev->sysfs_state);
@@ -4603,9 +4577,6 @@ out:
4603 } 4577 }
4604 mddev->bitmap_info.offset = 0; 4578 mddev->bitmap_info.offset = 0;
4605 4579
4606 /* make sure all md_delayed_delete calls have finished */
4607 flush_scheduled_work();
4608
4609 export_array(mddev); 4580 export_array(mddev);
4610 4581
4611 mddev->array_sectors = 0; 4582 mddev->array_sectors = 0;
@@ -5262,6 +5233,10 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
5262 mddev->minor_version = info->minor_version; 5233 mddev->minor_version = info->minor_version;
5263 mddev->patch_version = info->patch_version; 5234 mddev->patch_version = info->patch_version;
5264 mddev->persistent = !info->not_persistent; 5235 mddev->persistent = !info->not_persistent;
5236 /* ensure mddev_put doesn't delete this now that there
5237 * is some minimal configuration.
5238 */
5239 mddev->ctime = get_seconds();
5265 return 0; 5240 return 0;
5266 } 5241 }
5267 mddev->major_version = MD_MAJOR_VERSION; 5242 mddev->major_version = MD_MAJOR_VERSION;
@@ -6494,10 +6469,11 @@ void md_do_sync(mddev_t *mddev)
6494 mddev->curr_resync = 2; 6469 mddev->curr_resync = 2;
6495 6470
6496 try_again: 6471 try_again:
6497 if (kthread_should_stop()) { 6472 if (kthread_should_stop())
6498 set_bit(MD_RECOVERY_INTR, &mddev->recovery); 6473 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
6474
6475 if (test_bit(MD_RECOVERY_INTR, &mddev->recovery))
6499 goto skip; 6476 goto skip;
6500 }
6501 for_each_mddev(mddev2, tmp) { 6477 for_each_mddev(mddev2, tmp) {
6502 if (mddev2 == mddev) 6478 if (mddev2 == mddev)
6503 continue; 6479 continue;