aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/raid1.c18
-rw-r--r--include/linux/raid/raid1.h7
2 files changed, 18 insertions, 7 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 14a8fe0349c7..a8bc93d6ff63 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -154,7 +154,7 @@ static void put_all_bios(conf_t *conf, r1bio_t *r1_bio)
154 154
155 for (i = 0; i < conf->raid_disks; i++) { 155 for (i = 0; i < conf->raid_disks; i++) {
156 struct bio **bio = r1_bio->bios + i; 156 struct bio **bio = r1_bio->bios + i;
157 if (*bio) 157 if (*bio && *bio != IO_BLOCKED)
158 bio_put(*bio); 158 bio_put(*bio);
159 *bio = NULL; 159 *bio = NULL;
160 } 160 }
@@ -419,11 +419,13 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
419 new_disk = 0; 419 new_disk = 0;
420 420
421 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); 421 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
422 r1_bio->bios[new_disk] == IO_BLOCKED ||
422 !rdev || !test_bit(In_sync, &rdev->flags) 423 !rdev || !test_bit(In_sync, &rdev->flags)
423 || test_bit(WriteMostly, &rdev->flags); 424 || test_bit(WriteMostly, &rdev->flags);
424 rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) { 425 rdev = rcu_dereference(conf->mirrors[++new_disk].rdev)) {
425 426
426 if (rdev && test_bit(In_sync, &rdev->flags)) 427 if (rdev && test_bit(In_sync, &rdev->flags) &&
428 r1_bio->bios[new_disk] != IO_BLOCKED)
427 wonly_disk = new_disk; 429 wonly_disk = new_disk;
428 430
429 if (new_disk == conf->raid_disks - 1) { 431 if (new_disk == conf->raid_disks - 1) {
@@ -437,11 +439,13 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
437 439
438 /* make sure the disk is operational */ 440 /* make sure the disk is operational */
439 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev); 441 for (rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
442 r1_bio->bios[new_disk] == IO_BLOCKED ||
440 !rdev || !test_bit(In_sync, &rdev->flags) || 443 !rdev || !test_bit(In_sync, &rdev->flags) ||
441 test_bit(WriteMostly, &rdev->flags); 444 test_bit(WriteMostly, &rdev->flags);
442 rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) { 445 rdev = rcu_dereference(conf->mirrors[new_disk].rdev)) {
443 446
444 if (rdev && test_bit(In_sync, &rdev->flags)) 447 if (rdev && test_bit(In_sync, &rdev->flags) &&
448 r1_bio->bios[new_disk] != IO_BLOCKED)
445 wonly_disk = new_disk; 449 wonly_disk = new_disk;
446 450
447 if (new_disk <= 0) 451 if (new_disk <= 0)
@@ -478,7 +482,7 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio)
478 482
479 rdev = rcu_dereference(conf->mirrors[disk].rdev); 483 rdev = rcu_dereference(conf->mirrors[disk].rdev);
480 484
481 if (!rdev || 485 if (!rdev || r1_bio->bios[disk] == IO_BLOCKED ||
482 !test_bit(In_sync, &rdev->flags) || 486 !test_bit(In_sync, &rdev->flags) ||
483 test_bit(WriteMostly, &rdev->flags)) 487 test_bit(WriteMostly, &rdev->flags))
484 continue; 488 continue;
@@ -1335,7 +1339,7 @@ static void raid1d(mddev_t *mddev)
1335 sector_t sect = r1_bio->sector; 1339 sector_t sect = r1_bio->sector;
1336 int sectors = r1_bio->sectors; 1340 int sectors = r1_bio->sectors;
1337 freeze_array(conf); 1341 freeze_array(conf);
1338 while(sectors) { 1342 if (mddev->ro == 0) while(sectors) {
1339 int s = sectors; 1343 int s = sectors;
1340 int d = r1_bio->read_disk; 1344 int d = r1_bio->read_disk;
1341 int success = 0; 1345 int success = 0;
@@ -1388,7 +1392,6 @@ static void raid1d(mddev_t *mddev)
1388 sect += s; 1392 sect += s;
1389 } 1393 }
1390 1394
1391
1392 unfreeze_array(conf); 1395 unfreeze_array(conf);
1393 1396
1394 bio = r1_bio->bios[r1_bio->read_disk]; 1397 bio = r1_bio->bios[r1_bio->read_disk];
@@ -1399,7 +1402,8 @@ static void raid1d(mddev_t *mddev)
1399 (unsigned long long)r1_bio->sector); 1402 (unsigned long long)r1_bio->sector);
1400 raid_end_bio_io(r1_bio); 1403 raid_end_bio_io(r1_bio);
1401 } else { 1404 } else {
1402 r1_bio->bios[r1_bio->read_disk] = NULL; 1405 r1_bio->bios[r1_bio->read_disk] =
1406 mddev->ro ? IO_BLOCKED : NULL;
1403 r1_bio->read_disk = disk; 1407 r1_bio->read_disk = disk;
1404 bio_put(bio); 1408 bio_put(bio);
1405 bio = bio_clone(r1_bio->master_bio, GFP_NOIO); 1409 bio = bio_clone(r1_bio->master_bio, GFP_NOIO);
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
index cbe4238d3f9f..9d5494aaac0f 100644
--- a/include/linux/raid/raid1.h
+++ b/include/linux/raid/raid1.h
@@ -109,6 +109,13 @@ struct r1bio_s {
109 /* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/ 109 /* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/
110}; 110};
111 111
112/* when we get a read error on a read-only array, we redirect to another
113 * device without failing the first device, or trying to over-write to
114 * correct the read error. To keep track of bad blocks on a per-bio
115 * level, we store IO_BLOCKED in the appropriate 'bios' pointer
116 */
117#define IO_BLOCKED ((struct bio*)1)
118
112/* bits for r1bio.state */ 119/* bits for r1bio.state */
113#define R1BIO_Uptodate 0 120#define R1BIO_Uptodate 0
114#define R1BIO_IsSync 1 121#define R1BIO_IsSync 1