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.c51
1 files changed, 25 insertions, 26 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 37835538b58e..2b521ee67dfa 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3999,6 +3999,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
3999 return 0; 3999 return 0;
4000 } 4000 }
4001 4001
4002 /* Allow raid5_quiesce to complete */
4003 wait_event(conf->wait_for_overlap, conf->quiesce != 2);
4004
4002 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) 4005 if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
4003 return reshape_request(mddev, sector_nr, skipped); 4006 return reshape_request(mddev, sector_nr, skipped);
4004 4007
@@ -4316,6 +4319,15 @@ raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks)
4316 return sectors * (raid_disks - conf->max_degraded); 4319 return sectors * (raid_disks - conf->max_degraded);
4317} 4320}
4318 4321
4322static void free_conf(raid5_conf_t *conf)
4323{
4324 shrink_stripes(conf);
4325 safe_put_page(conf->spare_page);
4326 kfree(conf->disks);
4327 kfree(conf->stripe_hashtbl);
4328 kfree(conf);
4329}
4330
4319static raid5_conf_t *setup_conf(mddev_t *mddev) 4331static raid5_conf_t *setup_conf(mddev_t *mddev)
4320{ 4332{
4321 raid5_conf_t *conf; 4333 raid5_conf_t *conf;
@@ -4447,11 +4459,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev)
4447 4459
4448 abort: 4460 abort:
4449 if (conf) { 4461 if (conf) {
4450 shrink_stripes(conf); 4462 free_conf(conf);
4451 safe_put_page(conf->spare_page);
4452 kfree(conf->disks);
4453 kfree(conf->stripe_hashtbl);
4454 kfree(conf);
4455 return ERR_PTR(-EIO); 4463 return ERR_PTR(-EIO);
4456 } else 4464 } else
4457 return ERR_PTR(-ENOMEM); 4465 return ERR_PTR(-ENOMEM);
@@ -4629,12 +4637,8 @@ abort:
4629 md_unregister_thread(mddev->thread); 4637 md_unregister_thread(mddev->thread);
4630 mddev->thread = NULL; 4638 mddev->thread = NULL;
4631 if (conf) { 4639 if (conf) {
4632 shrink_stripes(conf);
4633 print_raid5_conf(conf); 4640 print_raid5_conf(conf);
4634 safe_put_page(conf->spare_page); 4641 free_conf(conf);
4635 kfree(conf->disks);
4636 kfree(conf->stripe_hashtbl);
4637 kfree(conf);
4638 } 4642 }
4639 mddev->private = NULL; 4643 mddev->private = NULL;
4640 printk(KERN_ALERT "raid5: failed to run raid set %s\n", mdname(mddev)); 4644 printk(KERN_ALERT "raid5: failed to run raid set %s\n", mdname(mddev));
@@ -4649,13 +4653,10 @@ static int stop(mddev_t *mddev)
4649 4653
4650 md_unregister_thread(mddev->thread); 4654 md_unregister_thread(mddev->thread);
4651 mddev->thread = NULL; 4655 mddev->thread = NULL;
4652 shrink_stripes(conf);
4653 kfree(conf->stripe_hashtbl);
4654 mddev->queue->backing_dev_info.congested_fn = NULL; 4656 mddev->queue->backing_dev_info.congested_fn = NULL;
4655 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 4657 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
4656 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); 4658 sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
4657 kfree(conf->disks); 4659 free_conf(conf);
4658 kfree(conf);
4659 mddev->private = NULL; 4660 mddev->private = NULL;
4660 return 0; 4661 return 0;
4661} 4662}
@@ -4857,6 +4858,7 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
4857 return -EINVAL; 4858 return -EINVAL;
4858 set_capacity(mddev->gendisk, mddev->array_sectors); 4859 set_capacity(mddev->gendisk, mddev->array_sectors);
4859 mddev->changed = 1; 4860 mddev->changed = 1;
4861 revalidate_disk(mddev->gendisk);
4860 if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) { 4862 if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) {
4861 mddev->recovery_cp = mddev->dev_sectors; 4863 mddev->recovery_cp = mddev->dev_sectors;
4862 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); 4864 set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
@@ -5002,7 +5004,7 @@ static int raid5_start_reshape(mddev_t *mddev)
5002 spin_unlock_irqrestore(&conf->device_lock, flags); 5004 spin_unlock_irqrestore(&conf->device_lock, flags);
5003 } 5005 }
5004 mddev->raid_disks = conf->raid_disks; 5006 mddev->raid_disks = conf->raid_disks;
5005 mddev->reshape_position = 0; 5007 mddev->reshape_position = conf->reshape_progress;
5006 set_bit(MD_CHANGE_DEVS, &mddev->flags); 5008 set_bit(MD_CHANGE_DEVS, &mddev->flags);
5007 5009
5008 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); 5010 clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
@@ -5057,7 +5059,6 @@ static void end_reshape(raid5_conf_t *conf)
5057 */ 5059 */
5058static void raid5_finish_reshape(mddev_t *mddev) 5060static void raid5_finish_reshape(mddev_t *mddev)
5059{ 5061{
5060 struct block_device *bdev;
5061 raid5_conf_t *conf = mddev->private; 5062 raid5_conf_t *conf = mddev->private;
5062 5063
5063 if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { 5064 if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
@@ -5066,15 +5067,7 @@ static void raid5_finish_reshape(mddev_t *mddev)
5066 md_set_array_sectors(mddev, raid5_size(mddev, 0, 0)); 5067 md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
5067 set_capacity(mddev->gendisk, mddev->array_sectors); 5068 set_capacity(mddev->gendisk, mddev->array_sectors);
5068 mddev->changed = 1; 5069 mddev->changed = 1;
5069 5070 revalidate_disk(mddev->gendisk);
5070 bdev = bdget_disk(mddev->gendisk, 0);
5071 if (bdev) {
5072 mutex_lock(&bdev->bd_inode->i_mutex);
5073 i_size_write(bdev->bd_inode,
5074 (loff_t)mddev->array_sectors << 9);
5075 mutex_unlock(&bdev->bd_inode->i_mutex);
5076 bdput(bdev);
5077 }
5078 } else { 5071 } else {
5079 int d; 5072 int d;
5080 mddev->degraded = conf->raid_disks; 5073 mddev->degraded = conf->raid_disks;
@@ -5106,12 +5099,18 @@ static void raid5_quiesce(mddev_t *mddev, int state)
5106 5099
5107 case 1: /* stop all writes */ 5100 case 1: /* stop all writes */
5108 spin_lock_irq(&conf->device_lock); 5101 spin_lock_irq(&conf->device_lock);
5109 conf->quiesce = 1; 5102 /* '2' tells resync/reshape to pause so that all
5103 * active stripes can drain
5104 */
5105 conf->quiesce = 2;
5110 wait_event_lock_irq(conf->wait_for_stripe, 5106 wait_event_lock_irq(conf->wait_for_stripe,
5111 atomic_read(&conf->active_stripes) == 0 && 5107 atomic_read(&conf->active_stripes) == 0 &&
5112 atomic_read(&conf->active_aligned_reads) == 0, 5108 atomic_read(&conf->active_aligned_reads) == 0,
5113 conf->device_lock, /* nothing */); 5109 conf->device_lock, /* nothing */);
5110 conf->quiesce = 1;
5114 spin_unlock_irq(&conf->device_lock); 5111 spin_unlock_irq(&conf->device_lock);
5112 /* allow reshape to continue */
5113 wake_up(&conf->wait_for_overlap);
5115 break; 5114 break;
5116 5115
5117 case 0: /* re-enable writes */ 5116 case 0: /* re-enable writes */