aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/md.c47
-rw-r--r--drivers/md/md.h2
-rw-r--r--drivers/md/raid0.c40
-rw-r--r--drivers/md/raid10.c6
-rw-r--r--drivers/md/raid5.c60
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
655static 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
647static void *raid0_takeover(mddev_t *mddev) 680static 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;