diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 364ea37706fa..0a5cf2171214 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -364,7 +364,7 @@ static void raid5_unplug_device(struct request_queue *q); | |||
364 | 364 | ||
365 | static struct stripe_head * | 365 | static struct stripe_head * |
366 | get_active_stripe(raid5_conf_t *conf, sector_t sector, | 366 | get_active_stripe(raid5_conf_t *conf, sector_t sector, |
367 | int previous, int noblock) | 367 | int previous, int noblock, int noquiesce) |
368 | { | 368 | { |
369 | struct stripe_head *sh; | 369 | struct stripe_head *sh; |
370 | 370 | ||
@@ -374,7 +374,7 @@ get_active_stripe(raid5_conf_t *conf, sector_t sector, | |||
374 | 374 | ||
375 | do { | 375 | do { |
376 | wait_event_lock_irq(conf->wait_for_stripe, | 376 | wait_event_lock_irq(conf->wait_for_stripe, |
377 | conf->quiesce == 0, | 377 | conf->quiesce == 0 || noquiesce, |
378 | conf->device_lock, /* nothing */); | 378 | conf->device_lock, /* nothing */); |
379 | sh = __find_stripe(conf, sector, conf->generation - previous); | 379 | sh = __find_stripe(conf, sector, conf->generation - previous); |
380 | if (!sh) { | 380 | if (!sh) { |
@@ -2826,7 +2826,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh, | |||
2826 | sector_t bn = compute_blocknr(sh, i, 1); | 2826 | sector_t bn = compute_blocknr(sh, i, 1); |
2827 | sector_t s = raid5_compute_sector(conf, bn, 0, | 2827 | sector_t s = raid5_compute_sector(conf, bn, 0, |
2828 | &dd_idx, NULL); | 2828 | &dd_idx, NULL); |
2829 | sh2 = get_active_stripe(conf, s, 0, 1); | 2829 | sh2 = get_active_stripe(conf, s, 0, 1, 1); |
2830 | if (sh2 == NULL) | 2830 | if (sh2 == NULL) |
2831 | /* so far only the early blocks of this stripe | 2831 | /* so far only the early blocks of this stripe |
2832 | * have been requested. When later blocks | 2832 | * have been requested. When later blocks |
@@ -3100,7 +3100,7 @@ static bool handle_stripe5(struct stripe_head *sh) | |||
3100 | /* Finish reconstruct operations initiated by the expansion process */ | 3100 | /* Finish reconstruct operations initiated by the expansion process */ |
3101 | if (sh->reconstruct_state == reconstruct_state_result) { | 3101 | if (sh->reconstruct_state == reconstruct_state_result) { |
3102 | struct stripe_head *sh2 | 3102 | struct stripe_head *sh2 |
3103 | = get_active_stripe(conf, sh->sector, 1, 1); | 3103 | = get_active_stripe(conf, sh->sector, 1, 1, 1); |
3104 | if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) { | 3104 | if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) { |
3105 | /* sh cannot be written until sh2 has been read. | 3105 | /* sh cannot be written until sh2 has been read. |
3106 | * so arrange for sh to be delayed a little | 3106 | * so arrange for sh to be delayed a little |
@@ -3397,7 +3397,7 @@ static bool handle_stripe6(struct stripe_head *sh) | |||
3397 | if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state) && | 3397 | if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state) && |
3398 | !sh->reconstruct_state) { | 3398 | !sh->reconstruct_state) { |
3399 | struct stripe_head *sh2 | 3399 | struct stripe_head *sh2 |
3400 | = get_active_stripe(conf, sh->sector, 1, 1); | 3400 | = get_active_stripe(conf, sh->sector, 1, 1, 1); |
3401 | if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) { | 3401 | if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) { |
3402 | /* sh cannot be written until sh2 has been read. | 3402 | /* sh cannot be written until sh2 has been read. |
3403 | * so arrange for sh to be delayed a little | 3403 | * so arrange for sh to be delayed a little |
@@ -3491,7 +3491,7 @@ static void unplug_slaves(mddev_t *mddev) | |||
3491 | int i; | 3491 | int i; |
3492 | 3492 | ||
3493 | rcu_read_lock(); | 3493 | rcu_read_lock(); |
3494 | for (i=0; i<mddev->raid_disks; i++) { | 3494 | for (i = 0; i < conf->raid_disks; i++) { |
3495 | mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); | 3495 | mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); |
3496 | if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { | 3496 | if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { |
3497 | struct request_queue *r_queue = bdev_get_queue(rdev->bdev); | 3497 | struct request_queue *r_queue = bdev_get_queue(rdev->bdev); |
@@ -3878,7 +3878,7 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3878 | (unsigned long long)logical_sector); | 3878 | (unsigned long long)logical_sector); |
3879 | 3879 | ||
3880 | sh = get_active_stripe(conf, new_sector, previous, | 3880 | sh = get_active_stripe(conf, new_sector, previous, |
3881 | (bi->bi_rw&RWA_MASK)); | 3881 | (bi->bi_rw&RWA_MASK), 0); |
3882 | if (sh) { | 3882 | if (sh) { |
3883 | if (unlikely(previous)) { | 3883 | if (unlikely(previous)) { |
3884 | /* expansion might have moved on while waiting for a | 3884 | /* expansion might have moved on while waiting for a |
@@ -4014,13 +4014,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
4014 | safepos = conf->reshape_safe; | 4014 | safepos = conf->reshape_safe; |
4015 | sector_div(safepos, data_disks); | 4015 | sector_div(safepos, data_disks); |
4016 | if (mddev->delta_disks < 0) { | 4016 | if (mddev->delta_disks < 0) { |
4017 | writepos -= reshape_sectors; | 4017 | writepos -= min_t(sector_t, reshape_sectors, writepos); |
4018 | readpos += reshape_sectors; | 4018 | readpos += reshape_sectors; |
4019 | safepos += reshape_sectors; | 4019 | safepos += reshape_sectors; |
4020 | } else { | 4020 | } else { |
4021 | writepos += reshape_sectors; | 4021 | writepos += reshape_sectors; |
4022 | readpos -= reshape_sectors; | 4022 | readpos -= min_t(sector_t, reshape_sectors, readpos); |
4023 | safepos -= reshape_sectors; | 4023 | safepos -= min_t(sector_t, reshape_sectors, safepos); |
4024 | } | 4024 | } |
4025 | 4025 | ||
4026 | /* 'writepos' is the most advanced device address we might write. | 4026 | /* 'writepos' is the most advanced device address we might write. |
@@ -4048,6 +4048,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
4048 | wait_event(conf->wait_for_overlap, | 4048 | wait_event(conf->wait_for_overlap, |
4049 | atomic_read(&conf->reshape_stripes)==0); | 4049 | atomic_read(&conf->reshape_stripes)==0); |
4050 | mddev->reshape_position = conf->reshape_progress; | 4050 | mddev->reshape_position = conf->reshape_progress; |
4051 | mddev->curr_resync_completed = mddev->curr_resync; | ||
4051 | conf->reshape_checkpoint = jiffies; | 4052 | conf->reshape_checkpoint = jiffies; |
4052 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 4053 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
4053 | md_wakeup_thread(mddev->thread); | 4054 | md_wakeup_thread(mddev->thread); |
@@ -4057,6 +4058,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
4057 | conf->reshape_safe = mddev->reshape_position; | 4058 | conf->reshape_safe = mddev->reshape_position; |
4058 | spin_unlock_irq(&conf->device_lock); | 4059 | spin_unlock_irq(&conf->device_lock); |
4059 | wake_up(&conf->wait_for_overlap); | 4060 | wake_up(&conf->wait_for_overlap); |
4061 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
4060 | } | 4062 | } |
4061 | 4063 | ||
4062 | if (mddev->delta_disks < 0) { | 4064 | if (mddev->delta_disks < 0) { |
@@ -4074,7 +4076,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
4074 | for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) { | 4076 | for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) { |
4075 | int j; | 4077 | int j; |
4076 | int skipped = 0; | 4078 | int skipped = 0; |
4077 | sh = get_active_stripe(conf, stripe_addr+i, 0, 0); | 4079 | sh = get_active_stripe(conf, stripe_addr+i, 0, 0, 1); |
4078 | set_bit(STRIPE_EXPANDING, &sh->state); | 4080 | set_bit(STRIPE_EXPANDING, &sh->state); |
4079 | atomic_inc(&conf->reshape_stripes); | 4081 | atomic_inc(&conf->reshape_stripes); |
4080 | /* If any of this stripe is beyond the end of the old | 4082 | /* If any of this stripe is beyond the end of the old |
@@ -4117,13 +4119,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
4117 | raid5_compute_sector(conf, stripe_addr*(new_data_disks), | 4119 | raid5_compute_sector(conf, stripe_addr*(new_data_disks), |
4118 | 1, &dd_idx, NULL); | 4120 | 1, &dd_idx, NULL); |
4119 | last_sector = | 4121 | last_sector = |
4120 | raid5_compute_sector(conf, ((stripe_addr+conf->chunk_size/512) | 4122 | raid5_compute_sector(conf, ((stripe_addr+reshape_sectors) |
4121 | *(new_data_disks) - 1), | 4123 | *(new_data_disks) - 1), |
4122 | 1, &dd_idx, NULL); | 4124 | 1, &dd_idx, NULL); |
4123 | if (last_sector >= mddev->dev_sectors) | 4125 | if (last_sector >= mddev->dev_sectors) |
4124 | last_sector = mddev->dev_sectors - 1; | 4126 | last_sector = mddev->dev_sectors - 1; |
4125 | while (first_sector <= last_sector) { | 4127 | while (first_sector <= last_sector) { |
4126 | sh = get_active_stripe(conf, first_sector, 1, 0); | 4128 | sh = get_active_stripe(conf, first_sector, 1, 0, 1); |
4127 | set_bit(STRIPE_EXPAND_SOURCE, &sh->state); | 4129 | set_bit(STRIPE_EXPAND_SOURCE, &sh->state); |
4128 | set_bit(STRIPE_HANDLE, &sh->state); | 4130 | set_bit(STRIPE_HANDLE, &sh->state); |
4129 | release_stripe(sh); | 4131 | release_stripe(sh); |
@@ -4141,11 +4143,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
4141 | * then we need to write out the superblock. | 4143 | * then we need to write out the superblock. |
4142 | */ | 4144 | */ |
4143 | sector_nr += reshape_sectors; | 4145 | sector_nr += reshape_sectors; |
4144 | if (sector_nr >= mddev->resync_max) { | 4146 | if ((sector_nr - mddev->curr_resync_completed) * 2 |
4147 | >= mddev->resync_max - mddev->curr_resync_completed) { | ||
4145 | /* Cannot proceed until we've updated the superblock... */ | 4148 | /* Cannot proceed until we've updated the superblock... */ |
4146 | wait_event(conf->wait_for_overlap, | 4149 | wait_event(conf->wait_for_overlap, |
4147 | atomic_read(&conf->reshape_stripes) == 0); | 4150 | atomic_read(&conf->reshape_stripes) == 0); |
4148 | mddev->reshape_position = conf->reshape_progress; | 4151 | mddev->reshape_position = conf->reshape_progress; |
4152 | mddev->curr_resync_completed = mddev->curr_resync; | ||
4149 | conf->reshape_checkpoint = jiffies; | 4153 | conf->reshape_checkpoint = jiffies; |
4150 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 4154 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
4151 | md_wakeup_thread(mddev->thread); | 4155 | md_wakeup_thread(mddev->thread); |
@@ -4156,6 +4160,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
4156 | conf->reshape_safe = mddev->reshape_position; | 4160 | conf->reshape_safe = mddev->reshape_position; |
4157 | spin_unlock_irq(&conf->device_lock); | 4161 | spin_unlock_irq(&conf->device_lock); |
4158 | wake_up(&conf->wait_for_overlap); | 4162 | wake_up(&conf->wait_for_overlap); |
4163 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
4159 | } | 4164 | } |
4160 | return reshape_sectors; | 4165 | return reshape_sectors; |
4161 | } | 4166 | } |
@@ -4220,9 +4225,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski | |||
4220 | 4225 | ||
4221 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); | 4226 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); |
4222 | 4227 | ||
4223 | sh = get_active_stripe(conf, sector_nr, 0, 1); | 4228 | sh = get_active_stripe(conf, sector_nr, 0, 1, 0); |
4224 | if (sh == NULL) { | 4229 | if (sh == NULL) { |
4225 | sh = get_active_stripe(conf, sector_nr, 0, 0); | 4230 | sh = get_active_stripe(conf, sector_nr, 0, 0, 0); |
4226 | /* make sure we don't swamp the stripe cache if someone else | 4231 | /* make sure we don't swamp the stripe cache if someone else |
4227 | * is trying to get access | 4232 | * is trying to get access |
4228 | */ | 4233 | */ |
@@ -4232,7 +4237,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski | |||
4232 | * We don't need to check the 'failed' flag as when that gets set, | 4237 | * We don't need to check the 'failed' flag as when that gets set, |
4233 | * recovery aborts. | 4238 | * recovery aborts. |
4234 | */ | 4239 | */ |
4235 | for (i=0; i<mddev->raid_disks; i++) | 4240 | for (i = 0; i < conf->raid_disks; i++) |
4236 | if (conf->disks[i].rdev == NULL) | 4241 | if (conf->disks[i].rdev == NULL) |
4237 | still_degraded = 1; | 4242 | still_degraded = 1; |
4238 | 4243 | ||
@@ -4284,7 +4289,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) | |||
4284 | /* already done this stripe */ | 4289 | /* already done this stripe */ |
4285 | continue; | 4290 | continue; |
4286 | 4291 | ||
4287 | sh = get_active_stripe(conf, sector, 0, 1); | 4292 | sh = get_active_stripe(conf, sector, 0, 1, 0); |
4288 | 4293 | ||
4289 | if (!sh) { | 4294 | if (!sh) { |
4290 | /* failed to get a stripe - must wait */ | 4295 | /* failed to get a stripe - must wait */ |