aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2017-03-10 01:00:47 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-04-08 03:30:36 -0400
commit5959cded91e319524f4e09f747b03c477d9fbaef (patch)
treec36407ef9c7196f3b8dcd9acdf26cffdfd735cda /drivers/md
parentd5986e0078f25ee9862f3f13157f1421f18d6c64 (diff)
blk: Ensure users for current->bio_list can see the full list.
commit f5fe1b51905df7cfe4fdfd85c5fb7bc5b71a094f upstream. Commit 79bd99596b73 ("blk: improve order of bio handling in generic_make_request()") changed current->bio_list so that it did not contain *all* of the queued bios, but only those submitted by the currently running make_request_fn. There are two places which walk the list and requeue selected bios, and others that check if the list is empty. These are no longer correct. So redefine current->bio_list to point to an array of two lists, which contain all queued bios, and adjust various code to test or walk both lists. Signed-off-by: NeilBrown <neilb@suse.com> Fixes: 79bd99596b73 ("blk: improve order of bio handling in generic_make_request()") Signed-off-by: Jens Axboe <axboe@fb.com> Cc: Jack Wang <jinpu.wang@profitbricks.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm.c29
-rw-r--r--drivers/md/raid10.c3
2 files changed, 18 insertions, 14 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 628ba001bb3c..e66f4040d84b 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -986,26 +986,29 @@ static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule)
986 struct dm_offload *o = container_of(cb, struct dm_offload, cb); 986 struct dm_offload *o = container_of(cb, struct dm_offload, cb);
987 struct bio_list list; 987 struct bio_list list;
988 struct bio *bio; 988 struct bio *bio;
989 int i;
989 990
990 INIT_LIST_HEAD(&o->cb.list); 991 INIT_LIST_HEAD(&o->cb.list);
991 992
992 if (unlikely(!current->bio_list)) 993 if (unlikely(!current->bio_list))
993 return; 994 return;
994 995
995 list = *current->bio_list; 996 for (i = 0; i < 2; i++) {
996 bio_list_init(current->bio_list); 997 list = current->bio_list[i];
997 998 bio_list_init(&current->bio_list[i]);
998 while ((bio = bio_list_pop(&list))) { 999
999 struct bio_set *bs = bio->bi_pool; 1000 while ((bio = bio_list_pop(&list))) {
1000 if (unlikely(!bs) || bs == fs_bio_set) { 1001 struct bio_set *bs = bio->bi_pool;
1001 bio_list_add(current->bio_list, bio); 1002 if (unlikely(!bs) || bs == fs_bio_set) {
1002 continue; 1003 bio_list_add(&current->bio_list[i], bio);
1004 continue;
1005 }
1006
1007 spin_lock(&bs->rescue_lock);
1008 bio_list_add(&bs->rescue_list, bio);
1009 queue_work(bs->rescue_workqueue, &bs->rescue_work);
1010 spin_unlock(&bs->rescue_lock);
1003 } 1011 }
1004
1005 spin_lock(&bs->rescue_lock);
1006 bio_list_add(&bs->rescue_list, bio);
1007 queue_work(bs->rescue_workqueue, &bs->rescue_work);
1008 spin_unlock(&bs->rescue_lock);
1009 } 1012 }
1010} 1013}
1011 1014
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 55b5e0e77b17..4c4aab02e311 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -941,7 +941,8 @@ static void wait_barrier(struct r10conf *conf)
941 !conf->barrier || 941 !conf->barrier ||
942 (atomic_read(&conf->nr_pending) && 942 (atomic_read(&conf->nr_pending) &&
943 current->bio_list && 943 current->bio_list &&
944 !bio_list_empty(current->bio_list)), 944 (!bio_list_empty(&current->bio_list[0]) ||
945 !bio_list_empty(&current->bio_list[1]))),
945 conf->resync_lock); 946 conf->resync_lock);
946 conf->nr_waiting--; 947 conf->nr_waiting--;
947 if (!conf->nr_waiting) 948 if (!conf->nr_waiting)