diff options
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r-- | drivers/md/raid1.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 55951182af73..6e17f8181c4b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -417,7 +417,17 @@ static void raid1_end_write_request(struct bio *bio, int error) | |||
417 | 417 | ||
418 | r1_bio->bios[mirror] = NULL; | 418 | r1_bio->bios[mirror] = NULL; |
419 | to_put = bio; | 419 | to_put = bio; |
420 | set_bit(R1BIO_Uptodate, &r1_bio->state); | 420 | /* |
421 | * Do not set R1BIO_Uptodate if the current device is | ||
422 | * rebuilding or Faulty. This is because we cannot use | ||
423 | * such device for properly reading the data back (we could | ||
424 | * potentially use it, if the current write would have felt | ||
425 | * before rdev->recovery_offset, but for simplicity we don't | ||
426 | * check this here. | ||
427 | */ | ||
428 | if (test_bit(In_sync, &conf->mirrors[mirror].rdev->flags) && | ||
429 | !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags)) | ||
430 | set_bit(R1BIO_Uptodate, &r1_bio->state); | ||
421 | 431 | ||
422 | /* Maybe we can clear some bad blocks. */ | 432 | /* Maybe we can clear some bad blocks. */ |
423 | if (is_badblock(conf->mirrors[mirror].rdev, | 433 | if (is_badblock(conf->mirrors[mirror].rdev, |
@@ -870,17 +880,17 @@ static void allow_barrier(struct r1conf *conf) | |||
870 | wake_up(&conf->wait_barrier); | 880 | wake_up(&conf->wait_barrier); |
871 | } | 881 | } |
872 | 882 | ||
873 | static void freeze_array(struct r1conf *conf) | 883 | static void freeze_array(struct r1conf *conf, int extra) |
874 | { | 884 | { |
875 | /* stop syncio and normal IO and wait for everything to | 885 | /* stop syncio and normal IO and wait for everything to |
876 | * go quite. | 886 | * go quite. |
877 | * We increment barrier and nr_waiting, and then | 887 | * We increment barrier and nr_waiting, and then |
878 | * wait until nr_pending match nr_queued+1 | 888 | * wait until nr_pending match nr_queued+extra |
879 | * This is called in the context of one normal IO request | 889 | * This is called in the context of one normal IO request |
880 | * that has failed. Thus any sync request that might be pending | 890 | * that has failed. Thus any sync request that might be pending |
881 | * will be blocked by nr_pending, and we need to wait for | 891 | * will be blocked by nr_pending, and we need to wait for |
882 | * pending IO requests to complete or be queued for re-try. | 892 | * pending IO requests to complete or be queued for re-try. |
883 | * Thus the number queued (nr_queued) plus this request (1) | 893 | * Thus the number queued (nr_queued) plus this request (extra) |
884 | * must match the number of pending IOs (nr_pending) before | 894 | * must match the number of pending IOs (nr_pending) before |
885 | * we continue. | 895 | * we continue. |
886 | */ | 896 | */ |
@@ -888,7 +898,7 @@ static void freeze_array(struct r1conf *conf) | |||
888 | conf->barrier++; | 898 | conf->barrier++; |
889 | conf->nr_waiting++; | 899 | conf->nr_waiting++; |
890 | wait_event_lock_irq_cmd(conf->wait_barrier, | 900 | wait_event_lock_irq_cmd(conf->wait_barrier, |
891 | conf->nr_pending == conf->nr_queued+1, | 901 | conf->nr_pending == conf->nr_queued+extra, |
892 | conf->resync_lock, | 902 | conf->resync_lock, |
893 | flush_pending_writes(conf)); | 903 | flush_pending_writes(conf)); |
894 | spin_unlock_irq(&conf->resync_lock); | 904 | spin_unlock_irq(&conf->resync_lock); |
@@ -1544,8 +1554,8 @@ static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev) | |||
1544 | * we wait for all outstanding requests to complete. | 1554 | * we wait for all outstanding requests to complete. |
1545 | */ | 1555 | */ |
1546 | synchronize_sched(); | 1556 | synchronize_sched(); |
1547 | raise_barrier(conf); | 1557 | freeze_array(conf, 0); |
1548 | lower_barrier(conf); | 1558 | unfreeze_array(conf); |
1549 | clear_bit(Unmerged, &rdev->flags); | 1559 | clear_bit(Unmerged, &rdev->flags); |
1550 | } | 1560 | } |
1551 | md_integrity_add_rdev(rdev, mddev); | 1561 | md_integrity_add_rdev(rdev, mddev); |
@@ -1595,11 +1605,11 @@ static int raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev) | |||
1595 | */ | 1605 | */ |
1596 | struct md_rdev *repl = | 1606 | struct md_rdev *repl = |
1597 | conf->mirrors[conf->raid_disks + number].rdev; | 1607 | conf->mirrors[conf->raid_disks + number].rdev; |
1598 | raise_barrier(conf); | 1608 | freeze_array(conf, 0); |
1599 | clear_bit(Replacement, &repl->flags); | 1609 | clear_bit(Replacement, &repl->flags); |
1600 | p->rdev = repl; | 1610 | p->rdev = repl; |
1601 | conf->mirrors[conf->raid_disks + number].rdev = NULL; | 1611 | conf->mirrors[conf->raid_disks + number].rdev = NULL; |
1602 | lower_barrier(conf); | 1612 | unfreeze_array(conf); |
1603 | clear_bit(WantReplacement, &rdev->flags); | 1613 | clear_bit(WantReplacement, &rdev->flags); |
1604 | } else | 1614 | } else |
1605 | clear_bit(WantReplacement, &rdev->flags); | 1615 | clear_bit(WantReplacement, &rdev->flags); |
@@ -2195,7 +2205,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio) | |||
2195 | * frozen | 2205 | * frozen |
2196 | */ | 2206 | */ |
2197 | if (mddev->ro == 0) { | 2207 | if (mddev->ro == 0) { |
2198 | freeze_array(conf); | 2208 | freeze_array(conf, 1); |
2199 | fix_read_error(conf, r1_bio->read_disk, | 2209 | fix_read_error(conf, r1_bio->read_disk, |
2200 | r1_bio->sector, r1_bio->sectors); | 2210 | r1_bio->sector, r1_bio->sectors); |
2201 | unfreeze_array(conf); | 2211 | unfreeze_array(conf); |
@@ -2780,8 +2790,8 @@ static int run(struct mddev *mddev) | |||
2780 | return PTR_ERR(conf); | 2790 | return PTR_ERR(conf); |
2781 | 2791 | ||
2782 | if (mddev->queue) | 2792 | if (mddev->queue) |
2783 | blk_queue_max_write_same_sectors(mddev->queue, | 2793 | blk_queue_max_write_same_sectors(mddev->queue, 0); |
2784 | mddev->chunk_sectors); | 2794 | |
2785 | rdev_for_each(rdev, mddev) { | 2795 | rdev_for_each(rdev, mddev) { |
2786 | if (!mddev->gendisk) | 2796 | if (!mddev->gendisk) |
2787 | continue; | 2797 | continue; |
@@ -2963,7 +2973,7 @@ static int raid1_reshape(struct mddev *mddev) | |||
2963 | return -ENOMEM; | 2973 | return -ENOMEM; |
2964 | } | 2974 | } |
2965 | 2975 | ||
2966 | raise_barrier(conf); | 2976 | freeze_array(conf, 0); |
2967 | 2977 | ||
2968 | /* ok, everything is stopped */ | 2978 | /* ok, everything is stopped */ |
2969 | oldpool = conf->r1bio_pool; | 2979 | oldpool = conf->r1bio_pool; |
@@ -2994,7 +3004,7 @@ static int raid1_reshape(struct mddev *mddev) | |||
2994 | conf->raid_disks = mddev->raid_disks = raid_disks; | 3004 | conf->raid_disks = mddev->raid_disks = raid_disks; |
2995 | mddev->delta_disks = 0; | 3005 | mddev->delta_disks = 0; |
2996 | 3006 | ||
2997 | lower_barrier(conf); | 3007 | unfreeze_array(conf); |
2998 | 3008 | ||
2999 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 3009 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
3000 | md_wakeup_thread(mddev->thread); | 3010 | md_wakeup_thread(mddev->thread); |