diff options
Diffstat (limited to 'drivers/md/raid1.c')
-rw-r--r-- | drivers/md/raid1.c | 91 |
1 files changed, 19 insertions, 72 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 06cd712807d0..c2a21ae56d97 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -52,23 +52,16 @@ | |||
52 | #define NR_RAID1_BIOS 256 | 52 | #define NR_RAID1_BIOS 256 |
53 | 53 | ||
54 | 54 | ||
55 | static void unplug_slaves(mddev_t *mddev); | ||
56 | |||
57 | static void allow_barrier(conf_t *conf); | 55 | static void allow_barrier(conf_t *conf); |
58 | static void lower_barrier(conf_t *conf); | 56 | static void lower_barrier(conf_t *conf); |
59 | 57 | ||
60 | static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data) | 58 | static void * r1bio_pool_alloc(gfp_t gfp_flags, void *data) |
61 | { | 59 | { |
62 | struct pool_info *pi = data; | 60 | struct pool_info *pi = data; |
63 | r1bio_t *r1_bio; | ||
64 | int size = offsetof(r1bio_t, bios[pi->raid_disks]); | 61 | int size = offsetof(r1bio_t, bios[pi->raid_disks]); |
65 | 62 | ||
66 | /* allocate a r1bio with room for raid_disks entries in the bios array */ | 63 | /* allocate a r1bio with room for raid_disks entries in the bios array */ |
67 | r1_bio = kzalloc(size, gfp_flags); | 64 | return kzalloc(size, gfp_flags); |
68 | if (!r1_bio && pi->mddev) | ||
69 | unplug_slaves(pi->mddev); | ||
70 | |||
71 | return r1_bio; | ||
72 | } | 65 | } |
73 | 66 | ||
74 | static void r1bio_pool_free(void *r1_bio, void *data) | 67 | static void r1bio_pool_free(void *r1_bio, void *data) |
@@ -91,10 +84,8 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) | |||
91 | int i, j; | 84 | int i, j; |
92 | 85 | ||
93 | r1_bio = r1bio_pool_alloc(gfp_flags, pi); | 86 | r1_bio = r1bio_pool_alloc(gfp_flags, pi); |
94 | if (!r1_bio) { | 87 | if (!r1_bio) |
95 | unplug_slaves(pi->mddev); | ||
96 | return NULL; | 88 | return NULL; |
97 | } | ||
98 | 89 | ||
99 | /* | 90 | /* |
100 | * Allocate bios : 1 for reading, n-1 for writing | 91 | * Allocate bios : 1 for reading, n-1 for writing |
@@ -520,37 +511,6 @@ static int read_balance(conf_t *conf, r1bio_t *r1_bio) | |||
520 | return new_disk; | 511 | return new_disk; |
521 | } | 512 | } |
522 | 513 | ||
523 | static void unplug_slaves(mddev_t *mddev) | ||
524 | { | ||
525 | conf_t *conf = mddev->private; | ||
526 | int i; | ||
527 | |||
528 | rcu_read_lock(); | ||
529 | for (i=0; i<mddev->raid_disks; i++) { | ||
530 | mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev); | ||
531 | if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { | ||
532 | struct request_queue *r_queue = bdev_get_queue(rdev->bdev); | ||
533 | |||
534 | atomic_inc(&rdev->nr_pending); | ||
535 | rcu_read_unlock(); | ||
536 | |||
537 | blk_unplug(r_queue); | ||
538 | |||
539 | rdev_dec_pending(rdev, mddev); | ||
540 | rcu_read_lock(); | ||
541 | } | ||
542 | } | ||
543 | rcu_read_unlock(); | ||
544 | } | ||
545 | |||
546 | static void raid1_unplug(struct request_queue *q) | ||
547 | { | ||
548 | mddev_t *mddev = q->queuedata; | ||
549 | |||
550 | unplug_slaves(mddev); | ||
551 | md_wakeup_thread(mddev->thread); | ||
552 | } | ||
553 | |||
554 | static int raid1_congested(void *data, int bits) | 514 | static int raid1_congested(void *data, int bits) |
555 | { | 515 | { |
556 | mddev_t *mddev = data; | 516 | mddev_t *mddev = data; |
@@ -580,23 +540,16 @@ static int raid1_congested(void *data, int bits) | |||
580 | } | 540 | } |
581 | 541 | ||
582 | 542 | ||
583 | static int flush_pending_writes(conf_t *conf) | 543 | static void flush_pending_writes(conf_t *conf) |
584 | { | 544 | { |
585 | /* Any writes that have been queued but are awaiting | 545 | /* Any writes that have been queued but are awaiting |
586 | * bitmap updates get flushed here. | 546 | * bitmap updates get flushed here. |
587 | * We return 1 if any requests were actually submitted. | ||
588 | */ | 547 | */ |
589 | int rv = 0; | ||
590 | |||
591 | spin_lock_irq(&conf->device_lock); | 548 | spin_lock_irq(&conf->device_lock); |
592 | 549 | ||
593 | if (conf->pending_bio_list.head) { | 550 | if (conf->pending_bio_list.head) { |
594 | struct bio *bio; | 551 | struct bio *bio; |
595 | bio = bio_list_get(&conf->pending_bio_list); | 552 | bio = bio_list_get(&conf->pending_bio_list); |
596 | /* Only take the spinlock to quiet a warning */ | ||
597 | spin_lock(conf->mddev->queue->queue_lock); | ||
598 | blk_remove_plug(conf->mddev->queue); | ||
599 | spin_unlock(conf->mddev->queue->queue_lock); | ||
600 | spin_unlock_irq(&conf->device_lock); | 553 | spin_unlock_irq(&conf->device_lock); |
601 | /* flush any pending bitmap writes to | 554 | /* flush any pending bitmap writes to |
602 | * disk before proceeding w/ I/O */ | 555 | * disk before proceeding w/ I/O */ |
@@ -608,10 +561,14 @@ static int flush_pending_writes(conf_t *conf) | |||
608 | generic_make_request(bio); | 561 | generic_make_request(bio); |
609 | bio = next; | 562 | bio = next; |
610 | } | 563 | } |
611 | rv = 1; | ||
612 | } else | 564 | } else |
613 | spin_unlock_irq(&conf->device_lock); | 565 | spin_unlock_irq(&conf->device_lock); |
614 | return rv; | 566 | } |
567 | |||
568 | static void md_kick_device(mddev_t *mddev) | ||
569 | { | ||
570 | blk_flush_plug(current); | ||
571 | md_wakeup_thread(mddev->thread); | ||
615 | } | 572 | } |
616 | 573 | ||
617 | /* Barriers.... | 574 | /* Barriers.... |
@@ -643,8 +600,7 @@ static void raise_barrier(conf_t *conf) | |||
643 | 600 | ||
644 | /* Wait until no block IO is waiting */ | 601 | /* Wait until no block IO is waiting */ |
645 | wait_event_lock_irq(conf->wait_barrier, !conf->nr_waiting, | 602 | wait_event_lock_irq(conf->wait_barrier, !conf->nr_waiting, |
646 | conf->resync_lock, | 603 | conf->resync_lock, md_kick_device(conf->mddev)); |
647 | raid1_unplug(conf->mddev->queue)); | ||
648 | 604 | ||
649 | /* block any new IO from starting */ | 605 | /* block any new IO from starting */ |
650 | conf->barrier++; | 606 | conf->barrier++; |
@@ -652,8 +608,7 @@ static void raise_barrier(conf_t *conf) | |||
652 | /* Now wait for all pending IO to complete */ | 608 | /* Now wait for all pending IO to complete */ |
653 | wait_event_lock_irq(conf->wait_barrier, | 609 | wait_event_lock_irq(conf->wait_barrier, |
654 | !conf->nr_pending && conf->barrier < RESYNC_DEPTH, | 610 | !conf->nr_pending && conf->barrier < RESYNC_DEPTH, |
655 | conf->resync_lock, | 611 | conf->resync_lock, md_kick_device(conf->mddev)); |
656 | raid1_unplug(conf->mddev->queue)); | ||
657 | 612 | ||
658 | spin_unlock_irq(&conf->resync_lock); | 613 | spin_unlock_irq(&conf->resync_lock); |
659 | } | 614 | } |
@@ -675,7 +630,7 @@ static void wait_barrier(conf_t *conf) | |||
675 | conf->nr_waiting++; | 630 | conf->nr_waiting++; |
676 | wait_event_lock_irq(conf->wait_barrier, !conf->barrier, | 631 | wait_event_lock_irq(conf->wait_barrier, !conf->barrier, |
677 | conf->resync_lock, | 632 | conf->resync_lock, |
678 | raid1_unplug(conf->mddev->queue)); | 633 | md_kick_device(conf->mddev)); |
679 | conf->nr_waiting--; | 634 | conf->nr_waiting--; |
680 | } | 635 | } |
681 | conf->nr_pending++; | 636 | conf->nr_pending++; |
@@ -712,7 +667,7 @@ static void freeze_array(conf_t *conf) | |||
712 | conf->nr_pending == conf->nr_queued+1, | 667 | conf->nr_pending == conf->nr_queued+1, |
713 | conf->resync_lock, | 668 | conf->resync_lock, |
714 | ({ flush_pending_writes(conf); | 669 | ({ flush_pending_writes(conf); |
715 | raid1_unplug(conf->mddev->queue); })); | 670 | md_kick_device(conf->mddev); })); |
716 | spin_unlock_irq(&conf->resync_lock); | 671 | spin_unlock_irq(&conf->resync_lock); |
717 | } | 672 | } |
718 | static void unfreeze_array(conf_t *conf) | 673 | static void unfreeze_array(conf_t *conf) |
@@ -962,7 +917,6 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
962 | atomic_inc(&r1_bio->remaining); | 917 | atomic_inc(&r1_bio->remaining); |
963 | spin_lock_irqsave(&conf->device_lock, flags); | 918 | spin_lock_irqsave(&conf->device_lock, flags); |
964 | bio_list_add(&conf->pending_bio_list, mbio); | 919 | bio_list_add(&conf->pending_bio_list, mbio); |
965 | blk_plug_device_unlocked(mddev->queue); | ||
966 | spin_unlock_irqrestore(&conf->device_lock, flags); | 920 | spin_unlock_irqrestore(&conf->device_lock, flags); |
967 | } | 921 | } |
968 | r1_bio_write_done(r1_bio, bio->bi_vcnt, behind_pages, behind_pages != NULL); | 922 | r1_bio_write_done(r1_bio, bio->bi_vcnt, behind_pages, behind_pages != NULL); |
@@ -971,7 +925,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
971 | /* In case raid1d snuck in to freeze_array */ | 925 | /* In case raid1d snuck in to freeze_array */ |
972 | wake_up(&conf->wait_barrier); | 926 | wake_up(&conf->wait_barrier); |
973 | 927 | ||
974 | if (do_sync) | 928 | if (do_sync || !bitmap) |
975 | md_wakeup_thread(mddev->thread); | 929 | md_wakeup_thread(mddev->thread); |
976 | 930 | ||
977 | return 0; | 931 | return 0; |
@@ -1178,7 +1132,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number) | |||
1178 | p->rdev = rdev; | 1132 | p->rdev = rdev; |
1179 | goto abort; | 1133 | goto abort; |
1180 | } | 1134 | } |
1181 | md_integrity_register(mddev); | 1135 | err = md_integrity_register(mddev); |
1182 | } | 1136 | } |
1183 | abort: | 1137 | abort: |
1184 | 1138 | ||
@@ -1561,7 +1515,6 @@ static void raid1d(mddev_t *mddev) | |||
1561 | unsigned long flags; | 1515 | unsigned long flags; |
1562 | conf_t *conf = mddev->private; | 1516 | conf_t *conf = mddev->private; |
1563 | struct list_head *head = &conf->retry_list; | 1517 | struct list_head *head = &conf->retry_list; |
1564 | int unplug=0; | ||
1565 | mdk_rdev_t *rdev; | 1518 | mdk_rdev_t *rdev; |
1566 | 1519 | ||
1567 | md_check_recovery(mddev); | 1520 | md_check_recovery(mddev); |
@@ -1569,7 +1522,7 @@ static void raid1d(mddev_t *mddev) | |||
1569 | for (;;) { | 1522 | for (;;) { |
1570 | char b[BDEVNAME_SIZE]; | 1523 | char b[BDEVNAME_SIZE]; |
1571 | 1524 | ||
1572 | unplug += flush_pending_writes(conf); | 1525 | flush_pending_writes(conf); |
1573 | 1526 | ||
1574 | spin_lock_irqsave(&conf->device_lock, flags); | 1527 | spin_lock_irqsave(&conf->device_lock, flags); |
1575 | if (list_empty(head)) { | 1528 | if (list_empty(head)) { |
@@ -1583,10 +1536,9 @@ static void raid1d(mddev_t *mddev) | |||
1583 | 1536 | ||
1584 | mddev = r1_bio->mddev; | 1537 | mddev = r1_bio->mddev; |
1585 | conf = mddev->private; | 1538 | conf = mddev->private; |
1586 | if (test_bit(R1BIO_IsSync, &r1_bio->state)) { | 1539 | if (test_bit(R1BIO_IsSync, &r1_bio->state)) |
1587 | sync_request_write(mddev, r1_bio); | 1540 | sync_request_write(mddev, r1_bio); |
1588 | unplug = 1; | 1541 | else { |
1589 | } else { | ||
1590 | int disk; | 1542 | int disk; |
1591 | 1543 | ||
1592 | /* we got a read error. Maybe the drive is bad. Maybe just | 1544 | /* we got a read error. Maybe the drive is bad. Maybe just |
@@ -1636,14 +1588,11 @@ static void raid1d(mddev_t *mddev) | |||
1636 | bio->bi_end_io = raid1_end_read_request; | 1588 | bio->bi_end_io = raid1_end_read_request; |
1637 | bio->bi_rw = READ | do_sync; | 1589 | bio->bi_rw = READ | do_sync; |
1638 | bio->bi_private = r1_bio; | 1590 | bio->bi_private = r1_bio; |
1639 | unplug = 1; | ||
1640 | generic_make_request(bio); | 1591 | generic_make_request(bio); |
1641 | } | 1592 | } |
1642 | } | 1593 | } |
1643 | cond_resched(); | 1594 | cond_resched(); |
1644 | } | 1595 | } |
1645 | if (unplug) | ||
1646 | unplug_slaves(mddev); | ||
1647 | } | 1596 | } |
1648 | 1597 | ||
1649 | 1598 | ||
@@ -2066,11 +2015,9 @@ static int run(mddev_t *mddev) | |||
2066 | 2015 | ||
2067 | md_set_array_sectors(mddev, raid1_size(mddev, 0, 0)); | 2016 | md_set_array_sectors(mddev, raid1_size(mddev, 0, 0)); |
2068 | 2017 | ||
2069 | mddev->queue->unplug_fn = raid1_unplug; | ||
2070 | mddev->queue->backing_dev_info.congested_fn = raid1_congested; | 2018 | mddev->queue->backing_dev_info.congested_fn = raid1_congested; |
2071 | mddev->queue->backing_dev_info.congested_data = mddev; | 2019 | mddev->queue->backing_dev_info.congested_data = mddev; |
2072 | md_integrity_register(mddev); | 2020 | return md_integrity_register(mddev); |
2073 | return 0; | ||
2074 | } | 2021 | } |
2075 | 2022 | ||
2076 | static int stop(mddev_t *mddev) | 2023 | static int stop(mddev_t *mddev) |