diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/md.c | 42 |
1 files changed, 11 insertions, 31 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index f4f5f82f9f53..dd3dfe42d5a9 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. |
@@ -4355,7 +4357,7 @@ static int do_md_run(mddev_t * mddev) | |||
4355 | mddev->barriers_work = 1; | 4357 | mddev->barriers_work = 1; |
4356 | mddev->ok_start_degraded = start_dirty_degraded; | 4358 | mddev->ok_start_degraded = start_dirty_degraded; |
4357 | 4359 | ||
4358 | if (start_readonly) | 4360 | if (start_readonly && mddev->ro == 0) |
4359 | mddev->ro = 2; /* read-only, but switch on first write */ | 4361 | mddev->ro = 2; /* read-only, but switch on first write */ |
4360 | 4362 | ||
4361 | err = mddev->pers->run(mddev); | 4363 | err = mddev->pers->run(mddev); |
@@ -4419,33 +4421,6 @@ static int do_md_run(mddev_t * mddev) | |||
4419 | 4421 | ||
4420 | set_capacity(disk, mddev->array_sectors); | 4422 | set_capacity(disk, mddev->array_sectors); |
4421 | 4423 | ||
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); | 4424 | md_wakeup_thread(mddev->thread); |
4450 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ | 4425 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ |
4451 | 4426 | ||
@@ -5262,6 +5237,10 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) | |||
5262 | mddev->minor_version = info->minor_version; | 5237 | mddev->minor_version = info->minor_version; |
5263 | mddev->patch_version = info->patch_version; | 5238 | mddev->patch_version = info->patch_version; |
5264 | mddev->persistent = !info->not_persistent; | 5239 | mddev->persistent = !info->not_persistent; |
5240 | /* ensure mddev_put doesn't delete this now that there | ||
5241 | * is some minimal configuration. | ||
5242 | */ | ||
5243 | mddev->ctime = get_seconds(); | ||
5265 | return 0; | 5244 | return 0; |
5266 | } | 5245 | } |
5267 | mddev->major_version = MD_MAJOR_VERSION; | 5246 | mddev->major_version = MD_MAJOR_VERSION; |
@@ -6494,10 +6473,11 @@ void md_do_sync(mddev_t *mddev) | |||
6494 | mddev->curr_resync = 2; | 6473 | mddev->curr_resync = 2; |
6495 | 6474 | ||
6496 | try_again: | 6475 | try_again: |
6497 | if (kthread_should_stop()) { | 6476 | if (kthread_should_stop()) |
6498 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 6477 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
6478 | |||
6479 | if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) | ||
6499 | goto skip; | 6480 | goto skip; |
6500 | } | ||
6501 | for_each_mddev(mddev2, tmp) { | 6481 | for_each_mddev(mddev2, tmp) { |
6502 | if (mddev2 == mddev) | 6482 | if (mddev2 == mddev) |
6503 | continue; | 6483 | continue; |