aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-03-27 04:18:13 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 11:45:02 -0500
commit63c70c4f3a30e77e6f445bd16eff7934a031ebd3 (patch)
tree12d2cd6cec5cd304bdf514ec8999a44c26f058ae
parentb578d55fdd80140f657130abd85aebeb345755fb (diff)
[PATCH] md: Split reshape handler in check_reshape and start_reshape
check_reshape checks validity and does things that can be done instantly - like adding devices to raid1. start_reshape initiates a restriping process to convert the whole array. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/md/md.c10
-rw-r--r--drivers/md/raid1.c19
-rw-r--r--drivers/md/raid5.c60
-rw-r--r--include/linux/raid/md_k.h3
4 files changed, 58 insertions, 34 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index b9dfdfccdb78..1a637676a930 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -2594,7 +2594,7 @@ static int do_md_run(mddev_t * mddev)
2594 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); 2594 strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
2595 2595
2596 if (mddev->reshape_position != MaxSector && 2596 if (mddev->reshape_position != MaxSector &&
2597 pers->reshape == NULL) { 2597 pers->start_reshape == NULL) {
2598 /* This personality cannot handle reshaping... */ 2598 /* This personality cannot handle reshaping... */
2599 mddev->pers = NULL; 2599 mddev->pers = NULL;
2600 module_put(pers->owner); 2600 module_put(pers->owner);
@@ -3556,14 +3556,16 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks)
3556{ 3556{
3557 int rv; 3557 int rv;
3558 /* change the number of raid disks */ 3558 /* change the number of raid disks */
3559 if (mddev->pers->reshape == NULL) 3559 if (mddev->pers->check_reshape == NULL)
3560 return -EINVAL; 3560 return -EINVAL;
3561 if (raid_disks <= 0 || 3561 if (raid_disks <= 0 ||
3562 raid_disks >= mddev->max_disks) 3562 raid_disks >= mddev->max_disks)
3563 return -EINVAL; 3563 return -EINVAL;
3564 if (mddev->sync_thread) 3564 if (mddev->sync_thread || mddev->reshape_position != MaxSector)
3565 return -EBUSY; 3565 return -EBUSY;
3566 rv = mddev->pers->reshape(mddev, raid_disks); 3566 mddev->delta_disks = raid_disks - mddev->raid_disks;
3567
3568 rv = mddev->pers->check_reshape(mddev);
3567 return rv; 3569 return rv;
3568} 3570}
3569 3571
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index b65b8cfbdf30..04418e10d1dc 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1976,7 +1976,7 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors)
1976 return 0; 1976 return 0;
1977} 1977}
1978 1978
1979static int raid1_reshape(mddev_t *mddev, int raid_disks) 1979static int raid1_reshape(mddev_t *mddev)
1980{ 1980{
1981 /* We need to: 1981 /* We need to:
1982 * 1/ resize the r1bio_pool 1982 * 1/ resize the r1bio_pool
@@ -1993,10 +1993,22 @@ static int raid1_reshape(mddev_t *mddev, int raid_disks)
1993 struct pool_info *newpoolinfo; 1993 struct pool_info *newpoolinfo;
1994 mirror_info_t *newmirrors; 1994 mirror_info_t *newmirrors;
1995 conf_t *conf = mddev_to_conf(mddev); 1995 conf_t *conf = mddev_to_conf(mddev);
1996 int cnt; 1996 int cnt, raid_disks;
1997 1997
1998 int d, d2; 1998 int d, d2;
1999 1999
2000 /* Cannot change chunk_size, layout, or level */
2001 if (mddev->chunk_size != mddev->new_chunk ||
2002 mddev->layout != mddev->new_layout ||
2003 mddev->level != mddev->new_level) {
2004 mddev->new_chunk = mddev->chunk_size;
2005 mddev->new_layout = mddev->layout;
2006 mddev->new_level = mddev->level;
2007 return -EINVAL;
2008 }
2009
2010 raid_disks = mddev->raid_disks + mddev->delta_disks;
2011
2000 if (raid_disks < conf->raid_disks) { 2012 if (raid_disks < conf->raid_disks) {
2001 cnt=0; 2013 cnt=0;
2002 for (d= 0; d < conf->raid_disks; d++) 2014 for (d= 0; d < conf->raid_disks; d++)
@@ -2043,6 +2055,7 @@ static int raid1_reshape(mddev_t *mddev, int raid_disks)
2043 2055
2044 mddev->degraded += (raid_disks - conf->raid_disks); 2056 mddev->degraded += (raid_disks - conf->raid_disks);
2045 conf->raid_disks = mddev->raid_disks = raid_disks; 2057 conf->raid_disks = mddev->raid_disks = raid_disks;
2058 mddev->delta_disks = 0;
2046 2059
2047 conf->last_used = 0; /* just make sure it is in-range */ 2060 conf->last_used = 0; /* just make sure it is in-range */
2048 lower_barrier(conf); 2061 lower_barrier(conf);
@@ -2084,7 +2097,7 @@ static struct mdk_personality raid1_personality =
2084 .spare_active = raid1_spare_active, 2097 .spare_active = raid1_spare_active,
2085 .sync_request = sync_request, 2098 .sync_request = sync_request,
2086 .resize = raid1_resize, 2099 .resize = raid1_resize,
2087 .reshape = raid1_reshape, 2100 .check_reshape = raid1_reshape,
2088 .quiesce = raid1_quiesce, 2101 .quiesce = raid1_quiesce,
2089}; 2102};
2090 2103
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};
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index 1a6f9f2f6282..002ee631fabb 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -261,7 +261,8 @@ struct mdk_personality
261 int (*spare_active) (mddev_t *mddev); 261 int (*spare_active) (mddev_t *mddev);
262 sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster); 262 sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
263 int (*resize) (mddev_t *mddev, sector_t sectors); 263 int (*resize) (mddev_t *mddev, sector_t sectors);
264 int (*reshape) (mddev_t *mddev, int raid_disks); 264 int (*check_reshape) (mddev_t *mddev);
265 int (*start_reshape) (mddev_t *mddev);
265 int (*reconfig) (mddev_t *mddev, int layout, int chunk_size); 266 int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
266 /* quiesce moves between quiescence states 267 /* quiesce moves between quiescence states
267 * 0 - fully active 268 * 0 - fully active