diff options
| -rw-r--r-- | drivers/md/md.c | 47 | ||||
| -rw-r--r-- | drivers/md/md.h | 2 | ||||
| -rw-r--r-- | drivers/md/raid0.c | 40 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 6 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 60 |
5 files changed, 106 insertions, 49 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index b76cfc89e1b5..0cc30ecda4c1 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -287,6 +287,7 @@ static int md_make_request(struct request_queue *q, struct bio *bio) | |||
| 287 | mddev_t *mddev = q->queuedata; | 287 | mddev_t *mddev = q->queuedata; |
| 288 | int rv; | 288 | int rv; |
| 289 | int cpu; | 289 | int cpu; |
| 290 | unsigned int sectors; | ||
| 290 | 291 | ||
| 291 | if (mddev == NULL || mddev->pers == NULL | 292 | if (mddev == NULL || mddev->pers == NULL |
| 292 | || !mddev->ready) { | 293 | || !mddev->ready) { |
| @@ -311,12 +312,16 @@ static int md_make_request(struct request_queue *q, struct bio *bio) | |||
| 311 | atomic_inc(&mddev->active_io); | 312 | atomic_inc(&mddev->active_io); |
| 312 | rcu_read_unlock(); | 313 | rcu_read_unlock(); |
| 313 | 314 | ||
| 315 | /* | ||
| 316 | * save the sectors now since our bio can | ||
| 317 | * go away inside make_request | ||
| 318 | */ | ||
| 319 | sectors = bio_sectors(bio); | ||
| 314 | rv = mddev->pers->make_request(mddev, bio); | 320 | rv = mddev->pers->make_request(mddev, bio); |
| 315 | 321 | ||
| 316 | cpu = part_stat_lock(); | 322 | cpu = part_stat_lock(); |
| 317 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); | 323 | part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); |
| 318 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], | 324 | part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors); |
| 319 | bio_sectors(bio)); | ||
| 320 | part_stat_unlock(); | 325 | part_stat_unlock(); |
| 321 | 326 | ||
| 322 | if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) | 327 | if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) |
| @@ -1947,8 +1952,6 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) | |||
| 1947 | __bdevname(dev, b)); | 1952 | __bdevname(dev, b)); |
| 1948 | return PTR_ERR(bdev); | 1953 | return PTR_ERR(bdev); |
| 1949 | } | 1954 | } |
| 1950 | if (!shared) | ||
| 1951 | set_bit(AllReserved, &rdev->flags); | ||
| 1952 | rdev->bdev = bdev; | 1955 | rdev->bdev = bdev; |
| 1953 | return err; | 1956 | return err; |
| 1954 | } | 1957 | } |
| @@ -2465,6 +2468,9 @@ slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2465 | if (rdev->raid_disk != -1) | 2468 | if (rdev->raid_disk != -1) |
| 2466 | return -EBUSY; | 2469 | return -EBUSY; |
| 2467 | 2470 | ||
| 2471 | if (test_bit(MD_RECOVERY_RUNNING, &rdev->mddev->recovery)) | ||
| 2472 | return -EBUSY; | ||
| 2473 | |||
| 2468 | if (rdev->mddev->pers->hot_add_disk == NULL) | 2474 | if (rdev->mddev->pers->hot_add_disk == NULL) |
| 2469 | return -EINVAL; | 2475 | return -EINVAL; |
| 2470 | 2476 | ||
| @@ -2610,12 +2616,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2610 | 2616 | ||
| 2611 | mddev_lock(mddev); | 2617 | mddev_lock(mddev); |
| 2612 | list_for_each_entry(rdev2, &mddev->disks, same_set) | 2618 | list_for_each_entry(rdev2, &mddev->disks, same_set) |
| 2613 | if (test_bit(AllReserved, &rdev2->flags) || | 2619 | if (rdev->bdev == rdev2->bdev && |
| 2614 | (rdev->bdev == rdev2->bdev && | 2620 | rdev != rdev2 && |
| 2615 | rdev != rdev2 && | 2621 | overlaps(rdev->data_offset, rdev->sectors, |
| 2616 | overlaps(rdev->data_offset, rdev->sectors, | 2622 | rdev2->data_offset, |
| 2617 | rdev2->data_offset, | 2623 | rdev2->sectors)) { |
| 2618 | rdev2->sectors))) { | ||
| 2619 | overlap = 1; | 2624 | overlap = 1; |
| 2620 | break; | 2625 | break; |
| 2621 | } | 2626 | } |
| @@ -5578,6 +5583,8 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks) | |||
| 5578 | mddev->delta_disks = raid_disks - mddev->raid_disks; | 5583 | mddev->delta_disks = raid_disks - mddev->raid_disks; |
| 5579 | 5584 | ||
| 5580 | rv = mddev->pers->check_reshape(mddev); | 5585 | rv = mddev->pers->check_reshape(mddev); |
| 5586 | if (rv < 0) | ||
| 5587 | mddev->delta_disks = 0; | ||
| 5581 | return rv; | 5588 | return rv; |
| 5582 | } | 5589 | } |
| 5583 | 5590 | ||
| @@ -6985,9 +6992,6 @@ void md_do_sync(mddev_t *mddev) | |||
| 6985 | } else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) | 6992 | } else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) |
| 6986 | mddev->resync_min = mddev->curr_resync_completed; | 6993 | mddev->resync_min = mddev->curr_resync_completed; |
| 6987 | mddev->curr_resync = 0; | 6994 | mddev->curr_resync = 0; |
| 6988 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) | ||
| 6989 | mddev->curr_resync_completed = 0; | ||
| 6990 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
| 6991 | wake_up(&resync_wait); | 6995 | wake_up(&resync_wait); |
| 6992 | set_bit(MD_RECOVERY_DONE, &mddev->recovery); | 6996 | set_bit(MD_RECOVERY_DONE, &mddev->recovery); |
| 6993 | md_wakeup_thread(mddev->thread); | 6997 | md_wakeup_thread(mddev->thread); |
| @@ -7028,7 +7032,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
| 7028 | } | 7032 | } |
| 7029 | } | 7033 | } |
| 7030 | 7034 | ||
| 7031 | if (mddev->degraded && ! mddev->ro && !mddev->recovery_disabled) { | 7035 | if (mddev->degraded && !mddev->recovery_disabled) { |
| 7032 | list_for_each_entry(rdev, &mddev->disks, same_set) { | 7036 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
| 7033 | if (rdev->raid_disk >= 0 && | 7037 | if (rdev->raid_disk >= 0 && |
| 7034 | !test_bit(In_sync, &rdev->flags) && | 7038 | !test_bit(In_sync, &rdev->flags) && |
| @@ -7151,7 +7155,20 @@ void md_check_recovery(mddev_t *mddev) | |||
| 7151 | /* Only thing we do on a ro array is remove | 7155 | /* Only thing we do on a ro array is remove |
| 7152 | * failed devices. | 7156 | * failed devices. |
| 7153 | */ | 7157 | */ |
| 7154 | remove_and_add_spares(mddev); | 7158 | mdk_rdev_t *rdev; |
| 7159 | list_for_each_entry(rdev, &mddev->disks, same_set) | ||
| 7160 | if (rdev->raid_disk >= 0 && | ||
| 7161 | !test_bit(Blocked, &rdev->flags) && | ||
| 7162 | test_bit(Faulty, &rdev->flags) && | ||
| 7163 | atomic_read(&rdev->nr_pending)==0) { | ||
| 7164 | if (mddev->pers->hot_remove_disk( | ||
| 7165 | mddev, rdev->raid_disk)==0) { | ||
| 7166 | char nm[20]; | ||
| 7167 | sprintf(nm,"rd%d", rdev->raid_disk); | ||
| 7168 | sysfs_remove_link(&mddev->kobj, nm); | ||
| 7169 | rdev->raid_disk = -1; | ||
| 7170 | } | ||
| 7171 | } | ||
| 7155 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 7172 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 7156 | goto unlock; | 7173 | goto unlock; |
| 7157 | } | 7174 | } |
diff --git a/drivers/md/md.h b/drivers/md/md.h index eec517ced31a..7e90b8593b2a 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
| @@ -93,8 +93,6 @@ struct mdk_rdev_s | |||
| 93 | #define Faulty 1 /* device is known to have a fault */ | 93 | #define Faulty 1 /* device is known to have a fault */ |
| 94 | #define In_sync 2 /* device is in_sync with rest of array */ | 94 | #define In_sync 2 /* device is in_sync with rest of array */ |
| 95 | #define WriteMostly 4 /* Avoid reading if at all possible */ | 95 | #define WriteMostly 4 /* Avoid reading if at all possible */ |
| 96 | #define AllReserved 6 /* If whole device is reserved for | ||
| 97 | * one array */ | ||
| 98 | #define AutoDetected 7 /* added by auto-detect */ | 96 | #define AutoDetected 7 /* added by auto-detect */ |
| 99 | #define Blocked 8 /* An error occured on an externally | 97 | #define Blocked 8 /* An error occured on an externally |
| 100 | * managed array, don't allow writes | 98 | * managed array, don't allow writes |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index a39f4c355e55..637a96855edb 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
| @@ -179,6 +179,14 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) | |||
| 179 | rdev1->new_raid_disk = j; | 179 | rdev1->new_raid_disk = j; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | if (mddev->level == 1) { | ||
| 183 | /* taiking over a raid1 array- | ||
| 184 | * we have only one active disk | ||
| 185 | */ | ||
| 186 | j = 0; | ||
| 187 | rdev1->new_raid_disk = j; | ||
| 188 | } | ||
| 189 | |||
| 182 | if (j < 0 || j >= mddev->raid_disks) { | 190 | if (j < 0 || j >= mddev->raid_disks) { |
| 183 | printk(KERN_ERR "md/raid0:%s: bad disk number %d - " | 191 | printk(KERN_ERR "md/raid0:%s: bad disk number %d - " |
| 184 | "aborting!\n", mdname(mddev), j); | 192 | "aborting!\n", mdname(mddev), j); |
| @@ -644,12 +652,38 @@ static void *raid0_takeover_raid10(mddev_t *mddev) | |||
| 644 | return priv_conf; | 652 | return priv_conf; |
| 645 | } | 653 | } |
| 646 | 654 | ||
| 655 | static void *raid0_takeover_raid1(mddev_t *mddev) | ||
| 656 | { | ||
| 657 | raid0_conf_t *priv_conf; | ||
| 658 | |||
| 659 | /* Check layout: | ||
| 660 | * - (N - 1) mirror drives must be already faulty | ||
| 661 | */ | ||
| 662 | if ((mddev->raid_disks - 1) != mddev->degraded) { | ||
| 663 | printk(KERN_ERR "md/raid0:%s: (N - 1) mirrors drives must be already faulty!\n", | ||
| 664 | mdname(mddev)); | ||
| 665 | return ERR_PTR(-EINVAL); | ||
| 666 | } | ||
| 667 | |||
| 668 | /* Set new parameters */ | ||
| 669 | mddev->new_level = 0; | ||
| 670 | mddev->new_layout = 0; | ||
| 671 | mddev->new_chunk_sectors = 128; /* by default set chunk size to 64k */ | ||
| 672 | mddev->delta_disks = 1 - mddev->raid_disks; | ||
| 673 | /* make sure it will be not marked as dirty */ | ||
| 674 | mddev->recovery_cp = MaxSector; | ||
| 675 | |||
| 676 | create_strip_zones(mddev, &priv_conf); | ||
| 677 | return priv_conf; | ||
| 678 | } | ||
| 679 | |||
| 647 | static void *raid0_takeover(mddev_t *mddev) | 680 | static void *raid0_takeover(mddev_t *mddev) |
| 648 | { | 681 | { |
| 649 | /* raid0 can take over: | 682 | /* raid0 can take over: |
| 650 | * raid4 - if all data disks are active. | 683 | * raid4 - if all data disks are active. |
| 651 | * raid5 - providing it is Raid4 layout and one disk is faulty | 684 | * raid5 - providing it is Raid4 layout and one disk is faulty |
| 652 | * raid10 - assuming we have all necessary active disks | 685 | * raid10 - assuming we have all necessary active disks |
| 686 | * raid1 - with (N -1) mirror drives faulty | ||
| 653 | */ | 687 | */ |
| 654 | if (mddev->level == 4) | 688 | if (mddev->level == 4) |
| 655 | return raid0_takeover_raid45(mddev); | 689 | return raid0_takeover_raid45(mddev); |
| @@ -665,6 +699,12 @@ static void *raid0_takeover(mddev_t *mddev) | |||
| 665 | if (mddev->level == 10) | 699 | if (mddev->level == 10) |
| 666 | return raid0_takeover_raid10(mddev); | 700 | return raid0_takeover_raid10(mddev); |
| 667 | 701 | ||
| 702 | if (mddev->level == 1) | ||
| 703 | return raid0_takeover_raid1(mddev); | ||
| 704 | |||
| 705 | printk(KERN_ERR "Takeover from raid%i to raid0 not supported\n", | ||
| 706 | mddev->level); | ||
| 707 | |||
| 668 | return ERR_PTR(-EINVAL); | 708 | return ERR_PTR(-EINVAL); |
| 669 | } | 709 | } |
| 670 | 710 | ||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 69b659544390..3b607b28741b 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -2463,11 +2463,13 @@ static void *raid10_takeover_raid0(mddev_t *mddev) | |||
| 2463 | mddev->recovery_cp = MaxSector; | 2463 | mddev->recovery_cp = MaxSector; |
| 2464 | 2464 | ||
| 2465 | conf = setup_conf(mddev); | 2465 | conf = setup_conf(mddev); |
| 2466 | if (!IS_ERR(conf)) | 2466 | if (!IS_ERR(conf)) { |
| 2467 | list_for_each_entry(rdev, &mddev->disks, same_set) | 2467 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 2468 | if (rdev->raid_disk >= 0) | 2468 | if (rdev->raid_disk >= 0) |
| 2469 | rdev->new_raid_disk = rdev->raid_disk * 2; | 2469 | rdev->new_raid_disk = rdev->raid_disk * 2; |
| 2470 | 2470 | conf->barrier = 1; | |
| 2471 | } | ||
| 2472 | |||
| 2471 | return conf; | 2473 | return conf; |
| 2472 | } | 2474 | } |
| 2473 | 2475 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 5044babfcda0..702812824195 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -5517,7 +5517,6 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
| 5517 | raid5_conf_t *conf = mddev->private; | 5517 | raid5_conf_t *conf = mddev->private; |
| 5518 | mdk_rdev_t *rdev; | 5518 | mdk_rdev_t *rdev; |
| 5519 | int spares = 0; | 5519 | int spares = 0; |
| 5520 | int added_devices = 0; | ||
| 5521 | unsigned long flags; | 5520 | unsigned long flags; |
| 5522 | 5521 | ||
| 5523 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | 5522 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
| @@ -5527,8 +5526,8 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
| 5527 | return -ENOSPC; | 5526 | return -ENOSPC; |
| 5528 | 5527 | ||
| 5529 | list_for_each_entry(rdev, &mddev->disks, same_set) | 5528 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 5530 | if ((rdev->raid_disk < 0 || rdev->raid_disk >= conf->raid_disks) | 5529 | if (!test_bit(In_sync, &rdev->flags) |
| 5531 | && !test_bit(Faulty, &rdev->flags)) | 5530 | && !test_bit(Faulty, &rdev->flags)) |
| 5532 | spares++; | 5531 | spares++; |
| 5533 | 5532 | ||
| 5534 | if (spares - mddev->degraded < mddev->delta_disks - conf->max_degraded) | 5533 | if (spares - mddev->degraded < mddev->delta_disks - conf->max_degraded) |
| @@ -5571,34 +5570,35 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
| 5571 | * to correctly record the "partially reconstructed" state of | 5570 | * to correctly record the "partially reconstructed" state of |
| 5572 | * such devices during the reshape and confusion could result. | 5571 | * such devices during the reshape and confusion could result. |
| 5573 | */ | 5572 | */ |
| 5574 | if (mddev->delta_disks >= 0) | 5573 | if (mddev->delta_disks >= 0) { |
| 5575 | list_for_each_entry(rdev, &mddev->disks, same_set) | 5574 | int added_devices = 0; |
| 5576 | if (rdev->raid_disk < 0 && | 5575 | list_for_each_entry(rdev, &mddev->disks, same_set) |
| 5577 | !test_bit(Faulty, &rdev->flags)) { | 5576 | if (rdev->raid_disk < 0 && |
| 5578 | if (raid5_add_disk(mddev, rdev) == 0) { | 5577 | !test_bit(Faulty, &rdev->flags)) { |
| 5579 | char nm[20]; | 5578 | if (raid5_add_disk(mddev, rdev) == 0) { |
| 5580 | if (rdev->raid_disk >= conf->previous_raid_disks) { | 5579 | char nm[20]; |
| 5581 | set_bit(In_sync, &rdev->flags); | 5580 | if (rdev->raid_disk |
| 5582 | added_devices++; | 5581 | >= conf->previous_raid_disks) { |
| 5583 | } else | 5582 | set_bit(In_sync, &rdev->flags); |
| 5584 | rdev->recovery_offset = 0; | 5583 | added_devices++; |
| 5585 | sprintf(nm, "rd%d", rdev->raid_disk); | 5584 | } else |
| 5586 | if (sysfs_create_link(&mddev->kobj, | 5585 | rdev->recovery_offset = 0; |
| 5587 | &rdev->kobj, nm)) | 5586 | sprintf(nm, "rd%d", rdev->raid_disk); |
| 5588 | /* Failure here is OK */; | 5587 | if (sysfs_create_link(&mddev->kobj, |
| 5589 | } else | 5588 | &rdev->kobj, nm)) |
| 5590 | break; | 5589 | /* Failure here is OK */; |
| 5591 | } else if (rdev->raid_disk >= conf->previous_raid_disks | 5590 | } |
| 5592 | && !test_bit(Faulty, &rdev->flags)) { | 5591 | } else if (rdev->raid_disk >= conf->previous_raid_disks |
| 5593 | /* This is a spare that was manually added */ | 5592 | && !test_bit(Faulty, &rdev->flags)) { |
| 5594 | set_bit(In_sync, &rdev->flags); | 5593 | /* This is a spare that was manually added */ |
| 5595 | added_devices++; | 5594 | set_bit(In_sync, &rdev->flags); |
| 5596 | } | 5595 | added_devices++; |
| 5596 | } | ||
| 5597 | 5597 | ||
| 5598 | /* When a reshape changes the number of devices, ->degraded | 5598 | /* When a reshape changes the number of devices, |
| 5599 | * is measured against the larger of the pre and post number of | 5599 | * ->degraded is measured against the larger of the |
| 5600 | * devices.*/ | 5600 | * pre and post number of devices. |
| 5601 | if (mddev->delta_disks > 0) { | 5601 | */ |
| 5602 | spin_lock_irqsave(&conf->device_lock, flags); | 5602 | spin_lock_irqsave(&conf->device_lock, flags); |
| 5603 | mddev->degraded += (conf->raid_disks - conf->previous_raid_disks) | 5603 | mddev->degraded += (conf->raid_disks - conf->previous_raid_disks) |
| 5604 | - added_devices; | 5604 | - added_devices; |
