summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-03-15 16:54:58 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2017-03-15 16:54:58 -0700
commit69eea5a4ab9c705496e912b55a9d312325de19e6 (patch)
tree7643a4c90017a83f4497c9884c1b8bbcce097d83 /drivers
parent95422dec6bd4a7c57444743f7b1bb375335a6298 (diff)
parent9c62110454b088b4914ffe375c2dbc19643eac34 (diff)
downloadlinux-69eea5a4ab9c705496e912b55a9d312325de19e6.tar.gz
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe:
 "Four small fixes for this cycle:

   - followup fix from Neil for a fix that went in before -rc2, ensuring
     that we always see the full per-task bio_list.

   - fix for blk-mq-sched from me that ensures that we retain similar
     direct-to-issue behavior on running the queue.

   - fix from Sagi fixing a potential NULL pointer dereference in blk-mq
     on spurious CPU unplug.

   - a memory leak fix in writeback from Tahsin, fixing a case where
     device removal of a mounted device can leak a struct
     wb_writeback_work"

* 'for-linus' of git://git.kernel.dk/linux-block:
  blk-mq-sched: don't run the queue async from blk_mq_try_issue_directly()
  writeback: fix memory leak in wb_queue_work()
  blk-mq: Fix tagset reinit in the presence of cpu hot-unplug
  blk: Ensure users for current->bio_list can see the full list.
Diffstat (limited to 'drivers')
-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 f4ffd1eb8f44..dfb75979e455 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -989,26 +989,29 @@ static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule)
 	struct dm_offload *o = container_of(cb, struct dm_offload, cb);
 	struct bio_list list;
 	struct bio *bio;
+	int i;
 
 	INIT_LIST_HEAD(&o->cb.list);
 
 	if (unlikely(!current->bio_list))
 		return;
 
-	list = *current->bio_list;
-	bio_list_init(current->bio_list);
-
-	while ((bio = bio_list_pop(&list))) {
-		struct bio_set *bs = bio->bi_pool;
-		if (unlikely(!bs) || bs == fs_bio_set) {
-			bio_list_add(current->bio_list, bio);
-			continue;
+	for (i = 0; i < 2; i++) {
+		list = current->bio_list[i];
+		bio_list_init(&current->bio_list[i]);
+
+		while ((bio = bio_list_pop(&list))) {
+			struct bio_set *bs = bio->bi_pool;
+			if (unlikely(!bs) || bs == fs_bio_set) {
+				bio_list_add(&current->bio_list[i], bio);
+				continue;
+			}
+
+			spin_lock(&bs->rescue_lock);
+			bio_list_add(&bs->rescue_list, bio);
+			queue_work(bs->rescue_workqueue, &bs->rescue_work);
+			spin_unlock(&bs->rescue_lock);
 		}
-
-		spin_lock(&bs->rescue_lock);
-		bio_list_add(&bs->rescue_list, bio);
-		queue_work(bs->rescue_workqueue, &bs->rescue_work);
-		spin_unlock(&bs->rescue_lock);
 	}
 }
 
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 063c43d83b72..0536658c9d40 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -974,7 +974,8 @@ static void wait_barrier(struct r10conf *conf)
 				    !conf->barrier ||
 				    (atomic_read(&conf->nr_pending) &&
 				     current->bio_list &&
-				     !bio_list_empty(current->bio_list)),
+				     (!bio_list_empty(&current->bio_list[0]) ||
+				      !bio_list_empty(&current->bio_list[1]))),
 				    conf->resync_lock);
 		conf->nr_waiting--;
 		if (!conf->nr_waiting)