diff options
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r-- | drivers/md/raid10.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index bbe40e9cf923..867f06ae33d9 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -496,6 +496,7 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio) | |||
496 | int disk, slot, nslot; | 496 | int disk, slot, nslot; |
497 | const int sectors = r10_bio->sectors; | 497 | const int sectors = r10_bio->sectors; |
498 | sector_t new_distance, current_distance; | 498 | sector_t new_distance, current_distance; |
499 | mdk_rdev_t *rdev; | ||
499 | 500 | ||
500 | raid10_find_phys(conf, r10_bio); | 501 | raid10_find_phys(conf, r10_bio); |
501 | rcu_read_lock(); | 502 | rcu_read_lock(); |
@@ -510,8 +511,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio) | |||
510 | slot = 0; | 511 | slot = 0; |
511 | disk = r10_bio->devs[slot].devnum; | 512 | disk = r10_bio->devs[slot].devnum; |
512 | 513 | ||
513 | while (!conf->mirrors[disk].rdev || | 514 | while ((rdev = rcu_dereference(conf->mirrors[disk].rdev)) == NULL || |
514 | !conf->mirrors[disk].rdev->in_sync) { | 515 | !test_bit(In_sync, &rdev->flags)) { |
515 | slot++; | 516 | slot++; |
516 | if (slot == conf->copies) { | 517 | if (slot == conf->copies) { |
517 | slot = 0; | 518 | slot = 0; |
@@ -527,8 +528,8 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio) | |||
527 | /* make sure the disk is operational */ | 528 | /* make sure the disk is operational */ |
528 | slot = 0; | 529 | slot = 0; |
529 | disk = r10_bio->devs[slot].devnum; | 530 | disk = r10_bio->devs[slot].devnum; |
530 | while (!conf->mirrors[disk].rdev || | 531 | while ((rdev=rcu_dereference(conf->mirrors[disk].rdev)) == NULL || |
531 | !conf->mirrors[disk].rdev->in_sync) { | 532 | !test_bit(In_sync, &rdev->flags)) { |
532 | slot ++; | 533 | slot ++; |
533 | if (slot == conf->copies) { | 534 | if (slot == conf->copies) { |
534 | disk = -1; | 535 | disk = -1; |
@@ -547,11 +548,11 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio) | |||
547 | int ndisk = r10_bio->devs[nslot].devnum; | 548 | int ndisk = r10_bio->devs[nslot].devnum; |
548 | 549 | ||
549 | 550 | ||
550 | if (!conf->mirrors[ndisk].rdev || | 551 | if ((rdev=rcu_dereference(conf->mirrors[ndisk].rdev)) == NULL || |
551 | !conf->mirrors[ndisk].rdev->in_sync) | 552 | !test_bit(In_sync, &rdev->flags)) |
552 | continue; | 553 | continue; |
553 | 554 | ||
554 | if (!atomic_read(&conf->mirrors[ndisk].rdev->nr_pending)) { | 555 | if (!atomic_read(&rdev->nr_pending)) { |
555 | disk = ndisk; | 556 | disk = ndisk; |
556 | slot = nslot; | 557 | slot = nslot; |
557 | break; | 558 | break; |
@@ -569,7 +570,7 @@ rb_out: | |||
569 | r10_bio->read_slot = slot; | 570 | r10_bio->read_slot = slot; |
570 | /* conf->next_seq_sect = this_sector + sectors;*/ | 571 | /* conf->next_seq_sect = this_sector + sectors;*/ |
571 | 572 | ||
572 | if (disk >= 0 && conf->mirrors[disk].rdev) | 573 | if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL) |
573 | atomic_inc(&conf->mirrors[disk].rdev->nr_pending); | 574 | atomic_inc(&conf->mirrors[disk].rdev->nr_pending); |
574 | rcu_read_unlock(); | 575 | rcu_read_unlock(); |
575 | 576 | ||
@@ -583,8 +584,8 @@ static void unplug_slaves(mddev_t *mddev) | |||
583 | 584 | ||
584 | rcu_read_lock(); | 585 | rcu_read_lock(); |
585 | for (i=0; i<mddev->raid_disks; i++) { | 586 | for (i=0; i<mddev->raid_disks; i++) { |
586 | mdk_rdev_t *rdev = conf->mirrors[i].rdev; | 587 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); |
587 | if (rdev && !rdev->faulty && atomic_read(&rdev->nr_pending)) { | 588 | if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { |
588 | request_queue_t *r_queue = bdev_get_queue(rdev->bdev); | 589 | request_queue_t *r_queue = bdev_get_queue(rdev->bdev); |
589 | 590 | ||
590 | atomic_inc(&rdev->nr_pending); | 591 | atomic_inc(&rdev->nr_pending); |
@@ -614,8 +615,8 @@ static int raid10_issue_flush(request_queue_t *q, struct gendisk *disk, | |||
614 | 615 | ||
615 | rcu_read_lock(); | 616 | rcu_read_lock(); |
616 | for (i=0; i<mddev->raid_disks && ret == 0; i++) { | 617 | for (i=0; i<mddev->raid_disks && ret == 0; i++) { |
617 | mdk_rdev_t *rdev = conf->mirrors[i].rdev; | 618 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); |
618 | if (rdev && !rdev->faulty) { | 619 | if (rdev && !test_bit(Faulty, &rdev->flags)) { |
619 | struct block_device *bdev = rdev->bdev; | 620 | struct block_device *bdev = rdev->bdev; |
620 | request_queue_t *r_queue = bdev_get_queue(bdev); | 621 | request_queue_t *r_queue = bdev_get_queue(bdev); |
621 | 622 | ||
@@ -768,9 +769,10 @@ static int make_request(request_queue_t *q, struct bio * bio) | |||
768 | rcu_read_lock(); | 769 | rcu_read_lock(); |
769 | for (i = 0; i < conf->copies; i++) { | 770 | for (i = 0; i < conf->copies; i++) { |
770 | int d = r10_bio->devs[i].devnum; | 771 | int d = r10_bio->devs[i].devnum; |
771 | if (conf->mirrors[d].rdev && | 772 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[d].rdev); |
772 | !conf->mirrors[d].rdev->faulty) { | 773 | if (rdev && |
773 | atomic_inc(&conf->mirrors[d].rdev->nr_pending); | 774 | !test_bit(Faulty, &rdev->flags)) { |
775 | atomic_inc(&rdev->nr_pending); | ||
774 | r10_bio->devs[i].bio = bio; | 776 | r10_bio->devs[i].bio = bio; |
775 | } else | 777 | } else |
776 | r10_bio->devs[i].bio = NULL; | 778 | r10_bio->devs[i].bio = NULL; |
@@ -824,7 +826,7 @@ static void status(struct seq_file *seq, mddev_t *mddev) | |||
824 | for (i = 0; i < conf->raid_disks; i++) | 826 | for (i = 0; i < conf->raid_disks; i++) |
825 | seq_printf(seq, "%s", | 827 | seq_printf(seq, "%s", |
826 | conf->mirrors[i].rdev && | 828 | conf->mirrors[i].rdev && |
827 | conf->mirrors[i].rdev->in_sync ? "U" : "_"); | 829 | test_bit(In_sync, &conf->mirrors[i].rdev->flags) ? "U" : "_"); |
828 | seq_printf(seq, "]"); | 830 | seq_printf(seq, "]"); |
829 | } | 831 | } |
830 | 832 | ||
@@ -839,7 +841,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
839 | * next level up know. | 841 | * next level up know. |
840 | * else mark the drive as failed | 842 | * else mark the drive as failed |
841 | */ | 843 | */ |
842 | if (rdev->in_sync | 844 | if (test_bit(In_sync, &rdev->flags) |
843 | && conf->working_disks == 1) | 845 | && conf->working_disks == 1) |
844 | /* | 846 | /* |
845 | * Don't fail the drive, just return an IO error. | 847 | * Don't fail the drive, just return an IO error. |
@@ -849,7 +851,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
849 | * really dead" tests... | 851 | * really dead" tests... |
850 | */ | 852 | */ |
851 | return; | 853 | return; |
852 | if (rdev->in_sync) { | 854 | if (test_bit(In_sync, &rdev->flags)) { |
853 | mddev->degraded++; | 855 | mddev->degraded++; |
854 | conf->working_disks--; | 856 | conf->working_disks--; |
855 | /* | 857 | /* |
@@ -857,8 +859,8 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
857 | */ | 859 | */ |
858 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 860 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); |
859 | } | 861 | } |
860 | rdev->in_sync = 0; | 862 | clear_bit(In_sync, &rdev->flags); |
861 | rdev->faulty = 1; | 863 | set_bit(Faulty, &rdev->flags); |
862 | mddev->sb_dirty = 1; | 864 | mddev->sb_dirty = 1; |
863 | printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n" | 865 | printk(KERN_ALERT "raid10: Disk failure on %s, disabling device. \n" |
864 | " Operation continuing on %d devices\n", | 866 | " Operation continuing on %d devices\n", |
@@ -883,7 +885,8 @@ static void print_conf(conf_t *conf) | |||
883 | tmp = conf->mirrors + i; | 885 | tmp = conf->mirrors + i; |
884 | if (tmp->rdev) | 886 | if (tmp->rdev) |
885 | printk(" disk %d, wo:%d, o:%d, dev:%s\n", | 887 | printk(" disk %d, wo:%d, o:%d, dev:%s\n", |
886 | i, !tmp->rdev->in_sync, !tmp->rdev->faulty, | 888 | i, !test_bit(In_sync, &tmp->rdev->flags), |
889 | !test_bit(Faulty, &tmp->rdev->flags), | ||
887 | bdevname(tmp->rdev->bdev,b)); | 890 | bdevname(tmp->rdev->bdev,b)); |
888 | } | 891 | } |
889 | } | 892 | } |
@@ -936,11 +939,11 @@ static int raid10_spare_active(mddev_t *mddev) | |||
936 | for (i = 0; i < conf->raid_disks; i++) { | 939 | for (i = 0; i < conf->raid_disks; i++) { |
937 | tmp = conf->mirrors + i; | 940 | tmp = conf->mirrors + i; |
938 | if (tmp->rdev | 941 | if (tmp->rdev |
939 | && !tmp->rdev->faulty | 942 | && !test_bit(Faulty, &tmp->rdev->flags) |
940 | && !tmp->rdev->in_sync) { | 943 | && !test_bit(In_sync, &tmp->rdev->flags)) { |
941 | conf->working_disks++; | 944 | conf->working_disks++; |
942 | mddev->degraded--; | 945 | mddev->degraded--; |
943 | tmp->rdev->in_sync = 1; | 946 | set_bit(In_sync, &tmp->rdev->flags); |
944 | } | 947 | } |
945 | } | 948 | } |
946 | 949 | ||
@@ -980,7 +983,7 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
980 | p->head_position = 0; | 983 | p->head_position = 0; |
981 | rdev->raid_disk = mirror; | 984 | rdev->raid_disk = mirror; |
982 | found = 1; | 985 | found = 1; |
983 | p->rdev = rdev; | 986 | rcu_assign_pointer(p->rdev, rdev); |
984 | break; | 987 | break; |
985 | } | 988 | } |
986 | 989 | ||
@@ -998,7 +1001,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number) | |||
998 | print_conf(conf); | 1001 | print_conf(conf); |
999 | rdev = p->rdev; | 1002 | rdev = p->rdev; |
1000 | if (rdev) { | 1003 | if (rdev) { |
1001 | if (rdev->in_sync || | 1004 | if (test_bit(In_sync, &rdev->flags) || |
1002 | atomic_read(&rdev->nr_pending)) { | 1005 | atomic_read(&rdev->nr_pending)) { |
1003 | err = -EBUSY; | 1006 | err = -EBUSY; |
1004 | goto abort; | 1007 | goto abort; |
@@ -1414,7 +1417,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1414 | 1417 | ||
1415 | for (i=0 ; i<conf->raid_disks; i++) | 1418 | for (i=0 ; i<conf->raid_disks; i++) |
1416 | if (conf->mirrors[i].rdev && | 1419 | if (conf->mirrors[i].rdev && |
1417 | !conf->mirrors[i].rdev->in_sync) { | 1420 | !test_bit(In_sync, &conf->mirrors[i].rdev->flags)) { |
1418 | /* want to reconstruct this device */ | 1421 | /* want to reconstruct this device */ |
1419 | r10bio_t *rb2 = r10_bio; | 1422 | r10bio_t *rb2 = r10_bio; |
1420 | 1423 | ||
@@ -1435,7 +1438,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1435 | for (j=0; j<conf->copies;j++) { | 1438 | for (j=0; j<conf->copies;j++) { |
1436 | int d = r10_bio->devs[j].devnum; | 1439 | int d = r10_bio->devs[j].devnum; |
1437 | if (conf->mirrors[d].rdev && | 1440 | if (conf->mirrors[d].rdev && |
1438 | conf->mirrors[d].rdev->in_sync) { | 1441 | test_bit(In_sync, &conf->mirrors[d].rdev->flags)) { |
1439 | /* This is where we read from */ | 1442 | /* This is where we read from */ |
1440 | bio = r10_bio->devs[0].bio; | 1443 | bio = r10_bio->devs[0].bio; |
1441 | bio->bi_next = biolist; | 1444 | bio->bi_next = biolist; |
@@ -1511,7 +1514,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1511 | bio = r10_bio->devs[i].bio; | 1514 | bio = r10_bio->devs[i].bio; |
1512 | bio->bi_end_io = NULL; | 1515 | bio->bi_end_io = NULL; |
1513 | if (conf->mirrors[d].rdev == NULL || | 1516 | if (conf->mirrors[d].rdev == NULL || |
1514 | conf->mirrors[d].rdev->faulty) | 1517 | test_bit(Faulty, &conf->mirrors[d].rdev->flags)) |
1515 | continue; | 1518 | continue; |
1516 | atomic_inc(&conf->mirrors[d].rdev->nr_pending); | 1519 | atomic_inc(&conf->mirrors[d].rdev->nr_pending); |
1517 | atomic_inc(&r10_bio->remaining); | 1520 | atomic_inc(&r10_bio->remaining); |
@@ -1697,7 +1700,7 @@ static int run(mddev_t *mddev) | |||
1697 | mddev->queue->max_sectors = (PAGE_SIZE>>9); | 1700 | mddev->queue->max_sectors = (PAGE_SIZE>>9); |
1698 | 1701 | ||
1699 | disk->head_position = 0; | 1702 | disk->head_position = 0; |
1700 | if (!rdev->faulty && rdev->in_sync) | 1703 | if (!test_bit(Faulty, &rdev->flags) && test_bit(In_sync, &rdev->flags)) |
1701 | conf->working_disks++; | 1704 | conf->working_disks++; |
1702 | } | 1705 | } |
1703 | conf->raid_disks = mddev->raid_disks; | 1706 | conf->raid_disks = mddev->raid_disks; |