ehea: Whitespace cleanup
[safe/jmp/linux-2.6] / drivers / md / raid1.c
index 1b7130c..46677d7 100644 (file)
@@ -271,21 +271,25 @@ static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int
         */
        update_head_pos(mirror, r1_bio);
 
-       if (uptodate || (conf->raid_disks - conf->mddev->degraded) <= 1) {
-               /*
-                * Set R1BIO_Uptodate in our master bio, so that
-                * we will return a good error code for to the higher
-                * levels even if IO on some other mirrored buffer fails.
-                *
-                * The 'master' represents the composite IO operation to
-                * user-side. So if something waits for IO, then it will
-                * wait for the 'master' bio.
+       if (uptodate)
+               set_bit(R1BIO_Uptodate, &r1_bio->state);
+       else {
+               /* If all other devices have failed, we want to return
+                * the error upwards rather than fail the last device.
+                * Here we redefine "uptodate" to mean "Don't want to retry"
                 */
-               if (uptodate)
-                       set_bit(R1BIO_Uptodate, &r1_bio->state);
+               unsigned long flags;
+               spin_lock_irqsave(&conf->device_lock, flags);
+               if (r1_bio->mddev->degraded == conf->raid_disks ||
+                   (r1_bio->mddev->degraded == conf->raid_disks-1 &&
+                    !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags)))
+                       uptodate = 1;
+               spin_unlock_irqrestore(&conf->device_lock, flags);
+       }
 
+       if (uptodate)
                raid_end_bio_io(r1_bio);
-       else {
+       else {
                /*
                 * oops, read error:
                 */
@@ -992,13 +996,14 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
                unsigned long flags;
                spin_lock_irqsave(&conf->device_lock, flags);
                mddev->degraded++;
+               set_bit(Faulty, &rdev->flags);
                spin_unlock_irqrestore(&conf->device_lock, flags);
                /*
                 * if recovery is running, make sure it aborts.
                 */
                set_bit(MD_RECOVERY_ERR, &mddev->recovery);
-       }
-       set_bit(Faulty, &rdev->flags);
+       } else
+               set_bit(Faulty, &rdev->flags);
        set_bit(MD_CHANGE_DEVS, &mddev->flags);
        printk(KERN_ALERT "raid1: Disk failure on %s, disabling device. \n"
                "       Operation continuing on %d devices\n",
@@ -1235,17 +1240,24 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
                        }
                r1_bio->read_disk = primary;
                for (i=0; i<mddev->raid_disks; i++)
-                       if (r1_bio->bios[i]->bi_end_io == end_sync_read &&
-                           test_bit(BIO_UPTODATE, &r1_bio->bios[i]->bi_flags)) {
+                       if (r1_bio->bios[i]->bi_end_io == end_sync_read) {
                                int j;
                                int vcnt = r1_bio->sectors >> (PAGE_SHIFT- 9);
                                struct bio *pbio = r1_bio->bios[primary];
                                struct bio *sbio = r1_bio->bios[i];
-                               for (j = vcnt; j-- ; )
-                                       if (memcmp(page_address(pbio->bi_io_vec[j].bv_page),
-                                                  page_address(sbio->bi_io_vec[j].bv_page),
-                                                  PAGE_SIZE))
-                                               break;
+
+                               if (test_bit(BIO_UPTODATE, &sbio->bi_flags)) {
+                                       for (j = vcnt; j-- ; ) {
+                                               struct page *p, *s;
+                                               p = pbio->bi_io_vec[j].bv_page;
+                                               s = sbio->bi_io_vec[j].bv_page;
+                                               if (memcmp(page_address(p),
+                                                          page_address(s),
+                                                          PAGE_SIZE))
+                                                       break;
+                                       }
+                               } else
+                                       j = 0;
                                if (j >= 0)
                                        mddev->resync_mismatches += r1_bio->sectors;
                                if (j < 0 || test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) {
@@ -2063,6 +2075,7 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors)
         */
        mddev->array_size = sectors>>1;
        set_capacity(mddev->gendisk, mddev->array_size << 1);
+       mddev->changed = 1;
        if (mddev->array_size > mddev->size && mddev->recovery_cp == MaxSector) {
                mddev->recovery_cp = mddev->size << 1;
                set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);