aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c60
1 files changed, 34 insertions, 26 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 089a32604305..355dafb98aac 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -2590,21 +2590,15 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
2590} 2590}
2591 2591
2592#ifdef CONFIG_MD_RAID5_RESHAPE 2592#ifdef CONFIG_MD_RAID5_RESHAPE
2593static int raid5_reshape(mddev_t *mddev, int raid_disks) 2593static int raid5_check_reshape(mddev_t *mddev)
2594{ 2594{
2595 raid5_conf_t *conf = mddev_to_conf(mddev); 2595 raid5_conf_t *conf = mddev_to_conf(mddev);
2596 int err; 2596 int err;
2597 mdk_rdev_t *rdev;
2598 struct list_head *rtmp;
2599 int spares = 0;
2600 int added_devices = 0;
2601 2597
2602 if (mddev->degraded || 2598 if (mddev->delta_disks < 0 ||
2603 test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) 2599 mddev->new_level != mddev->level)
2604 return -EBUSY; 2600 return -EINVAL; /* Cannot shrink array or change level yet */
2605 if (conf->raid_disks > raid_disks) 2601 if (mddev->delta_disks == 0)
2606 return -EINVAL; /* Cannot shrink array yet */
2607 if (conf->raid_disks == raid_disks)
2608 return 0; /* nothing to do */ 2602 return 0; /* nothing to do */
2609 2603
2610 /* Can only proceed if there are plenty of stripe_heads. 2604 /* Can only proceed if there are plenty of stripe_heads.
@@ -2615,30 +2609,48 @@ static int raid5_reshape(mddev_t *mddev, int raid_disks)
2615 * If the chunk size is greater, user-space should request more 2609 * If the chunk size is greater, user-space should request more
2616 * stripe_heads first. 2610 * stripe_heads first.
2617 */ 2611 */
2618 if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes) { 2612 if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes ||
2613 (mddev->new_chunk / STRIPE_SIZE) * 4 > conf->max_nr_stripes) {
2619 printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n", 2614 printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n",
2620 (mddev->chunk_size / STRIPE_SIZE)*4); 2615 (mddev->chunk_size / STRIPE_SIZE)*4);
2621 return -ENOSPC; 2616 return -ENOSPC;
2622 } 2617 }
2623 2618
2619 err = resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
2620 if (err)
2621 return err;
2622
2623 /* looks like we might be able to manage this */
2624 return 0;
2625}
2626
2627static int raid5_start_reshape(mddev_t *mddev)
2628{
2629 raid5_conf_t *conf = mddev_to_conf(mddev);
2630 mdk_rdev_t *rdev;
2631 struct list_head *rtmp;
2632 int spares = 0;
2633 int added_devices = 0;
2634
2635 if (mddev->degraded ||
2636 test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
2637 return -EBUSY;
2638
2624 ITERATE_RDEV(mddev, rdev, rtmp) 2639 ITERATE_RDEV(mddev, rdev, rtmp)
2625 if (rdev->raid_disk < 0 && 2640 if (rdev->raid_disk < 0 &&
2626 !test_bit(Faulty, &rdev->flags)) 2641 !test_bit(Faulty, &rdev->flags))
2627 spares++; 2642 spares++;
2628 if (conf->raid_disks + spares < raid_disks-1) 2643
2644 if (spares < mddev->delta_disks-1)
2629 /* Not enough devices even to make a degraded array 2645 /* Not enough devices even to make a degraded array
2630 * of that size 2646 * of that size
2631 */ 2647 */
2632 return -EINVAL; 2648 return -EINVAL;
2633 2649
2634 err = resize_stripes(conf, raid_disks);
2635 if (err)
2636 return err;
2637
2638 atomic_set(&conf->reshape_stripes, 0); 2650 atomic_set(&conf->reshape_stripes, 0);
2639 spin_lock_irq(&conf->device_lock); 2651 spin_lock_irq(&conf->device_lock);
2640 conf->previous_raid_disks = conf->raid_disks; 2652 conf->previous_raid_disks = conf->raid_disks;
2641 conf->raid_disks = raid_disks; 2653 conf->raid_disks += mddev->delta_disks;
2642 conf->expand_progress = 0; 2654 conf->expand_progress = 0;
2643 conf->expand_lo = 0; 2655 conf->expand_lo = 0;
2644 spin_unlock_irq(&conf->device_lock); 2656 spin_unlock_irq(&conf->device_lock);
@@ -2660,12 +2672,8 @@ static int raid5_reshape(mddev_t *mddev, int raid_disks)
2660 break; 2672 break;
2661 } 2673 }
2662 2674
2663 mddev->degraded = (raid_disks - conf->previous_raid_disks) - added_devices; 2675 mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
2664 mddev->new_chunk = mddev->chunk_size; 2676 mddev->raid_disks = conf->raid_disks;
2665 mddev->new_layout = mddev->layout;
2666 mddev->new_level = mddev->level;
2667 mddev->raid_disks = raid_disks;
2668 mddev->delta_disks = raid_disks - conf->previous_raid_disks;
2669 mddev->reshape_position = 0; 2677 mddev->reshape_position = 0;
2670 mddev->sb_dirty = 1; 2678 mddev->sb_dirty = 1;
2671 2679
@@ -2679,7 +2687,6 @@ static int raid5_reshape(mddev_t *mddev, int raid_disks)
2679 mddev->recovery = 0; 2687 mddev->recovery = 0;
2680 spin_lock_irq(&conf->device_lock); 2688 spin_lock_irq(&conf->device_lock);
2681 mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks; 2689 mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks;
2682 mddev->delta_disks = 0;
2683 conf->expand_progress = MaxSector; 2690 conf->expand_progress = MaxSector;
2684 spin_unlock_irq(&conf->device_lock); 2691 spin_unlock_irq(&conf->device_lock);
2685 return -EAGAIN; 2692 return -EAGAIN;
@@ -2752,7 +2759,8 @@ static struct mdk_personality raid5_personality =
2752 .sync_request = sync_request, 2759 .sync_request = sync_request,
2753 .resize = raid5_resize, 2760 .resize = raid5_resize,
2754#ifdef CONFIG_MD_RAID5_RESHAPE 2761#ifdef CONFIG_MD_RAID5_RESHAPE
2755 .reshape = raid5_reshape, 2762 .check_reshape = raid5_check_reshape,
2763 .start_reshape = raid5_start_reshape,
2756#endif 2764#endif
2757 .quiesce = raid5_quiesce, 2765 .quiesce = raid5_quiesce,
2758}; 2766};