aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-26 21:00:36 -0400
committerNeilBrown <neilb@suse.de>2011-07-26 21:00:36 -0400
commit2bb77736ae5dca0a189829fbb7379d43364a9dac (patch)
treea15efb6810aaf67af679bd05edb5419ac9f19583 /drivers/md/raid10.c
parent5389042ffa36976caa45a79af16081d759001fa7 (diff)
md/raid10: Make use of new recovery_disabled handling
When we get a read error during recovery, RAID10 previously arranged for the recovering device to appear to fail so that the recovery stops and doesn't restart. This is misleading and wrong. Instead, make use of the new recovery_disabled handling and mark the target device and having recovery disabled. Add appropriate checks in add_disk and remove_disk so that devices are removed and not re-added when recovery is disabled. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 1725ec1e1e82..5583201e5cde 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1099,7 +1099,6 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
1099 conf_t *conf = mddev->private; 1099 conf_t *conf = mddev->private;
1100 int err = -EEXIST; 1100 int err = -EEXIST;
1101 int mirror; 1101 int mirror;
1102 mirror_info_t *p;
1103 int first = 0; 1102 int first = 0;
1104 int last = conf->raid_disks - 1; 1103 int last = conf->raid_disks - 1;
1105 1104
@@ -1119,32 +1118,36 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
1119 mirror = rdev->saved_raid_disk; 1118 mirror = rdev->saved_raid_disk;
1120 else 1119 else
1121 mirror = first; 1120 mirror = first;
1122 for ( ; mirror <= last ; mirror++) 1121 for ( ; mirror <= last ; mirror++) {
1123 if ( !(p=conf->mirrors+mirror)->rdev) { 1122 mirror_info_t *p = &conf->mirrors[mirror];
1124 1123 if (p->recovery_disabled == mddev->recovery_disabled)
1125 disk_stack_limits(mddev->gendisk, rdev->bdev, 1124 continue;
1126 rdev->data_offset << 9); 1125 if (!p->rdev)
1127 /* as we don't honour merge_bvec_fn, we must 1126 continue;
1128 * never risk violating it, so limit
1129 * ->max_segments to one lying with a single
1130 * page, as a one page request is never in
1131 * violation.
1132 */
1133 if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
1134 blk_queue_max_segments(mddev->queue, 1);
1135 blk_queue_segment_boundary(mddev->queue,
1136 PAGE_CACHE_SIZE - 1);
1137 }
1138 1127
1139 p->head_position = 0; 1128 disk_stack_limits(mddev->gendisk, rdev->bdev,
1140 rdev->raid_disk = mirror; 1129 rdev->data_offset << 9);
1141 err = 0; 1130 /* as we don't honour merge_bvec_fn, we must
1142 if (rdev->saved_raid_disk != mirror) 1131 * never risk violating it, so limit
1143 conf->fullsync = 1; 1132 * ->max_segments to one lying with a single
1144 rcu_assign_pointer(p->rdev, rdev); 1133 * page, as a one page request is never in
1145 break; 1134 * violation.
1135 */
1136 if (rdev->bdev->bd_disk->queue->merge_bvec_fn) {
1137 blk_queue_max_segments(mddev->queue, 1);
1138 blk_queue_segment_boundary(mddev->queue,
1139 PAGE_CACHE_SIZE - 1);
1146 } 1140 }
1147 1141
1142 p->head_position = 0;
1143 rdev->raid_disk = mirror;
1144 err = 0;
1145 if (rdev->saved_raid_disk != mirror)
1146 conf->fullsync = 1;
1147 rcu_assign_pointer(p->rdev, rdev);
1148 break;
1149 }
1150
1148 md_integrity_add_rdev(rdev, mddev); 1151 md_integrity_add_rdev(rdev, mddev);
1149 print_conf(conf); 1152 print_conf(conf);
1150 return err; 1153 return err;
@@ -1169,6 +1172,7 @@ static int raid10_remove_disk(mddev_t *mddev, int number)
1169 * is not possible. 1172 * is not possible.
1170 */ 1173 */
1171 if (!test_bit(Faulty, &rdev->flags) && 1174 if (!test_bit(Faulty, &rdev->flags) &&
1175 mddev->recovery_disabled != p->recovery_disabled &&
1172 enough(conf)) { 1176 enough(conf)) {
1173 err = -EBUSY; 1177 err = -EBUSY;
1174 goto abort; 1178 goto abort;
@@ -1383,8 +1387,14 @@ static void recovery_request_write(mddev_t *mddev, r10bio_t *r10_bio)
1383 md_sync_acct(conf->mirrors[d].rdev->bdev, wbio->bi_size >> 9); 1387 md_sync_acct(conf->mirrors[d].rdev->bdev, wbio->bi_size >> 9);
1384 if (test_bit(R10BIO_Uptodate, &r10_bio->state)) 1388 if (test_bit(R10BIO_Uptodate, &r10_bio->state))
1385 generic_make_request(wbio); 1389 generic_make_request(wbio);
1386 else 1390 else {
1387 bio_endio(wbio, -EIO); 1391 printk(KERN_NOTICE
1392 "md/raid10:%s: recovery aborted due to read error\n",
1393 mdname(mddev));
1394 conf->mirrors[d].recovery_disabled = mddev->recovery_disabled;
1395 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
1396 bio_endio(wbio, 0);
1397 }
1388} 1398}
1389 1399
1390 1400