spin_lock_irqsave(&conf->device_lock, flags);
        list_add(&r1_bio->retry_list, &conf->retry_list);
+       conf->nr_queued ++;
        spin_unlock_irqrestore(&conf->device_lock, flags);
 
        wake_up(&conf->wait_barrier);
        /*
         * this branch is our 'one mirror IO has finished' event handler:
         */
-       if (!uptodate)
-               md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
-       else
+       update_head_pos(mirror, r1_bio);
+
+       if (uptodate || conf->working_disks <= 1) {
                /*
                 * Set R1BIO_Uptodate in our master bio, so that
                 * we will return a good error code for to the higher
                 */
                set_bit(R1BIO_Uptodate, &r1_bio->state);
 
-       update_head_pos(mirror, r1_bio);
-
-       /*
-        * we have only one bio on the read side
-        */
-       if (uptodate)
                raid_end_bio_io(r1_bio);
-       else {
+       } else {
                /*
                 * oops, read error:
                 */
        wake_up(&conf->wait_barrier);
 }
 
+static void freeze_array(conf_t *conf)
+{
+       /* stop syncio and normal IO and wait for everything to
+        * go quite.
+        * We increment barrier and nr_waiting, and then
+        * wait until barrier+nr_pending match nr_queued+2
+        */
+       spin_lock_irq(&conf->resync_lock);
+       conf->barrier++;
+       conf->nr_waiting++;
+       wait_event_lock_irq(conf->wait_barrier,
+                           conf->barrier+conf->nr_pending == conf->nr_queued+2,
+                           conf->resync_lock,
+                           raid1_unplug(conf->mddev->queue));
+       spin_unlock_irq(&conf->resync_lock);
+}
+static void unfreeze_array(conf_t *conf)
+{
+       /* reverse the effect of the freeze */
+       spin_lock_irq(&conf->resync_lock);
+       conf->barrier--;
+       conf->nr_waiting--;
+       wake_up(&conf->wait_barrier);
+       spin_unlock_irq(&conf->resync_lock);
+}
+
 
 /* duplicate the data pages for behind I/O */
 static struct page **alloc_behind_pages(struct bio *bio)
                        break;
                r1_bio = list_entry(head->prev, r1bio_t, retry_list);
                list_del(head->prev);
+               conf->nr_queued--;
                spin_unlock_irqrestore(&conf->device_lock, flags);
 
                mddev = r1_bio->mddev;
                                }
                } else {
                        int disk;
+
+                       /* we got a read error. Maybe the drive is bad.  Maybe just
+                        * the block and we can fix it.
+                        * We freeze all other IO, and try reading the block from
+                        * other devices.  When we find one, we re-write
+                        * and check it that fixes the read error.
+                        * This is all done synchronously while the array is
+                        * frozen
+                        */
+                       sector_t sect = r1_bio->sector;
+                       int sectors = r1_bio->sectors;
+                       freeze_array(conf);
+                       while(sectors) {
+                               int s = sectors;
+                               int d = r1_bio->read_disk;
+                               int success = 0;
+
+                               if (s > (PAGE_SIZE>>9))
+                                       s = PAGE_SIZE >> 9;
+
+                               do {
+                                       rdev = conf->mirrors[d].rdev;
+                                       if (rdev &&
+                                           test_bit(In_sync, &rdev->flags) &&
+                                           sync_page_io(rdev->bdev,
+                                                        sect + rdev->data_offset,
+                                                        s<<9,
+                                                        conf->tmppage, READ))
+                                               success = 1;
+                                       else {
+                                               d++;
+                                               if (d == conf->raid_disks)
+                                                       d = 0;
+                                       }
+                               } while (!success && d != r1_bio->read_disk);
+
+                               if (success) {
+                                       /* write it back and re-read */
+                                       while (d != r1_bio->read_disk) {
+                                               if (d==0)
+                                                       d = conf->raid_disks;
+                                               d--;
+                                               rdev = conf->mirrors[d].rdev;
+                                               if (rdev &&
+                                                   test_bit(In_sync, &rdev->flags)) {
+                                                       if (sync_page_io(rdev->bdev,
+                                                                        sect + rdev->data_offset,
+                                                                        s<<9, conf->tmppage, WRITE) == 0 ||
+                                                           sync_page_io(rdev->bdev,
+                                                                        sect + rdev->data_offset,
+                                                                        s<<9, conf->tmppage, READ) == 0) {
+                                                               /* Well, this device is dead */
+                                                               md_error(mddev, rdev);
+                                                       }
+                                               }
+                                       }
+                               } else {
+                                       /* Cannot read from anywhere -- bye bye array */
+                                       md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
+                                       break;
+                               }
+                               sectors -= s;
+                               sect += s;
+                       }
+
+
+                       unfreeze_array(conf);
+
                        bio = r1_bio->bios[r1_bio->read_disk];
                        if ((disk=read_balance(conf, r1_bio)) == -1) {
                                printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
 
        memset(conf->mirrors, 0, sizeof(struct mirror_info)*mddev->raid_disks);
 
+       conf->tmppage = alloc_page(GFP_KERNEL);
+       if (!conf->tmppage)
+               goto out_no_mem;
+
        conf->poolinfo = kmalloc(sizeof(*conf->poolinfo), GFP_KERNEL);
        if (!conf->poolinfo)
                goto out_no_mem;
                if (conf->r1bio_pool)
                        mempool_destroy(conf->r1bio_pool);
                kfree(conf->mirrors);
+               __free_page(conf->tmppage);
                kfree(conf->poolinfo);
                kfree(conf);
                mddev->private = NULL;