|
@@ -2015,17 +2015,34 @@ blk_qc_t generic_make_request(struct bio *bio)
|
|
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
|
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
|
|
|
|
|
if (likely(blk_queue_enter(q, false) == 0)) {
|
|
if (likely(blk_queue_enter(q, false) == 0)) {
|
|
|
|
+ struct bio_list hold;
|
|
|
|
+ struct bio_list lower, same;
|
|
|
|
+
|
|
|
|
+ /* Create a fresh bio_list for all subordinate requests */
|
|
|
|
+ hold = bio_list_on_stack;
|
|
|
|
+ bio_list_init(&bio_list_on_stack);
|
|
ret = q->make_request_fn(q, bio);
|
|
ret = q->make_request_fn(q, bio);
|
|
|
|
|
|
blk_queue_exit(q);
|
|
blk_queue_exit(q);
|
|
|
|
|
|
- bio = bio_list_pop(current->bio_list);
|
|
|
|
|
|
+ /* sort new bios into those for a lower level
|
|
|
|
+ * and those for the same level
|
|
|
|
+ */
|
|
|
|
+ bio_list_init(&lower);
|
|
|
|
+ bio_list_init(&same);
|
|
|
|
+ while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL)
|
|
|
|
+ if (q == bdev_get_queue(bio->bi_bdev))
|
|
|
|
+ bio_list_add(&same, bio);
|
|
|
|
+ else
|
|
|
|
+ bio_list_add(&lower, bio);
|
|
|
|
+ /* now assemble so we handle the lowest level first */
|
|
|
|
+ bio_list_merge(&bio_list_on_stack, &lower);
|
|
|
|
+ bio_list_merge(&bio_list_on_stack, &same);
|
|
|
|
+ bio_list_merge(&bio_list_on_stack, &hold);
|
|
} else {
|
|
} else {
|
|
- struct bio *bio_next = bio_list_pop(current->bio_list);
|
|
|
|
-
|
|
|
|
bio_io_error(bio);
|
|
bio_io_error(bio);
|
|
- bio = bio_next;
|
|
|
|
}
|
|
}
|
|
|
|
+ bio = bio_list_pop(current->bio_list);
|
|
} while (bio);
|
|
} while (bio);
|
|
current->bio_list = NULL; /* deactivate */
|
|
current->bio_list = NULL; /* deactivate */
|
|
|
|
|