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.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 16f5c21963db..25247a852912 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -679,14 +679,9 @@ get_active_stripe(struct r5conf *conf, sector_t sector,
679 init_stripe(sh, sector, previous); 679 init_stripe(sh, sector, previous);
680 atomic_inc(&sh->count); 680 atomic_inc(&sh->count);
681 } 681 }
682 } else { 682 } else if (!atomic_inc_not_zero(&sh->count)) {
683 spin_lock(&conf->device_lock); 683 spin_lock(&conf->device_lock);
684 if (atomic_read(&sh->count)) { 684 if (!atomic_read(&sh->count)) {
685 BUG_ON(!list_empty(&sh->lru)
686 && !test_bit(STRIPE_EXPANDING, &sh->state)
687 && !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)
688 );
689 } else {
690 if (!test_bit(STRIPE_HANDLE, &sh->state)) 685 if (!test_bit(STRIPE_HANDLE, &sh->state))
691 atomic_inc(&conf->active_stripes); 686 atomic_inc(&conf->active_stripes);
692 BUG_ON(list_empty(&sh->lru) && 687 BUG_ON(list_empty(&sh->lru) &&
@@ -4552,6 +4547,8 @@ static void make_request(struct mddev *mddev, struct bio * bi)
4552 struct stripe_head *sh; 4547 struct stripe_head *sh;
4553 const int rw = bio_data_dir(bi); 4548 const int rw = bio_data_dir(bi);
4554 int remaining; 4549 int remaining;
4550 DEFINE_WAIT(w);
4551 bool do_prepare;
4555 4552
4556 if (unlikely(bi->bi_rw & REQ_FLUSH)) { 4553 if (unlikely(bi->bi_rw & REQ_FLUSH)) {
4557 md_flush_request(mddev, bi); 4554 md_flush_request(mddev, bi);
@@ -4575,15 +4572,18 @@ static void make_request(struct mddev *mddev, struct bio * bi)
4575 bi->bi_next = NULL; 4572 bi->bi_next = NULL;
4576 bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ 4573 bi->bi_phys_segments = 1; /* over-loaded to count active stripes */
4577 4574
4575 prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
4578 for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { 4576 for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
4579 DEFINE_WAIT(w);
4580 int previous; 4577 int previous;
4581 int seq; 4578 int seq;
4582 4579
4580 do_prepare = false;
4583 retry: 4581 retry:
4584 seq = read_seqcount_begin(&conf->gen_lock); 4582 seq = read_seqcount_begin(&conf->gen_lock);
4585 previous = 0; 4583 previous = 0;
4586 prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE); 4584 if (do_prepare)
4585 prepare_to_wait(&conf->wait_for_overlap, &w,
4586 TASK_UNINTERRUPTIBLE);
4587 if (unlikely(conf->reshape_progress != MaxSector)) { 4587 if (unlikely(conf->reshape_progress != MaxSector)) {
4588 /* spinlock is needed as reshape_progress may be 4588 /* spinlock is needed as reshape_progress may be
4589 * 64bit on a 32bit platform, and so it might be 4589 * 64bit on a 32bit platform, and so it might be
@@ -4604,6 +4604,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
4604 : logical_sector >= conf->reshape_safe) { 4604 : logical_sector >= conf->reshape_safe) {
4605 spin_unlock_irq(&conf->device_lock); 4605 spin_unlock_irq(&conf->device_lock);
4606 schedule(); 4606 schedule();
4607 do_prepare = true;
4607 goto retry; 4608 goto retry;
4608 } 4609 }
4609 } 4610 }
@@ -4640,6 +4641,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
4640 if (must_retry) { 4641 if (must_retry) {
4641 release_stripe(sh); 4642 release_stripe(sh);
4642 schedule(); 4643 schedule();
4644 do_prepare = true;
4643 goto retry; 4645 goto retry;
4644 } 4646 }
4645 } 4647 }
@@ -4663,8 +4665,10 @@ static void make_request(struct mddev *mddev, struct bio * bi)
4663 prepare_to_wait(&conf->wait_for_overlap, 4665 prepare_to_wait(&conf->wait_for_overlap,
4664 &w, TASK_INTERRUPTIBLE); 4666 &w, TASK_INTERRUPTIBLE);
4665 if (logical_sector >= mddev->suspend_lo && 4667 if (logical_sector >= mddev->suspend_lo &&
4666 logical_sector < mddev->suspend_hi) 4668 logical_sector < mddev->suspend_hi) {
4667 schedule(); 4669 schedule();
4670 do_prepare = true;
4671 }
4668 goto retry; 4672 goto retry;
4669 } 4673 }
4670 4674
@@ -4677,9 +4681,9 @@ static void make_request(struct mddev *mddev, struct bio * bi)
4677 md_wakeup_thread(mddev->thread); 4681 md_wakeup_thread(mddev->thread);
4678 release_stripe(sh); 4682 release_stripe(sh);
4679 schedule(); 4683 schedule();
4684 do_prepare = true;
4680 goto retry; 4685 goto retry;
4681 } 4686 }
4682 finish_wait(&conf->wait_for_overlap, &w);
4683 set_bit(STRIPE_HANDLE, &sh->state); 4687 set_bit(STRIPE_HANDLE, &sh->state);
4684 clear_bit(STRIPE_DELAYED, &sh->state); 4688 clear_bit(STRIPE_DELAYED, &sh->state);
4685 if ((bi->bi_rw & REQ_SYNC) && 4689 if ((bi->bi_rw & REQ_SYNC) &&
@@ -4689,10 +4693,10 @@ static void make_request(struct mddev *mddev, struct bio * bi)
4689 } else { 4693 } else {
4690 /* cannot get stripe for read-ahead, just give-up */ 4694 /* cannot get stripe for read-ahead, just give-up */
4691 clear_bit(BIO_UPTODATE, &bi->bi_flags); 4695 clear_bit(BIO_UPTODATE, &bi->bi_flags);
4692 finish_wait(&conf->wait_for_overlap, &w);
4693 break; 4696 break;
4694 } 4697 }
4695 } 4698 }
4699 finish_wait(&conf->wait_for_overlap, &w);
4696 4700
4697 remaining = raid5_dec_bi_active_stripes(bi); 4701 remaining = raid5_dec_bi_active_stripes(bi);
4698 if (remaining == 0) { 4702 if (remaining == 0) {