[TG3]: Fix tx race condition
[linux-2.6-microblaze.git] / drivers / md / raid1.c
index 4070eff..1efe22a 100644 (file)
@@ -374,26 +374,26 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
         * already.
         */
        if (atomic_dec_and_test(&r1_bio->remaining)) {
-               if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) {
+               if (test_bit(R1BIO_BarrierRetry, &r1_bio->state))
                        reschedule_retry(r1_bio);
-                       goto out;
-               }
-               /* it really is the end of this request */
-               if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
-                       /* free extra copy of the data pages */
-                       int i = bio->bi_vcnt;
-                       while (i--)
-                               safe_put_page(bio->bi_io_vec[i].bv_page);
+               else {
+                       /* it really is the end of this request */
+                       if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
+                               /* free extra copy of the data pages */
+                               int i = bio->bi_vcnt;
+                               while (i--)
+                                       safe_put_page(bio->bi_io_vec[i].bv_page);
+                       }
+                       /* clear the bitmap if all writes complete successfully */
+                       bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
+                                       r1_bio->sectors,
+                                       !test_bit(R1BIO_Degraded, &r1_bio->state),
+                                       behind);
+                       md_write_end(r1_bio->mddev);
+                       raid_end_bio_io(r1_bio);
                }
-               /* clear the bitmap if all writes complete successfully */
-               bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
-                               r1_bio->sectors,
-                               !test_bit(R1BIO_Degraded, &r1_bio->state),
-                               behind);
-               md_write_end(r1_bio->mddev);
-               raid_end_bio_io(r1_bio);
        }
- out:
+
        if (to_put)
                bio_put(to_put);
 
@@ -1145,7 +1145,7 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error)
                long sectors_to_go = r1_bio->sectors;
                /* make sure these bits doesn't get cleared. */
                do {
-                       bitmap_end_sync(mddev->bitmap, r1_bio->sector,
+                       bitmap_end_sync(mddev->bitmap, s,
                                        &sync_blocks, 1);
                        s += sync_blocks;
                        sectors_to_go -= sync_blocks;
@@ -1509,6 +1509,9 @@ static void raid1d(mddev_t *mddev)
                                                                         s<<9, conf->tmppage, READ) == 0)
                                                                /* Well, this device is dead */
                                                                md_error(mddev, rdev);
+                                                       else
+                                                               printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n",
+                                                                      mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b));
                                                }
                                        }
                                } else {
@@ -1625,6 +1628,12 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
        /* before building a request, check if we can skip these blocks..
         * This call the bitmap_start_sync doesn't actually record anything
         */
+       if (mddev->bitmap == NULL &&
+           mddev->recovery_cp == MaxSector &&
+           conf->fullsync == 0) {
+               *skipped = 1;
+               return max_sector - sector_nr;
+       }
        if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
            !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
                /* We can skip this block, and probably several more */
@@ -1888,7 +1897,8 @@ static int run(mddev_t *mddev)
 
                disk = conf->mirrors + i;
 
-               if (!disk->rdev) {
+               if (!disk->rdev ||
+                   !test_bit(In_sync, &disk->rdev->flags)) {
                        disk->head_position = 0;
                        mddev->degraded++;
                }