Merge ../linux-2.6-watchdog-mm
[pandora-kernel.git] / drivers / md / raid1.c
index dc9d2de..97ee870 100644 (file)
@@ -775,6 +775,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
        struct bio_list bl;
        struct page **behind_pages = NULL;
        const int rw = bio_data_dir(bio);
+       const int do_sync = bio_sync(bio);
        int do_barriers;
 
        /*
@@ -835,7 +836,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
                read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset;
                read_bio->bi_bdev = mirror->rdev->bdev;
                read_bio->bi_end_io = raid1_end_read_request;
-               read_bio->bi_rw = READ;
+               read_bio->bi_rw = READ | do_sync;
                read_bio->bi_private = r1_bio;
 
                generic_make_request(read_bio);
@@ -906,7 +907,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
                mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
                mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
                mbio->bi_end_io = raid1_end_write_request;
-               mbio->bi_rw = WRITE | do_barriers;
+               mbio->bi_rw = WRITE | do_barriers | do_sync;
                mbio->bi_private = r1_bio;
 
                if (behind_pages) {
@@ -941,6 +942,8 @@ static int make_request(request_queue_t *q, struct bio * bio)
        blk_plug_device(mddev->queue);
        spin_unlock_irqrestore(&conf->device_lock, flags);
 
+       if (do_sync)
+               md_wakeup_thread(mddev->thread);
 #if 0
        while ((bio = bio_list_pop(&bl)) != NULL)
                generic_make_request(bio);
@@ -1263,6 +1266,11 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
                                        sbio->bi_sector = r1_bio->sector +
                                                conf->mirrors[i].rdev->data_offset;
                                        sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
+                                       for (j = 0; j < vcnt ; j++)
+                                               memcpy(page_address(sbio->bi_io_vec[j].bv_page),
+                                                      page_address(pbio->bi_io_vec[j].bv_page),
+                                                      PAGE_SIZE);
+
                                }
                        }
        }
@@ -1474,8 +1482,8 @@ static void fix_read_error(conf_t *conf, int read_disk,
                                               "raid1:%s: read error corrected "
                                               "(%d sectors at %llu on %s)\n",
                                               mdname(mddev), s,
-                                              (unsigned long long)sect +
-                                                  rdev->data_offset,
+                                              (unsigned long long)(sect +
+                                                  rdev->data_offset),
                                               bdevname(rdev->bdev, b));
                                }
                        }
@@ -1541,6 +1549,7 @@ static void raid1d(mddev_t *mddev)
                         * We already have a nr_pending reference on these rdevs.
                         */
                        int i;
+                       const int do_sync = bio_sync(r1_bio->master_bio);
                        clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
                        clear_bit(R1BIO_Barrier, &r1_bio->state);
                        for (i=0; i < conf->raid_disks; i++)
@@ -1561,7 +1570,7 @@ static void raid1d(mddev_t *mddev)
                                                conf->mirrors[i].rdev->data_offset;
                                        bio->bi_bdev = conf->mirrors[i].rdev->bdev;
                                        bio->bi_end_io = raid1_end_write_request;
-                                       bio->bi_rw = WRITE;
+                                       bio->bi_rw = WRITE | do_sync;
                                        bio->bi_private = r1_bio;
                                        r1_bio->bios[i] = bio;
                                        generic_make_request(bio);
@@ -1593,6 +1602,7 @@ static void raid1d(mddev_t *mddev)
                                       (unsigned long long)r1_bio->sector);
                                raid_end_bio_io(r1_bio);
                        } else {
+                               const int do_sync = bio_sync(r1_bio->master_bio);
                                r1_bio->bios[r1_bio->read_disk] =
                                        mddev->ro ? IO_BLOCKED : NULL;
                                r1_bio->read_disk = disk;
@@ -1608,7 +1618,7 @@ static void raid1d(mddev_t *mddev)
                                bio->bi_sector = r1_bio->sector + rdev->data_offset;
                                bio->bi_bdev = rdev->bdev;
                                bio->bi_end_io = raid1_end_read_request;
-                               bio->bi_rw = READ;
+                               bio->bi_rw = READ | do_sync;
                                bio->bi_private = r1_bio;
                                unplug = 1;
                                generic_make_request(bio);
@@ -1736,7 +1746,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                /* take from bio_init */
                bio->bi_next = NULL;
                bio->bi_flags |= 1 << BIO_UPTODATE;
-               bio->bi_rw = 0;
+               bio->bi_rw = READ;
                bio->bi_vcnt = 0;
                bio->bi_idx = 0;
                bio->bi_phys_segments = 0;
@@ -1951,6 +1961,7 @@ static int run(mddev_t *mddev)
                    !test_bit(In_sync, &disk->rdev->flags)) {
                        disk->head_position = 0;
                        mddev->degraded++;
+                       conf->fullsync = 1;
                }
        }
        if (mddev->degraded == conf->raid_disks) {
@@ -2093,6 +2104,8 @@ static int raid1_reshape(mddev_t *mddev)
                return -EINVAL;
        }
 
+       md_allow_write(mddev);
+
        raid_disks = mddev->raid_disks + mddev->delta_disks;
 
        if (raid_disks < conf->raid_disks) {