gre: fix netns vs proto registration ordering
[safe/jmp/linux-2.6] / drivers / md / md.c
index f4f5f82..dd3dfe4 100644 (file)
@@ -386,7 +386,9 @@ static void mddev_put(mddev_t *mddev)
        if (!atomic_dec_and_lock(&mddev->active, &all_mddevs_lock))
                return;
        if (!mddev->raid_disks && list_empty(&mddev->disks) &&
-           !mddev->hold_active) {
+           mddev->ctime == 0 && !mddev->hold_active) {
+               /* Array is not configured at all, and not held active,
+                * so destroy it */
                list_del(&mddev->all_mddevs);
                if (mddev->gendisk) {
                        /* we did a probe so need to clean up.
@@ -4355,7 +4357,7 @@ static int do_md_run(mddev_t * mddev)
        mddev->barriers_work = 1;
        mddev->ok_start_degraded = start_dirty_degraded;
 
-       if (start_readonly)
+       if (start_readonly && mddev->ro == 0)
                mddev->ro = 2; /* read-only, but switch on first write */
 
        err = mddev->pers->run(mddev);
@@ -4419,33 +4421,6 @@ static int do_md_run(mddev_t * mddev)
 
        set_capacity(disk, mddev->array_sectors);
 
-       /* If there is a partially-recovered drive we need to
-        * start recovery here.  If we leave it to md_check_recovery,
-        * it will remove the drives and not do the right thing
-        */
-       if (mddev->degraded && !mddev->sync_thread) {
-               int spares = 0;
-               list_for_each_entry(rdev, &mddev->disks, same_set)
-                       if (rdev->raid_disk >= 0 &&
-                           !test_bit(In_sync, &rdev->flags) &&
-                           !test_bit(Faulty, &rdev->flags))
-                               /* complete an interrupted recovery */
-                               spares++;
-               if (spares && mddev->pers->sync_request) {
-                       mddev->recovery = 0;
-                       set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
-                       mddev->sync_thread = md_register_thread(md_do_sync,
-                                                               mddev,
-                                                               "resync");
-                       if (!mddev->sync_thread) {
-                               printk(KERN_ERR "%s: could not start resync"
-                                      " thread...\n",
-                                      mdname(mddev));
-                               /* leave the spares where they are, it shouldn't hurt */
-                               mddev->recovery = 0;
-                       }
-               }
-       }
        md_wakeup_thread(mddev->thread);
        md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
 
@@ -5262,6 +5237,10 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
                mddev->minor_version = info->minor_version;
                mddev->patch_version = info->patch_version;
                mddev->persistent = !info->not_persistent;
+               /* ensure mddev_put doesn't delete this now that there
+                * is some minimal configuration.
+                */
+               mddev->ctime         = get_seconds();
                return 0;
        }
        mddev->major_version = MD_MAJOR_VERSION;
@@ -6494,10 +6473,11 @@ void md_do_sync(mddev_t *mddev)
                mddev->curr_resync = 2;
 
        try_again:
-               if (kthread_should_stop()) {
+               if (kthread_should_stop())
                        set_bit(MD_RECOVERY_INTR, &mddev->recovery);
+
+               if (test_bit(MD_RECOVERY_INTR, &mddev->recovery))
                        goto skip;
-               }
                for_each_mddev(mddev2, tmp) {
                        if (mddev2 == mddev)
                                continue;