atomic_add(sectors, &mddev->recovery_active);
                }
 
+               if (test_bit(MD_RECOVERY_INTR, &mddev->recovery))
+                       break;
+
                j += sectors;
                if (j>1) mddev->curr_resync = j;
                mddev->curr_mark_cnt = io_sectors;
                if (last_check == 0)
-                       /* this is the earliers that rebuilt will be
+                       /* this is the earliest that rebuild will be
                         * visible in /proc/mdstat
                         */
                        md_new_event(mddev);
                        continue;
 
                last_check = io_sectors;
-
-               if (test_bit(MD_RECOVERY_INTR, &mddev->recovery))
-                       break;
-
        repeat:
                if (time_after_eq(jiffies, mark[last_mark] + SYNC_MARK_STEP )) {
                        /* step marks */
 
        max_sync = RESYNC_PAGES << (PAGE_SHIFT-9);
        if (!test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
                /* recovery... the complicated one */
-               int j, k;
+               int j;
                r10_bio = NULL;
 
                for (i=0 ; i<conf->raid_disks; i++) {
                        r10bio_t *rb2;
                        sector_t sect;
                        int must_sync;
+                       int any_working;
 
                        if (conf->mirrors[i].rdev == NULL ||
                            test_bit(In_sync, &conf->mirrors[i].rdev->flags)) 
                        must_sync = bitmap_start_sync(mddev->bitmap, sect,
                                                      &sync_blocks, still_degraded);
 
+                       any_working = 0;
                        for (j=0; j<conf->copies;j++) {
+                               int k;
                                int d = r10_bio->devs[j].devnum;
                                mdk_rdev_t *rdev;
                                sector_t sector, first_bad;
                                    !test_bit(In_sync, &conf->mirrors[d].rdev->flags))
                                        continue;
                                /* This is where we read from */
+                               any_working = 1;
                                rdev = conf->mirrors[d].rdev;
                                sector = r10_bio->devs[j].addr;
 
                                break;
                        }
                        if (j == conf->copies) {
-                               /* Cannot recover, so abort the recovery */
+                               /* Cannot recover, so abort the recovery or
+                                * record a bad block */
                                put_buf(r10_bio);
                                if (rb2)
                                        atomic_dec(&rb2->remaining);
                                r10_bio = rb2;
-                               if (!test_and_set_bit(MD_RECOVERY_INTR,
-                                                     &mddev->recovery))
-                                       printk(KERN_INFO "md/raid10:%s: insufficient "
-                                              "working devices for recovery.\n",
-                                              mdname(mddev));
+                               if (any_working) {
+                                       /* problem is that there are bad blocks
+                                        * on other device(s)
+                                        */
+                                       int k;
+                                       for (k = 0; k < conf->copies; k++)
+                                               if (r10_bio->devs[k].devnum == i)
+                                                       break;
+                                       if (!rdev_set_badblocks(
+                                                   conf->mirrors[i].rdev,
+                                                   r10_bio->devs[k].addr,
+                                                   max_sync, 0))
+                                               any_working = 0;
+                               }
+                               if (!any_working)  {
+                                       if (!test_and_set_bit(MD_RECOVERY_INTR,
+                                                             &mddev->recovery))
+                                               printk(KERN_INFO "md/raid10:%s: insufficient "
+                                                      "working devices for recovery.\n",
+                                                      mdname(mddev));
+                                       conf->mirrors[i].recovery_disabled
+                                               = mddev->recovery_disabled;
+                               }
                                break;
                        }
                }
        return sectors_skipped + nr_sectors;
  giveup:
        /* There is nowhere to write, so all non-sync
-        * drives must be failed, so try the next chunk...
+        * drives must be failed or in resync, all drives
+        * have a bad block, so try the next chunk...
         */
        if (sector_nr + max_sync < max_sector)
                max_sector = sector_nr + max_sync;