aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/raid1.c62
-rw-r--r--drivers/md/raid10.c62
2 files changed, 81 insertions, 43 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 5c7fef091cec..38f076a3400d 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -592,6 +592,37 @@ static int raid1_congested(void *data, int bits)
592} 592}
593 593
594 594
595static int flush_pending_writes(conf_t *conf)
596{
597 /* Any writes that have been queued but are awaiting
598 * bitmap updates get flushed here.
599 * We return 1 if any requests were actually submitted.
600 */
601 int rv = 0;
602
603 spin_lock_irq(&conf->device_lock);
604
605 if (conf->pending_bio_list.head) {
606 struct bio *bio;
607 bio = bio_list_get(&conf->pending_bio_list);
608 blk_remove_plug(conf->mddev->queue);
609 spin_unlock_irq(&conf->device_lock);
610 /* flush any pending bitmap writes to
611 * disk before proceeding w/ I/O */
612 bitmap_unplug(conf->mddev->bitmap);
613
614 while (bio) { /* submit pending writes */
615 struct bio *next = bio->bi_next;
616 bio->bi_next = NULL;
617 generic_make_request(bio);
618 bio = next;
619 }
620 rv = 1;
621 } else
622 spin_unlock_irq(&conf->device_lock);
623 return rv;
624}
625
595/* Barriers.... 626/* Barriers....
596 * Sometimes we need to suspend IO while we do something else, 627 * Sometimes we need to suspend IO while we do something else,
597 * either some resync/recovery, or reconfigure the array. 628 * either some resync/recovery, or reconfigure the array.
@@ -681,7 +712,8 @@ static void freeze_array(conf_t *conf)
681 wait_event_lock_irq(conf->wait_barrier, 712 wait_event_lock_irq(conf->wait_barrier,
682 conf->barrier+conf->nr_pending == conf->nr_queued+2, 713 conf->barrier+conf->nr_pending == conf->nr_queued+2,
683 conf->resync_lock, 714 conf->resync_lock,
684 raid1_unplug(conf->mddev->queue)); 715 ({ flush_pending_writes(conf);
716 raid1_unplug(conf->mddev->queue); }));
685 spin_unlock_irq(&conf->resync_lock); 717 spin_unlock_irq(&conf->resync_lock);
686} 718}
687static void unfreeze_array(conf_t *conf) 719static void unfreeze_array(conf_t *conf)
@@ -907,6 +939,9 @@ static int make_request(struct request_queue *q, struct bio * bio)
907 blk_plug_device(mddev->queue); 939 blk_plug_device(mddev->queue);
908 spin_unlock_irqrestore(&conf->device_lock, flags); 940 spin_unlock_irqrestore(&conf->device_lock, flags);
909 941
942 /* In case raid1d snuck into freeze_array */
943 wake_up(&conf->wait_barrier);
944
910 if (do_sync) 945 if (do_sync)
911 md_wakeup_thread(mddev->thread); 946 md_wakeup_thread(mddev->thread);
912#if 0 947#if 0
@@ -1473,28 +1508,14 @@ static void raid1d(mddev_t *mddev)
1473 1508
1474 for (;;) { 1509 for (;;) {
1475 char b[BDEVNAME_SIZE]; 1510 char b[BDEVNAME_SIZE];
1476 spin_lock_irqsave(&conf->device_lock, flags);
1477
1478 if (conf->pending_bio_list.head) {
1479 bio = bio_list_get(&conf->pending_bio_list);
1480 blk_remove_plug(mddev->queue);
1481 spin_unlock_irqrestore(&conf->device_lock, flags);
1482 /* flush any pending bitmap writes to disk before proceeding w/ I/O */
1483 bitmap_unplug(mddev->bitmap);
1484 1511
1485 while (bio) { /* submit pending writes */ 1512 unplug += flush_pending_writes(conf);
1486 struct bio *next = bio->bi_next;
1487 bio->bi_next = NULL;
1488 generic_make_request(bio);
1489 bio = next;
1490 }
1491 unplug = 1;
1492 1513
1493 continue; 1514 spin_lock_irqsave(&conf->device_lock, flags);
1494 } 1515 if (list_empty(head)) {
1495 1516 spin_unlock_irqrestore(&conf->device_lock, flags);
1496 if (list_empty(head))
1497 break; 1517 break;
1518 }
1498 r1_bio = list_entry(head->prev, r1bio_t, retry_list); 1519 r1_bio = list_entry(head->prev, r1bio_t, retry_list);
1499 list_del(head->prev); 1520 list_del(head->prev);
1500 conf->nr_queued--; 1521 conf->nr_queued--;
@@ -1590,7 +1611,6 @@ static void raid1d(mddev_t *mddev)
1590 } 1611 }
1591 } 1612 }
1592 } 1613 }
1593 spin_unlock_irqrestore(&conf->device_lock, flags);
1594 if (unplug) 1614 if (unplug)
1595 unplug_slaves(mddev); 1615 unplug_slaves(mddev);
1596} 1616}
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 017f58113c33..5de42d87bf4e 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -629,7 +629,36 @@ static int raid10_congested(void *data, int bits)
629 return ret; 629 return ret;
630} 630}
631 631
632 632static int flush_pending_writes(conf_t *conf)
633{
634 /* Any writes that have been queued but are awaiting
635 * bitmap updates get flushed here.
636 * We return 1 if any requests were actually submitted.
637 */
638 int rv = 0;
639
640 spin_lock_irq(&conf->device_lock);
641
642 if (conf->pending_bio_list.head) {
643 struct bio *bio;
644 bio = bio_list_get(&conf->pending_bio_list);
645 blk_remove_plug(conf->mddev->queue);
646 spin_unlock_irq(&conf->device_lock);
647 /* flush any pending bitmap writes to disk
648 * before proceeding w/ I/O */
649 bitmap_unplug(conf->mddev->bitmap);
650
651 while (bio) { /* submit pending writes */
652 struct bio *next = bio->bi_next;
653 bio->bi_next = NULL;
654 generic_make_request(bio);
655 bio = next;
656 }
657 rv = 1;
658 } else
659 spin_unlock_irq(&conf->device_lock);
660 return rv;
661}
633/* Barriers.... 662/* Barriers....
634 * Sometimes we need to suspend IO while we do something else, 663 * Sometimes we need to suspend IO while we do something else,
635 * either some resync/recovery, or reconfigure the array. 664 * either some resync/recovery, or reconfigure the array.
@@ -720,7 +749,8 @@ static void freeze_array(conf_t *conf)
720 wait_event_lock_irq(conf->wait_barrier, 749 wait_event_lock_irq(conf->wait_barrier,
721 conf->barrier+conf->nr_pending == conf->nr_queued+2, 750 conf->barrier+conf->nr_pending == conf->nr_queued+2,
722 conf->resync_lock, 751 conf->resync_lock,
723 raid10_unplug(conf->mddev->queue)); 752 ({ flush_pending_writes(conf);
753 raid10_unplug(conf->mddev->queue); }));
724 spin_unlock_irq(&conf->resync_lock); 754 spin_unlock_irq(&conf->resync_lock);
725} 755}
726 756
@@ -892,6 +922,9 @@ static int make_request(struct request_queue *q, struct bio * bio)
892 blk_plug_device(mddev->queue); 922 blk_plug_device(mddev->queue);
893 spin_unlock_irqrestore(&conf->device_lock, flags); 923 spin_unlock_irqrestore(&conf->device_lock, flags);
894 924
925 /* In case raid10d snuck in to freeze_array */
926 wake_up(&conf->wait_barrier);
927
895 if (do_sync) 928 if (do_sync)
896 md_wakeup_thread(mddev->thread); 929 md_wakeup_thread(mddev->thread);
897 930
@@ -1464,28 +1497,14 @@ static void raid10d(mddev_t *mddev)
1464 1497
1465 for (;;) { 1498 for (;;) {
1466 char b[BDEVNAME_SIZE]; 1499 char b[BDEVNAME_SIZE];
1467 spin_lock_irqsave(&conf->device_lock, flags);
1468 1500
1469 if (conf->pending_bio_list.head) { 1501 unplug += flush_pending_writes(conf);
1470 bio = bio_list_get(&conf->pending_bio_list);
1471 blk_remove_plug(mddev->queue);
1472 spin_unlock_irqrestore(&conf->device_lock, flags);
1473 /* flush any pending bitmap writes to disk before proceeding w/ I/O */
1474 bitmap_unplug(mddev->bitmap);
1475 1502
1476 while (bio) { /* submit pending writes */ 1503 spin_lock_irqsave(&conf->device_lock, flags);
1477 struct bio *next = bio->bi_next; 1504 if (list_empty(head)) {
1478 bio->bi_next = NULL; 1505 spin_unlock_irqrestore(&conf->device_lock, flags);
1479 generic_make_request(bio);
1480 bio = next;
1481 }
1482 unplug = 1;
1483
1484 continue;
1485 }
1486
1487 if (list_empty(head))
1488 break; 1506 break;
1507 }
1489 r10_bio = list_entry(head->prev, r10bio_t, retry_list); 1508 r10_bio = list_entry(head->prev, r10bio_t, retry_list);
1490 list_del(head->prev); 1509 list_del(head->prev);
1491 conf->nr_queued--; 1510 conf->nr_queued--;
@@ -1548,7 +1567,6 @@ static void raid10d(mddev_t *mddev)
1548 } 1567 }
1549 } 1568 }
1550 } 1569 }
1551 spin_unlock_irqrestore(&conf->device_lock, flags);
1552 if (unplug) 1570 if (unplug)
1553 unplug_slaves(mddev); 1571 unplug_slaves(mddev);
1554} 1572}