diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/linear.c | 9 | ||||
-rw-r--r-- | drivers/md/raid0.c | 27 | ||||
-rw-r--r-- | drivers/md/raid1.c | 13 | ||||
-rw-r--r-- | drivers/md/raid10.c | 2 | ||||
-rw-r--r-- | drivers/md/raid5.c | 59 |
5 files changed, 75 insertions, 35 deletions
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index b0fcc7d02adb..fa211d80fc0a 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -198,6 +198,7 @@ out: | |||
198 | static int linear_run (struct mddev *mddev) | 198 | static int linear_run (struct mddev *mddev) |
199 | { | 199 | { |
200 | struct linear_conf *conf; | 200 | struct linear_conf *conf; |
201 | int ret; | ||
201 | 202 | ||
202 | if (md_check_no_bitmap(mddev)) | 203 | if (md_check_no_bitmap(mddev)) |
203 | return -EINVAL; | 204 | return -EINVAL; |
@@ -211,7 +212,13 @@ static int linear_run (struct mddev *mddev) | |||
211 | blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); | 212 | blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); |
212 | mddev->queue->backing_dev_info.congested_fn = linear_congested; | 213 | mddev->queue->backing_dev_info.congested_fn = linear_congested; |
213 | mddev->queue->backing_dev_info.congested_data = mddev; | 214 | mddev->queue->backing_dev_info.congested_data = mddev; |
214 | return md_integrity_register(mddev); | 215 | |
216 | ret = md_integrity_register(mddev); | ||
217 | if (ret) { | ||
218 | kfree(conf); | ||
219 | mddev->private = NULL; | ||
220 | } | ||
221 | return ret; | ||
215 | } | 222 | } |
216 | 223 | ||
217 | static int linear_add(struct mddev *mddev, struct md_rdev *rdev) | 224 | static int linear_add(struct mddev *mddev, struct md_rdev *rdev) |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 6f31f5596e01..de63a1fc3737 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -407,6 +407,8 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks | |||
407 | return array_sectors; | 407 | return array_sectors; |
408 | } | 408 | } |
409 | 409 | ||
410 | static int raid0_stop(struct mddev *mddev); | ||
411 | |||
410 | static int raid0_run(struct mddev *mddev) | 412 | static int raid0_run(struct mddev *mddev) |
411 | { | 413 | { |
412 | struct r0conf *conf; | 414 | struct r0conf *conf; |
@@ -454,7 +456,12 @@ static int raid0_run(struct mddev *mddev) | |||
454 | 456 | ||
455 | blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec); | 457 | blk_queue_merge_bvec(mddev->queue, raid0_mergeable_bvec); |
456 | dump_zones(mddev); | 458 | dump_zones(mddev); |
457 | return md_integrity_register(mddev); | 459 | |
460 | ret = md_integrity_register(mddev); | ||
461 | if (ret) | ||
462 | raid0_stop(mddev); | ||
463 | |||
464 | return ret; | ||
458 | } | 465 | } |
459 | 466 | ||
460 | static int raid0_stop(struct mddev *mddev) | 467 | static int raid0_stop(struct mddev *mddev) |
@@ -625,6 +632,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev) | |||
625 | static void *raid0_takeover_raid1(struct mddev *mddev) | 632 | static void *raid0_takeover_raid1(struct mddev *mddev) |
626 | { | 633 | { |
627 | struct r0conf *priv_conf; | 634 | struct r0conf *priv_conf; |
635 | int chunksect; | ||
628 | 636 | ||
629 | /* Check layout: | 637 | /* Check layout: |
630 | * - (N - 1) mirror drives must be already faulty | 638 | * - (N - 1) mirror drives must be already faulty |
@@ -635,10 +643,25 @@ static void *raid0_takeover_raid1(struct mddev *mddev) | |||
635 | return ERR_PTR(-EINVAL); | 643 | return ERR_PTR(-EINVAL); |
636 | } | 644 | } |
637 | 645 | ||
646 | /* | ||
647 | * a raid1 doesn't have the notion of chunk size, so | ||
648 | * figure out the largest suitable size we can use. | ||
649 | */ | ||
650 | chunksect = 64 * 2; /* 64K by default */ | ||
651 | |||
652 | /* The array must be an exact multiple of chunksize */ | ||
653 | while (chunksect && (mddev->array_sectors & (chunksect - 1))) | ||
654 | chunksect >>= 1; | ||
655 | |||
656 | if ((chunksect << 9) < PAGE_SIZE) | ||
657 | /* array size does not allow a suitable chunk size */ | ||
658 | return ERR_PTR(-EINVAL); | ||
659 | |||
638 | /* Set new parameters */ | 660 | /* Set new parameters */ |
639 | mddev->new_level = 0; | 661 | mddev->new_level = 0; |
640 | mddev->new_layout = 0; | 662 | mddev->new_layout = 0; |
641 | mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */ | 663 | mddev->new_chunk_sectors = chunksect; |
664 | mddev->chunk_sectors = chunksect; | ||
642 | mddev->delta_disks = 1 - mddev->raid_disks; | 665 | mddev->delta_disks = 1 - mddev->raid_disks; |
643 | mddev->raid_disks = 1; | 666 | mddev->raid_disks = 1; |
644 | /* make sure it will be not marked as dirty */ | 667 | /* make sure it will be not marked as dirty */ |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 4a40a200d769..d35e4c991e38 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1738,7 +1738,7 @@ static int process_checks(struct r1bio *r1_bio) | |||
1738 | s = sbio->bi_io_vec[j].bv_page; | 1738 | s = sbio->bi_io_vec[j].bv_page; |
1739 | if (memcmp(page_address(p), | 1739 | if (memcmp(page_address(p), |
1740 | page_address(s), | 1740 | page_address(s), |
1741 | PAGE_SIZE)) | 1741 | sbio->bi_io_vec[j].bv_len)) |
1742 | break; | 1742 | break; |
1743 | } | 1743 | } |
1744 | } else | 1744 | } else |
@@ -2386,8 +2386,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp | |||
2386 | int ok = 1; | 2386 | int ok = 1; |
2387 | for (i = 0 ; i < conf->raid_disks * 2 ; i++) | 2387 | for (i = 0 ; i < conf->raid_disks * 2 ; i++) |
2388 | if (r1_bio->bios[i]->bi_end_io == end_sync_write) { | 2388 | if (r1_bio->bios[i]->bi_end_io == end_sync_write) { |
2389 | struct md_rdev *rdev = | 2389 | struct md_rdev *rdev = conf->mirrors[i].rdev; |
2390 | rcu_dereference(conf->mirrors[i].rdev); | ||
2391 | ok = rdev_set_badblocks(rdev, sector_nr, | 2390 | ok = rdev_set_badblocks(rdev, sector_nr, |
2392 | min_bad, 0 | 2391 | min_bad, 0 |
2393 | ) && ok; | 2392 | ) && ok; |
@@ -2636,11 +2635,13 @@ static struct r1conf *setup_conf(struct mddev *mddev) | |||
2636 | return ERR_PTR(err); | 2635 | return ERR_PTR(err); |
2637 | } | 2636 | } |
2638 | 2637 | ||
2638 | static int stop(struct mddev *mddev); | ||
2639 | static int run(struct mddev *mddev) | 2639 | static int run(struct mddev *mddev) |
2640 | { | 2640 | { |
2641 | struct r1conf *conf; | 2641 | struct r1conf *conf; |
2642 | int i; | 2642 | int i; |
2643 | struct md_rdev *rdev; | 2643 | struct md_rdev *rdev; |
2644 | int ret; | ||
2644 | 2645 | ||
2645 | if (mddev->level != 1) { | 2646 | if (mddev->level != 1) { |
2646 | printk(KERN_ERR "md/raid1:%s: raid level not set to mirroring (%d)\n", | 2647 | printk(KERN_ERR "md/raid1:%s: raid level not set to mirroring (%d)\n", |
@@ -2705,7 +2706,11 @@ static int run(struct mddev *mddev) | |||
2705 | mddev->queue->backing_dev_info.congested_data = mddev; | 2706 | mddev->queue->backing_dev_info.congested_data = mddev; |
2706 | blk_queue_merge_bvec(mddev->queue, raid1_mergeable_bvec); | 2707 | blk_queue_merge_bvec(mddev->queue, raid1_mergeable_bvec); |
2707 | } | 2708 | } |
2708 | return md_integrity_register(mddev); | 2709 | |
2710 | ret = md_integrity_register(mddev); | ||
2711 | if (ret) | ||
2712 | stop(mddev); | ||
2713 | return ret; | ||
2709 | } | 2714 | } |
2710 | 2715 | ||
2711 | static int stop(struct mddev *mddev) | 2716 | static int stop(struct mddev *mddev) |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 3540316886f2..fff782189e48 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1821,7 +1821,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) | |||
1821 | for (j = 0; j < vcnt; j++) | 1821 | for (j = 0; j < vcnt; j++) |
1822 | if (memcmp(page_address(fbio->bi_io_vec[j].bv_page), | 1822 | if (memcmp(page_address(fbio->bi_io_vec[j].bv_page), |
1823 | page_address(tbio->bi_io_vec[j].bv_page), | 1823 | page_address(tbio->bi_io_vec[j].bv_page), |
1824 | PAGE_SIZE)) | 1824 | fbio->bi_io_vec[j].bv_len)) |
1825 | break; | 1825 | break; |
1826 | if (j == vcnt) | 1826 | if (j == vcnt) |
1827 | continue; | 1827 | continue; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 23ac880bba9a..f351422938e0 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -2471,39 +2471,41 @@ handle_failed_sync(struct r5conf *conf, struct stripe_head *sh, | |||
2471 | int abort = 0; | 2471 | int abort = 0; |
2472 | int i; | 2472 | int i; |
2473 | 2473 | ||
2474 | md_done_sync(conf->mddev, STRIPE_SECTORS, 0); | ||
2475 | clear_bit(STRIPE_SYNCING, &sh->state); | 2474 | clear_bit(STRIPE_SYNCING, &sh->state); |
2476 | s->syncing = 0; | 2475 | s->syncing = 0; |
2477 | s->replacing = 0; | 2476 | s->replacing = 0; |
2478 | /* There is nothing more to do for sync/check/repair. | 2477 | /* There is nothing more to do for sync/check/repair. |
2478 | * Don't even need to abort as that is handled elsewhere | ||
2479 | * if needed, and not always wanted e.g. if there is a known | ||
2480 | * bad block here. | ||
2479 | * For recover/replace we need to record a bad block on all | 2481 | * For recover/replace we need to record a bad block on all |
2480 | * non-sync devices, or abort the recovery | 2482 | * non-sync devices, or abort the recovery |
2481 | */ | 2483 | */ |
2482 | if (!test_bit(MD_RECOVERY_RECOVER, &conf->mddev->recovery)) | 2484 | if (test_bit(MD_RECOVERY_RECOVER, &conf->mddev->recovery)) { |
2483 | return; | 2485 | /* During recovery devices cannot be removed, so |
2484 | /* During recovery devices cannot be removed, so locking and | 2486 | * locking and refcounting of rdevs is not needed |
2485 | * refcounting of rdevs is not needed | 2487 | */ |
2486 | */ | 2488 | for (i = 0; i < conf->raid_disks; i++) { |
2487 | for (i = 0; i < conf->raid_disks; i++) { | 2489 | struct md_rdev *rdev = conf->disks[i].rdev; |
2488 | struct md_rdev *rdev = conf->disks[i].rdev; | 2490 | if (rdev |
2489 | if (rdev | 2491 | && !test_bit(Faulty, &rdev->flags) |
2490 | && !test_bit(Faulty, &rdev->flags) | 2492 | && !test_bit(In_sync, &rdev->flags) |
2491 | && !test_bit(In_sync, &rdev->flags) | 2493 | && !rdev_set_badblocks(rdev, sh->sector, |
2492 | && !rdev_set_badblocks(rdev, sh->sector, | 2494 | STRIPE_SECTORS, 0)) |
2493 | STRIPE_SECTORS, 0)) | 2495 | abort = 1; |
2494 | abort = 1; | 2496 | rdev = conf->disks[i].replacement; |
2495 | rdev = conf->disks[i].replacement; | 2497 | if (rdev |
2496 | if (rdev | 2498 | && !test_bit(Faulty, &rdev->flags) |
2497 | && !test_bit(Faulty, &rdev->flags) | 2499 | && !test_bit(In_sync, &rdev->flags) |
2498 | && !test_bit(In_sync, &rdev->flags) | 2500 | && !rdev_set_badblocks(rdev, sh->sector, |
2499 | && !rdev_set_badblocks(rdev, sh->sector, | 2501 | STRIPE_SECTORS, 0)) |
2500 | STRIPE_SECTORS, 0)) | 2502 | abort = 1; |
2501 | abort = 1; | 2503 | } |
2502 | } | 2504 | if (abort) |
2503 | if (abort) { | 2505 | conf->recovery_disabled = |
2504 | conf->recovery_disabled = conf->mddev->recovery_disabled; | 2506 | conf->mddev->recovery_disabled; |
2505 | set_bit(MD_RECOVERY_INTR, &conf->mddev->recovery); | ||
2506 | } | 2507 | } |
2508 | md_done_sync(conf->mddev, STRIPE_SECTORS, !abort); | ||
2507 | } | 2509 | } |
2508 | 2510 | ||
2509 | static int want_replace(struct stripe_head *sh, int disk_idx) | 2511 | static int want_replace(struct stripe_head *sh, int disk_idx) |
@@ -3203,7 +3205,8 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
3203 | /* Not in-sync */; | 3205 | /* Not in-sync */; |
3204 | else if (is_bad) { | 3206 | else if (is_bad) { |
3205 | /* also not in-sync */ | 3207 | /* also not in-sync */ |
3206 | if (!test_bit(WriteErrorSeen, &rdev->flags)) { | 3208 | if (!test_bit(WriteErrorSeen, &rdev->flags) && |
3209 | test_bit(R5_UPTODATE, &dev->flags)) { | ||
3207 | /* treat as in-sync, but with a read error | 3210 | /* treat as in-sync, but with a read error |
3208 | * which we can now try to correct | 3211 | * which we can now try to correct |
3209 | */ | 3212 | */ |
@@ -3276,12 +3279,14 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
3276 | /* If there is a failed device being replaced, | 3279 | /* If there is a failed device being replaced, |
3277 | * we must be recovering. | 3280 | * we must be recovering. |
3278 | * else if we are after recovery_cp, we must be syncing | 3281 | * else if we are after recovery_cp, we must be syncing |
3282 | * else if MD_RECOVERY_REQUESTED is set, we also are syncing. | ||
3279 | * else we can only be replacing | 3283 | * else we can only be replacing |
3280 | * sync and recovery both need to read all devices, and so | 3284 | * sync and recovery both need to read all devices, and so |
3281 | * use the same flag. | 3285 | * use the same flag. |
3282 | */ | 3286 | */ |
3283 | if (do_recovery || | 3287 | if (do_recovery || |
3284 | sh->sector >= conf->mddev->recovery_cp) | 3288 | sh->sector >= conf->mddev->recovery_cp || |
3289 | test_bit(MD_RECOVERY_REQUESTED, &(conf->mddev->recovery))) | ||
3285 | s->syncing = 1; | 3290 | s->syncing = 1; |
3286 | else | 3291 | else |
3287 | s->replacing = 1; | 3292 | s->replacing = 1; |