diff options
-rw-r--r-- | drivers/md/raid5.c | 43 |
1 files changed, 22 insertions, 21 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 4d7142376e58..c38310be0d95 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -274,8 +274,9 @@ static int grow_buffers(struct stripe_head *sh, int num) | |||
274 | } | 274 | } |
275 | 275 | ||
276 | static void raid5_build_block(struct stripe_head *sh, int i); | 276 | static void raid5_build_block(struct stripe_head *sh, int i); |
277 | static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks); | ||
277 | 278 | ||
278 | static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks) | 279 | static void init_stripe(struct stripe_head *sh, sector_t sector, int previous) |
279 | { | 280 | { |
280 | raid5_conf_t *conf = sh->raid_conf; | 281 | raid5_conf_t *conf = sh->raid_conf; |
281 | int i; | 282 | int i; |
@@ -290,11 +291,11 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int | |||
290 | 291 | ||
291 | remove_hash(sh); | 292 | remove_hash(sh); |
292 | 293 | ||
294 | sh->disks = previous ? conf->previous_raid_disks : conf->raid_disks; | ||
293 | sh->sector = sector; | 295 | sh->sector = sector; |
294 | sh->pd_idx = pd_idx; | 296 | sh->pd_idx = stripe_to_pdidx(sector, conf, sh->disks); |
295 | sh->state = 0; | 297 | sh->state = 0; |
296 | 298 | ||
297 | sh->disks = disks; | ||
298 | 299 | ||
299 | for (i = sh->disks; i--; ) { | 300 | for (i = sh->disks; i--; ) { |
300 | struct r5dev *dev = &sh->dev[i]; | 301 | struct r5dev *dev = &sh->dev[i]; |
@@ -330,10 +331,12 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, in | |||
330 | static void unplug_slaves(mddev_t *mddev); | 331 | static void unplug_slaves(mddev_t *mddev); |
331 | static void raid5_unplug_device(struct request_queue *q); | 332 | static void raid5_unplug_device(struct request_queue *q); |
332 | 333 | ||
333 | static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, int disks, | 334 | static struct stripe_head * |
334 | int pd_idx, int noblock) | 335 | get_active_stripe(raid5_conf_t *conf, sector_t sector, |
336 | int previous, int noblock) | ||
335 | { | 337 | { |
336 | struct stripe_head *sh; | 338 | struct stripe_head *sh; |
339 | int disks = previous ? conf->previous_raid_disks : conf->raid_disks; | ||
337 | 340 | ||
338 | pr_debug("get_stripe, sector %llu\n", (unsigned long long)sector); | 341 | pr_debug("get_stripe, sector %llu\n", (unsigned long long)sector); |
339 | 342 | ||
@@ -361,7 +364,7 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector | |||
361 | ); | 364 | ); |
362 | conf->inactive_blocked = 0; | 365 | conf->inactive_blocked = 0; |
363 | } else | 366 | } else |
364 | init_stripe(sh, sector, pd_idx, disks); | 367 | init_stripe(sh, sector, previous); |
365 | } else { | 368 | } else { |
366 | if (atomic_read(&sh->count)) { | 369 | if (atomic_read(&sh->count)) { |
367 | BUG_ON(!list_empty(&sh->lru)); | 370 | BUG_ON(!list_empty(&sh->lru)); |
@@ -2479,8 +2482,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh, | |||
2479 | conf->raid_disks - | 2482 | conf->raid_disks - |
2480 | conf->max_degraded, &dd_idx, | 2483 | conf->max_degraded, &dd_idx, |
2481 | &pd_idx, conf); | 2484 | &pd_idx, conf); |
2482 | sh2 = get_active_stripe(conf, s, conf->raid_disks, | 2485 | sh2 = get_active_stripe(conf, s, 0, 1); |
2483 | pd_idx, 1); | ||
2484 | if (sh2 == NULL) | 2486 | if (sh2 == NULL) |
2485 | /* so far only the early blocks of this stripe | 2487 | /* so far only the early blocks of this stripe |
2486 | * have been requested. When later blocks | 2488 | * have been requested. When later blocks |
@@ -3413,8 +3415,10 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3413 | for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { | 3415 | for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { |
3414 | DEFINE_WAIT(w); | 3416 | DEFINE_WAIT(w); |
3415 | int disks, data_disks; | 3417 | int disks, data_disks; |
3418 | int previous; | ||
3416 | 3419 | ||
3417 | retry: | 3420 | retry: |
3421 | previous = 0; | ||
3418 | prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE); | 3422 | prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE); |
3419 | if (likely(conf->expand_progress == MaxSector)) | 3423 | if (likely(conf->expand_progress == MaxSector)) |
3420 | disks = conf->raid_disks; | 3424 | disks = conf->raid_disks; |
@@ -3429,9 +3433,10 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3429 | */ | 3433 | */ |
3430 | spin_lock_irq(&conf->device_lock); | 3434 | spin_lock_irq(&conf->device_lock); |
3431 | disks = conf->raid_disks; | 3435 | disks = conf->raid_disks; |
3432 | if (logical_sector >= conf->expand_progress) | 3436 | if (logical_sector >= conf->expand_progress) { |
3433 | disks = conf->previous_raid_disks; | 3437 | disks = conf->previous_raid_disks; |
3434 | else { | 3438 | previous = 1; |
3439 | } else { | ||
3435 | if (logical_sector >= conf->expand_lo) { | 3440 | if (logical_sector >= conf->expand_lo) { |
3436 | spin_unlock_irq(&conf->device_lock); | 3441 | spin_unlock_irq(&conf->device_lock); |
3437 | schedule(); | 3442 | schedule(); |
@@ -3448,7 +3453,8 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3448 | (unsigned long long)new_sector, | 3453 | (unsigned long long)new_sector, |
3449 | (unsigned long long)logical_sector); | 3454 | (unsigned long long)logical_sector); |
3450 | 3455 | ||
3451 | sh = get_active_stripe(conf, new_sector, disks, pd_idx, (bi->bi_rw&RWA_MASK)); | 3456 | sh = get_active_stripe(conf, new_sector, previous, |
3457 | (bi->bi_rw&RWA_MASK)); | ||
3452 | if (sh) { | 3458 | if (sh) { |
3453 | if (unlikely(conf->expand_progress != MaxSector)) { | 3459 | if (unlikely(conf->expand_progress != MaxSector)) { |
3454 | /* expansion might have moved on while waiting for a | 3460 | /* expansion might have moved on while waiting for a |
@@ -3582,9 +3588,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
3582 | for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) { | 3588 | for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) { |
3583 | int j; | 3589 | int j; |
3584 | int skipped = 0; | 3590 | int skipped = 0; |
3585 | pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks); | 3591 | sh = get_active_stripe(conf, sector_nr+i, 0, 0); |
3586 | sh = get_active_stripe(conf, sector_nr+i, | ||
3587 | conf->raid_disks, pd_idx, 0); | ||
3588 | set_bit(STRIPE_EXPANDING, &sh->state); | 3592 | set_bit(STRIPE_EXPANDING, &sh->state); |
3589 | atomic_inc(&conf->reshape_stripes); | 3593 | atomic_inc(&conf->reshape_stripes); |
3590 | /* If any of this stripe is beyond the end of the old | 3594 | /* If any of this stripe is beyond the end of the old |
@@ -3632,10 +3636,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
3632 | if (last_sector >= mddev->dev_sectors) | 3636 | if (last_sector >= mddev->dev_sectors) |
3633 | last_sector = mddev->dev_sectors - 1; | 3637 | last_sector = mddev->dev_sectors - 1; |
3634 | while (first_sector <= last_sector) { | 3638 | while (first_sector <= last_sector) { |
3635 | pd_idx = stripe_to_pdidx(first_sector, conf, | 3639 | sh = get_active_stripe(conf, first_sector, 1, 0); |
3636 | conf->previous_raid_disks); | ||
3637 | sh = get_active_stripe(conf, first_sector, | ||
3638 | conf->previous_raid_disks, pd_idx, 0); | ||
3639 | set_bit(STRIPE_EXPAND_SOURCE, &sh->state); | 3640 | set_bit(STRIPE_EXPAND_SOURCE, &sh->state); |
3640 | set_bit(STRIPE_HANDLE, &sh->state); | 3641 | set_bit(STRIPE_HANDLE, &sh->state); |
3641 | release_stripe(sh); | 3642 | release_stripe(sh); |
@@ -3725,9 +3726,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski | |||
3725 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); | 3726 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); |
3726 | 3727 | ||
3727 | pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks); | 3728 | pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks); |
3728 | sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1); | 3729 | sh = get_active_stripe(conf, sector_nr, 0, 1); |
3729 | if (sh == NULL) { | 3730 | if (sh == NULL) { |
3730 | sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0); | 3731 | sh = get_active_stripe(conf, sector_nr, 0, 0); |
3731 | /* make sure we don't swamp the stripe cache if someone else | 3732 | /* make sure we don't swamp the stripe cache if someone else |
3732 | * is trying to get access | 3733 | * is trying to get access |
3733 | */ | 3734 | */ |
@@ -3793,7 +3794,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) | |||
3793 | /* already done this stripe */ | 3794 | /* already done this stripe */ |
3794 | continue; | 3795 | continue; |
3795 | 3796 | ||
3796 | sh = get_active_stripe(conf, sector, conf->raid_disks, pd_idx, 1); | 3797 | sh = get_active_stripe(conf, sector, 0, 1); |
3797 | 3798 | ||
3798 | if (!sh) { | 3799 | if (!sh) { |
3799 | /* failed to get a stripe - must wait */ | 3800 | /* failed to get a stripe - must wait */ |