diff options
| -rw-r--r-- | drivers/md/bitmap.c | 2 | ||||
| -rw-r--r-- | drivers/md/raid1.c | 57 |
2 files changed, 55 insertions, 4 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 15dbe03117e4..94e7f6ba2e11 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
| @@ -1305,7 +1305,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect | |||
| 1305 | prepare_to_wait(&bitmap->overflow_wait, &__wait, | 1305 | prepare_to_wait(&bitmap->overflow_wait, &__wait, |
| 1306 | TASK_UNINTERRUPTIBLE); | 1306 | TASK_UNINTERRUPTIBLE); |
| 1307 | spin_unlock_irq(&bitmap->counts.lock); | 1307 | spin_unlock_irq(&bitmap->counts.lock); |
| 1308 | io_schedule(); | 1308 | schedule(); |
| 1309 | finish_wait(&bitmap->overflow_wait, &__wait); | 1309 | finish_wait(&bitmap->overflow_wait, &__wait); |
| 1310 | continue; | 1310 | continue; |
| 1311 | } | 1311 | } |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 36a8fc059ac3..9f01870d031c 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
| @@ -870,6 +870,44 @@ do_sync_io: | |||
| 870 | pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size); | 870 | pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size); |
| 871 | } | 871 | } |
| 872 | 872 | ||
| 873 | struct raid1_plug_cb { | ||
| 874 | struct blk_plug_cb cb; | ||
| 875 | struct bio_list pending; | ||
| 876 | int pending_cnt; | ||
| 877 | }; | ||
| 878 | |||
| 879 | static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule) | ||
| 880 | { | ||
| 881 | struct raid1_plug_cb *plug = container_of(cb, struct raid1_plug_cb, | ||
| 882 | cb); | ||
| 883 | struct mddev *mddev = plug->cb.data; | ||
| 884 | struct r1conf *conf = mddev->private; | ||
| 885 | struct bio *bio; | ||
| 886 | |||
| 887 | if (from_schedule) { | ||
| 888 | spin_lock_irq(&conf->device_lock); | ||
| 889 | bio_list_merge(&conf->pending_bio_list, &plug->pending); | ||
| 890 | conf->pending_count += plug->pending_cnt; | ||
| 891 | spin_unlock_irq(&conf->device_lock); | ||
| 892 | md_wakeup_thread(mddev->thread); | ||
| 893 | kfree(plug); | ||
| 894 | return; | ||
| 895 | } | ||
| 896 | |||
| 897 | /* we aren't scheduling, so we can do the write-out directly. */ | ||
| 898 | bio = bio_list_get(&plug->pending); | ||
| 899 | bitmap_unplug(mddev->bitmap); | ||
| 900 | wake_up(&conf->wait_barrier); | ||
| 901 | |||
| 902 | while (bio) { /* submit pending writes */ | ||
| 903 | struct bio *next = bio->bi_next; | ||
| 904 | bio->bi_next = NULL; | ||
| 905 | generic_make_request(bio); | ||
| 906 | bio = next; | ||
| 907 | } | ||
| 908 | kfree(plug); | ||
| 909 | } | ||
| 910 | |||
| 873 | static void make_request(struct mddev *mddev, struct bio * bio) | 911 | static void make_request(struct mddev *mddev, struct bio * bio) |
| 874 | { | 912 | { |
| 875 | struct r1conf *conf = mddev->private; | 913 | struct r1conf *conf = mddev->private; |
| @@ -883,6 +921,8 @@ static void make_request(struct mddev *mddev, struct bio * bio) | |||
| 883 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); | 921 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); |
| 884 | const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); | 922 | const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); |
| 885 | struct md_rdev *blocked_rdev; | 923 | struct md_rdev *blocked_rdev; |
| 924 | struct blk_plug_cb *cb; | ||
| 925 | struct raid1_plug_cb *plug = NULL; | ||
| 886 | int first_clone; | 926 | int first_clone; |
| 887 | int sectors_handled; | 927 | int sectors_handled; |
| 888 | int max_sectors; | 928 | int max_sectors; |
| @@ -1185,11 +1225,22 @@ read_again: | |||
| 1185 | mbio->bi_private = r1_bio; | 1225 | mbio->bi_private = r1_bio; |
| 1186 | 1226 | ||
| 1187 | atomic_inc(&r1_bio->remaining); | 1227 | atomic_inc(&r1_bio->remaining); |
| 1228 | |||
| 1229 | cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug)); | ||
| 1230 | if (cb) | ||
| 1231 | plug = container_of(cb, struct raid1_plug_cb, cb); | ||
| 1232 | else | ||
| 1233 | plug = NULL; | ||
| 1188 | spin_lock_irqsave(&conf->device_lock, flags); | 1234 | spin_lock_irqsave(&conf->device_lock, flags); |
| 1189 | bio_list_add(&conf->pending_bio_list, mbio); | 1235 | if (plug) { |
| 1190 | conf->pending_count++; | 1236 | bio_list_add(&plug->pending, mbio); |
| 1237 | plug->pending_cnt++; | ||
| 1238 | } else { | ||
| 1239 | bio_list_add(&conf->pending_bio_list, mbio); | ||
| 1240 | conf->pending_count++; | ||
| 1241 | } | ||
| 1191 | spin_unlock_irqrestore(&conf->device_lock, flags); | 1242 | spin_unlock_irqrestore(&conf->device_lock, flags); |
| 1192 | if (!mddev_check_plugged(mddev)) | 1243 | if (!plug) |
| 1193 | md_wakeup_thread(mddev->thread); | 1244 | md_wakeup_thread(mddev->thread); |
| 1194 | } | 1245 | } |
| 1195 | /* Mustn't call r1_bio_write_done before this next test, | 1246 | /* Mustn't call r1_bio_write_done before this next test, |
