|
@@ -1973,7 +1973,14 @@ end_io:
|
|
|
*/
|
|
|
blk_qc_t generic_make_request(struct bio *bio)
|
|
|
{
|
|
|
- struct bio_list bio_list_on_stack;
|
|
|
+ /*
|
|
|
+ * bio_list_on_stack[0] contains bios submitted by the current
|
|
|
+ * make_request_fn.
|
|
|
+ * bio_list_on_stack[1] contains bios that were submitted before
|
|
|
+ * the current make_request_fn, but that haven't been processed
|
|
|
+ * yet.
|
|
|
+ */
|
|
|
+ struct bio_list bio_list_on_stack[2];
|
|
|
blk_qc_t ret = BLK_QC_T_NONE;
|
|
|
|
|
|
if (!generic_make_request_checks(bio))
|
|
@@ -1990,7 +1997,7 @@ blk_qc_t generic_make_request(struct bio *bio)
|
|
|
* should be added at the tail
|
|
|
*/
|
|
|
if (current->bio_list) {
|
|
|
- bio_list_add(current->bio_list, bio);
|
|
|
+ bio_list_add(¤t->bio_list[0], bio);
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
@@ -2009,18 +2016,17 @@ blk_qc_t generic_make_request(struct bio *bio)
|
|
|
* bio_list, and call into ->make_request() again.
|
|
|
*/
|
|
|
BUG_ON(bio->bi_next);
|
|
|
- bio_list_init(&bio_list_on_stack);
|
|
|
- current->bio_list = &bio_list_on_stack;
|
|
|
+ bio_list_init(&bio_list_on_stack[0]);
|
|
|
+ current->bio_list = bio_list_on_stack;
|
|
|
do {
|
|
|
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
|
|
|
|
|
|
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);
|
|
|
+ bio_list_on_stack[1] = bio_list_on_stack[0];
|
|
|
+ bio_list_init(&bio_list_on_stack[0]);
|
|
|
ret = q->make_request_fn(q, bio);
|
|
|
|
|
|
blk_queue_exit(q);
|
|
@@ -2030,19 +2036,19 @@ blk_qc_t generic_make_request(struct bio *bio)
|
|
|
*/
|
|
|
bio_list_init(&lower);
|
|
|
bio_list_init(&same);
|
|
|
- while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL)
|
|
|
+ while ((bio = bio_list_pop(&bio_list_on_stack[0])) != 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);
|
|
|
+ bio_list_merge(&bio_list_on_stack[0], &lower);
|
|
|
+ bio_list_merge(&bio_list_on_stack[0], &same);
|
|
|
+ bio_list_merge(&bio_list_on_stack[0], &bio_list_on_stack[1]);
|
|
|
} else {
|
|
|
bio_io_error(bio);
|
|
|
}
|
|
|
- bio = bio_list_pop(current->bio_list);
|
|
|
+ bio = bio_list_pop(&bio_list_on_stack[0]);
|
|
|
} while (bio);
|
|
|
current->bio_list = NULL; /* deactivate */
|
|
|
|