aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r--drivers/md/raid1.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index ac409b7d83f5..c610b947218a 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -773,7 +773,7 @@ static int make_request(struct request_queue *q, struct bio * bio)
773 r1bio_t *r1_bio; 773 r1bio_t *r1_bio;
774 struct bio *read_bio; 774 struct bio *read_bio;
775 int i, targets = 0, disks; 775 int i, targets = 0, disks;
776 struct bitmap *bitmap = mddev->bitmap; 776 struct bitmap *bitmap;
777 unsigned long flags; 777 unsigned long flags;
778 struct bio_list bl; 778 struct bio_list bl;
779 struct page **behind_pages = NULL; 779 struct page **behind_pages = NULL;
@@ -802,6 +802,8 @@ static int make_request(struct request_queue *q, struct bio * bio)
802 802
803 wait_barrier(conf); 803 wait_barrier(conf);
804 804
805 bitmap = mddev->bitmap;
806
805 disk_stat_inc(mddev->gendisk, ios[rw]); 807 disk_stat_inc(mddev->gendisk, ios[rw]);
806 disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio)); 808 disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bio));
807 809
@@ -1025,7 +1027,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
1025 /* 1027 /*
1026 * if recovery is running, make sure it aborts. 1028 * if recovery is running, make sure it aborts.
1027 */ 1029 */
1028 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 1030 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
1029 } else 1031 } else
1030 set_bit(Faulty, &rdev->flags); 1032 set_bit(Faulty, &rdev->flags);
1031 set_bit(MD_CHANGE_DEVS, &mddev->flags); 1033 set_bit(MD_CHANGE_DEVS, &mddev->flags);
@@ -1146,6 +1148,14 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
1146 err = -EBUSY; 1148 err = -EBUSY;
1147 goto abort; 1149 goto abort;
1148 } 1150 }
1151 /* Only remove non-faulty devices is recovery
1152 * is not possible.
1153 */
1154 if (!test_bit(Faulty, &rdev->flags) &&
1155 mddev->degraded < conf->raid_disks) {
1156 err = -EBUSY;
1157 goto abort;
1158 }
1149 p->rdev = NULL; 1159 p->rdev = NULL;
1150 synchronize_rcu(); 1160 synchronize_rcu();
1151 if (atomic_read(&rdev->nr_pending)) { 1161 if (atomic_read(&rdev->nr_pending)) {
@@ -1282,6 +1292,7 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
1282 rdev_dec_pending(conf->mirrors[i].rdev, mddev); 1292 rdev_dec_pending(conf->mirrors[i].rdev, mddev);
1283 } else { 1293 } else {
1284 /* fixup the bio for reuse */ 1294 /* fixup the bio for reuse */
1295 int size;
1285 sbio->bi_vcnt = vcnt; 1296 sbio->bi_vcnt = vcnt;
1286 sbio->bi_size = r1_bio->sectors << 9; 1297 sbio->bi_size = r1_bio->sectors << 9;
1287 sbio->bi_idx = 0; 1298 sbio->bi_idx = 0;
@@ -1295,10 +1306,20 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
1295 sbio->bi_sector = r1_bio->sector + 1306 sbio->bi_sector = r1_bio->sector +
1296 conf->mirrors[i].rdev->data_offset; 1307 conf->mirrors[i].rdev->data_offset;
1297 sbio->bi_bdev = conf->mirrors[i].rdev->bdev; 1308 sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
1298 for (j = 0; j < vcnt ; j++) 1309 size = sbio->bi_size;
1299 memcpy(page_address(sbio->bi_io_vec[j].bv_page), 1310 for (j = 0; j < vcnt ; j++) {
1311 struct bio_vec *bi;
1312 bi = &sbio->bi_io_vec[j];
1313 bi->bv_offset = 0;
1314 if (size > PAGE_SIZE)
1315 bi->bv_len = PAGE_SIZE;
1316 else
1317 bi->bv_len = size;
1318 size -= PAGE_SIZE;
1319 memcpy(page_address(bi->bv_page),
1300 page_address(pbio->bi_io_vec[j].bv_page), 1320 page_address(pbio->bi_io_vec[j].bv_page),
1301 PAGE_SIZE); 1321 PAGE_SIZE);
1322 }
1302 1323
1303 } 1324 }
1304 } 1325 }