diff options
author | NeilBrown <neilb@suse.de> | 2006-03-27 01:18:13 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-27 08:45:02 -0800 |
commit | 63c70c4f3a30e77e6f445bd16eff7934a031ebd3 (patch) | |
tree | 12d2cd6cec5cd304bdf514ec8999a44c26f058ae /drivers/md/raid5.c | |
parent | b578d55fdd80140f657130abd85aebeb345755fb (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>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 60 |
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) } #ifdef CONFIG_MD_RAID5_RESHAPE -static int raid5_reshape(mddev_t *mddev, int raid_disks) +static int raid5_check_reshape(mddev_t *mddev) { raid5_conf_t *conf = mddev_to_conf(mddev); int err; - mdk_rdev_t *rdev; - struct list_head *rtmp; - int spares = 0; - int added_devices = 0; - if (mddev->degraded || - test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) - return -EBUSY; - if (conf->raid_disks > raid_disks) - return -EINVAL; /* Cannot shrink array yet */ - if (conf->raid_disks == raid_disks) + if (mddev->delta_disks < 0 || + mddev->new_level != mddev->level) + return -EINVAL; /* Cannot shrink array or change level yet */ + if (mddev->delta_disks == 0) return 0; /* nothing to do */ /* Can only proceed if there are plenty of stripe_heads. @@ -2615,30 +2609,48 @@ static int raid5_reshape(mddev_t *mddev, int raid_disks) * If the chunk size is greater, user-space should request more * stripe_heads first. */ - if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes) { + if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes || + (mddev->new_chunk / STRIPE_SIZE) * 4 > conf->max_nr_stripes) { printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n", (mddev->chunk_size / STRIPE_SIZE)*4); return -ENOSPC; } + err = resize_stripes(conf, conf->raid_disks + mddev->delta_disks); + if (err) + return err; + + /* looks like we might be able to manage this */ + return 0; +} + +static int raid5_start_reshape(mddev_t *mddev) +{ + raid5_conf_t *conf = mddev_to_conf(mddev); + mdk_rdev_t *rdev; + struct list_head *rtmp; + int spares = 0; + int added_devices = 0; + + if (mddev->degraded || + test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) + return -EBUSY; + ITERATE_RDEV(mddev, rdev, rtmp) if (rdev->raid_disk < 0 && !test_bit(Faulty, &rdev->flags)) spares++; - if (conf->raid_disks + spares < raid_disks-1) + + if (spares < mddev->delta_disks-1) /* Not enough devices even to make a degraded array * of that size */ return -EINVAL; - err = resize_stripes(conf, raid_disks); - if (err) - return err; - atomic_set(&conf->reshape_stripes, 0); spin_lock_irq(&conf->device_lock); conf->previous_raid_disks = conf->raid_disks; - conf->raid_disks = raid_disks; + conf->raid_disks += mddev->delta_disks; conf->expand_progress = 0; conf->expand_lo = 0; spin_unlock_irq(&conf->device_lock); @@ -2660,12 +2672,8 @@ static int raid5_reshape(mddev_t *mddev, int raid_disks) break; } - mddev->degraded = (raid_disks - conf->previous_raid_disks) - added_devices; - mddev->new_chunk = mddev->chunk_size; - mddev->new_layout = mddev->layout; - mddev->new_level = mddev->level; - mddev->raid_disks = raid_disks; - mddev->delta_disks = raid_disks - conf->previous_raid_disks; + mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices; + mddev->raid_disks = conf->raid_disks; mddev->reshape_position = 0; mddev->sb_dirty = 1; @@ -2679,7 +2687,6 @@ static int raid5_reshape(mddev_t *mddev, int raid_disks) mddev->recovery = 0; spin_lock_irq(&conf->device_lock); mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks; - mddev->delta_disks = 0; conf->expand_progress = MaxSector; spin_unlock_irq(&conf->device_lock); return -EAGAIN; @@ -2752,7 +2759,8 @@ static struct mdk_personality raid5_personality = .sync_request = sync_request, .resize = raid5_resize, #ifdef CONFIG_MD_RAID5_RESHAPE - .reshape = raid5_reshape, + .check_reshape = raid5_check_reshape, + .start_reshape = raid5_start_reshape, #endif .quiesce = raid5_quiesce, }; |